@sinequa/atomic-angular 0.2.2 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/sinequa-atomic-angular.mjs +257 -172
- package/fesm2022/sinequa-atomic-angular.mjs.map +1 -1
- package/index.d.ts +306 -164
- package/package.json +1 -1
|
@@ -2997,20 +2997,24 @@ class NavigationService {
|
|
|
2997
2997
|
*
|
|
2998
2998
|
* @type Observable<RouterEvent>
|
|
2999
2999
|
*/
|
|
3000
|
-
navigationEnd$ = this.router.events.pipe(map(event => event), filter((event) => event instanceof NavigationEnd), tap(event => {
|
|
3001
|
-
const url = event.url.slice(1).split(
|
|
3000
|
+
navigationEnd$ = this.router.events.pipe(map((event) => event), filter((event) => event instanceof NavigationEnd), tap((event) => {
|
|
3001
|
+
const url = event.url.slice(1).split("?")[0]; // Extract route name
|
|
3002
3002
|
// TODO: use a "loading" configuration from globalConfig
|
|
3003
|
-
if (url && url !==
|
|
3003
|
+
if (url && url !== "loading" && url !== this.urlAfterNavigation) {
|
|
3004
3004
|
this.auditService.notifyRouteChange(url);
|
|
3005
3005
|
}
|
|
3006
|
-
}), tap(event =>
|
|
3006
|
+
}), tap((event) => {
|
|
3007
|
+
if (event.url !== "/login") {
|
|
3008
|
+
this.urlAfterNavigation = event.url;
|
|
3009
|
+
}
|
|
3010
|
+
}), shareReplay(1));
|
|
3007
3011
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3008
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NavigationService, providedIn:
|
|
3012
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NavigationService, providedIn: "root" });
|
|
3009
3013
|
}
|
|
3010
3014
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: NavigationService, decorators: [{
|
|
3011
3015
|
type: Injectable,
|
|
3012
3016
|
args: [{
|
|
3013
|
-
providedIn:
|
|
3017
|
+
providedIn: "root"
|
|
3014
3018
|
}]
|
|
3015
3019
|
}] });
|
|
3016
3020
|
|
|
@@ -10301,11 +10305,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
|
|
|
10301
10305
|
*
|
|
10302
10306
|
* @public
|
|
10303
10307
|
*/
|
|
10304
|
-
const FILTER_DATE_ALLOW_CUSTOM_RANGE = new InjectionToken(
|
|
10308
|
+
const FILTER_DATE_ALLOW_CUSTOM_RANGE = new InjectionToken("date allow custom range", {
|
|
10309
|
+
factory: () => true
|
|
10310
|
+
});
|
|
10305
10311
|
class DateComponent extends AggregationComponent {
|
|
10306
10312
|
destroyRef;
|
|
10307
10313
|
datepicker = viewChild(DateRangePickerDirective, ...(ngDevMode ? [{ debugName: "datepicker" }] : []));
|
|
10308
|
-
title = input({ label:
|
|
10314
|
+
title = input({ label: "Date", icon: "far fa-calendar-day" }, ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
10309
10315
|
displayEmptyDistributionIntervals = input(false, ...(ngDevMode ? [{ debugName: "displayEmptyDistributionIntervals" }] : []));
|
|
10310
10316
|
allowCustomRange = inject(FILTER_DATE_ALLOW_CUSTOM_RANGE);
|
|
10311
10317
|
transloco = inject(TranslocoService);
|
|
@@ -10323,20 +10329,24 @@ class DateComponent extends AggregationComponent {
|
|
|
10323
10329
|
constructor(destroyRef) {
|
|
10324
10330
|
super();
|
|
10325
10331
|
this.destroyRef = destroyRef;
|
|
10326
|
-
this.transloco.langChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(lang => {
|
|
10332
|
+
this.transloco.langChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((lang) => {
|
|
10327
10333
|
this.lang.set(lang);
|
|
10328
10334
|
this.datepicker()?.setOptions({ language: lang });
|
|
10329
10335
|
});
|
|
10330
10336
|
const abortController = new AbortController();
|
|
10331
|
-
addEventListener(
|
|
10337
|
+
addEventListener("changeDate", this.onDateChange.bind(this), {
|
|
10332
10338
|
signal: abortController.signal
|
|
10333
10339
|
});
|
|
10334
10340
|
// apply current date filter from queryParamsStore
|
|
10335
10341
|
effect(() => {
|
|
10336
|
-
this.updateForm(this.queryParamsStore.getFilter({
|
|
10342
|
+
this.updateForm(this.queryParamsStore.getFilter({
|
|
10343
|
+
field: this.aggregation()?.column,
|
|
10344
|
+
name: this.aggregation()?.name
|
|
10345
|
+
}));
|
|
10337
10346
|
});
|
|
10338
|
-
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(changes => {
|
|
10339
|
-
this.validSelection.set(!!changes.option &&
|
|
10347
|
+
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((changes) => {
|
|
10348
|
+
this.validSelection.set(!!changes.option &&
|
|
10349
|
+
(changes.option !== "custom-range" || changes.customRange?.from !== null || changes.customRange?.to !== null));
|
|
10340
10350
|
});
|
|
10341
10351
|
destroyRef.onDestroy(() => {
|
|
10342
10352
|
abortController.abort();
|
|
@@ -10346,7 +10356,10 @@ class DateComponent extends AggregationComponent {
|
|
|
10346
10356
|
const name = this.name();
|
|
10347
10357
|
if (name !== null) {
|
|
10348
10358
|
const agg = this.aggregationsService.processAggregation(name, this.column());
|
|
10349
|
-
return {
|
|
10359
|
+
return {
|
|
10360
|
+
...agg,
|
|
10361
|
+
items: agg?.items?.filter((item) => item.display !== "custom-range") ?? []
|
|
10362
|
+
};
|
|
10350
10363
|
}
|
|
10351
10364
|
return null;
|
|
10352
10365
|
}, ...(ngDevMode ? [{ debugName: "aggregation" }] : []));
|
|
@@ -10354,9 +10367,10 @@ class DateComponent extends AggregationComponent {
|
|
|
10354
10367
|
try {
|
|
10355
10368
|
const filter = this.getFormValueFilter();
|
|
10356
10369
|
this.queryParamsStore.updateFilter(filter);
|
|
10370
|
+
this.selection.set(false);
|
|
10357
10371
|
}
|
|
10358
10372
|
catch (err) {
|
|
10359
|
-
warn(
|
|
10373
|
+
warn("Error applying date filter:", err);
|
|
10360
10374
|
if (err instanceof Error) {
|
|
10361
10375
|
notify.error(this.transloco.translate(err.message));
|
|
10362
10376
|
}
|
|
@@ -10381,17 +10395,18 @@ class DateComponent extends AggregationComponent {
|
|
|
10381
10395
|
return;
|
|
10382
10396
|
}
|
|
10383
10397
|
const { operator, value } = filter;
|
|
10384
|
-
const code = this.dateOptions().find((option) => option.operator === operator && option.value === value)
|
|
10385
|
-
|
|
10386
|
-
|
|
10398
|
+
const code = this.dateOptions().find((option) => option.operator === operator && option.value === value)
|
|
10399
|
+
?.display ?? "custom-range";
|
|
10400
|
+
let from = null, to = null;
|
|
10401
|
+
if (code === "custom-range") {
|
|
10387
10402
|
switch (operator) {
|
|
10388
|
-
case
|
|
10403
|
+
case "lte":
|
|
10389
10404
|
to = filter.value;
|
|
10390
10405
|
break;
|
|
10391
|
-
case
|
|
10406
|
+
case "gte":
|
|
10392
10407
|
from = filter.value;
|
|
10393
10408
|
break;
|
|
10394
|
-
case
|
|
10409
|
+
case "between":
|
|
10395
10410
|
from = filter.start;
|
|
10396
10411
|
to = filter.end;
|
|
10397
10412
|
break;
|
|
@@ -10400,16 +10415,16 @@ class DateComponent extends AggregationComponent {
|
|
|
10400
10415
|
const formValue = {
|
|
10401
10416
|
option: code,
|
|
10402
10417
|
customRange: {
|
|
10403
|
-
from: code ===
|
|
10404
|
-
to: code ===
|
|
10418
|
+
from: code === "custom-range" ? (from ?? null) : null,
|
|
10419
|
+
to: code === "custom-range" ? (to ?? null) : null
|
|
10405
10420
|
}
|
|
10406
10421
|
};
|
|
10407
10422
|
this.form.setValue(formValue);
|
|
10408
10423
|
// Update the date range picker
|
|
10409
10424
|
const datepicker = this.datepicker();
|
|
10410
10425
|
if (datepicker) {
|
|
10411
|
-
const start = new Date(formValue.customRange.from ||
|
|
10412
|
-
const end = new Date(formValue.customRange.to ||
|
|
10426
|
+
const start = new Date(formValue.customRange.from || "");
|
|
10427
|
+
const end = new Date(formValue.customRange.to || "");
|
|
10413
10428
|
setTimeout(() => {
|
|
10414
10429
|
datepicker.rangeDatepicker?.setDates(start, end);
|
|
10415
10430
|
}, 1000);
|
|
@@ -10419,19 +10434,19 @@ class DateComponent extends AggregationComponent {
|
|
|
10419
10434
|
const value = this.form.value;
|
|
10420
10435
|
// value.option is null
|
|
10421
10436
|
if (!value.option) {
|
|
10422
|
-
throw new Error(
|
|
10437
|
+
throw new Error("filters.selectionInvalid");
|
|
10423
10438
|
}
|
|
10424
|
-
if (value.option !==
|
|
10439
|
+
if (value.option !== "custom-range") {
|
|
10425
10440
|
const dateOption = this.dateOptions().find((option) => option.display === value.option);
|
|
10426
10441
|
const aggregation = this.aggregation();
|
|
10427
10442
|
if (!aggregation) {
|
|
10428
|
-
throw new Error(
|
|
10443
|
+
throw new Error("filters.aggregationNotFound");
|
|
10429
10444
|
}
|
|
10430
10445
|
return {
|
|
10431
10446
|
name: aggregation.name,
|
|
10432
|
-
operator: dateOption?.operator ||
|
|
10447
|
+
operator: dateOption?.operator || "eq",
|
|
10433
10448
|
field: aggregation.column,
|
|
10434
|
-
display: dateOption?.display ??
|
|
10449
|
+
display: dateOption?.display ?? "",
|
|
10435
10450
|
filters: dateOption?.filters,
|
|
10436
10451
|
value: dateOption?.value
|
|
10437
10452
|
};
|
|
@@ -10442,7 +10457,7 @@ class DateComponent extends AggregationComponent {
|
|
|
10442
10457
|
// if both are not null, operator is between
|
|
10443
10458
|
const aggregation = this.aggregation();
|
|
10444
10459
|
if (!aggregation) {
|
|
10445
|
-
throw new Error(
|
|
10460
|
+
throw new Error("filters.aggregationNotFound");
|
|
10446
10461
|
}
|
|
10447
10462
|
const filter = {
|
|
10448
10463
|
name: aggregation.name,
|
|
@@ -10450,24 +10465,24 @@ class DateComponent extends AggregationComponent {
|
|
|
10450
10465
|
display: value.option
|
|
10451
10466
|
};
|
|
10452
10467
|
if (value.customRange.from && value.customRange.to) {
|
|
10453
|
-
filter.operator =
|
|
10468
|
+
filter.operator = "between";
|
|
10454
10469
|
filter.start = value.customRange.from;
|
|
10455
10470
|
filter.end = value.customRange.to;
|
|
10456
10471
|
}
|
|
10457
10472
|
else if (value.customRange.from) {
|
|
10458
|
-
filter.operator =
|
|
10473
|
+
filter.operator = "gte";
|
|
10459
10474
|
filter.value = value.customRange.from;
|
|
10460
10475
|
}
|
|
10461
10476
|
else if (value.customRange.to) {
|
|
10462
|
-
filter.operator =
|
|
10477
|
+
filter.operator = "lte";
|
|
10463
10478
|
filter.value = value.customRange.to;
|
|
10464
10479
|
}
|
|
10465
10480
|
else {
|
|
10466
|
-
throw new Error(
|
|
10481
|
+
throw new Error("filters.customRangeInvalid");
|
|
10467
10482
|
}
|
|
10468
10483
|
return filter;
|
|
10469
10484
|
}
|
|
10470
|
-
throw new Error(
|
|
10485
|
+
throw new Error("filters.filterInvalid");
|
|
10471
10486
|
}
|
|
10472
10487
|
onDateChange(event) {
|
|
10473
10488
|
// Get the selected dates
|
|
@@ -10490,11 +10505,11 @@ class DateComponent extends AggregationComponent {
|
|
|
10490
10505
|
}
|
|
10491
10506
|
}
|
|
10492
10507
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: DateComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
10493
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: DateComponent, isStandalone: true, selector: "date-filter,DateFilter", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, displayEmptyDistributionIntervals: { classPropertyName: "displayEmptyDistributionIntervals", publicName: "displayEmptyDistributionIntervals", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope(
|
|
10508
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", type: DateComponent, isStandalone: true, selector: "date-filter,DateFilter", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, displayEmptyDistributionIntervals: { classPropertyName: "displayEmptyDistributionIntervals", publicName: "displayEmptyDistributionIntervals", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "@container" }, providers: [provideTranslocoScope("filters")], viewQueries: [{ propertyName: "datepicker", first: true, predicate: DateRangePickerDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<details (toggle)=\"onToggle($event)\" [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full select-none items-center pl-1 text-sm font-semibold\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @if (aggregation()?.icon) {\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\n }\n <span class=\"grow\">{{ aggregation()?.display | syslang | transloco }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n [attr.title]=\"'filters.clearFilters' | transloco\"\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\n (click)=\"clear()\"\n (keydown.enter)=\"clear()\">\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\n </button>\n }\n\n @if (selection() && validSelection()) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n [attr.title]=\"'filters.applyFilters' | transloco\"\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\n (click)=\"apply()\"\n (keydown.enter)=\"apply()\">\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (collapsible()) {\n <button variant=\"none\" title=\"Open/Close\" class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul class=\"flex flex-col gap-1 pt-2 scrollbar-thin max-h-[calc(var(--height,100%)-100px)] snap-y snap-start overflow-auto\" role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label for=\"date-filter-{{ option.display }}\" class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li role=\"listitem\" aria-label=\"custom range\" class=\"flex px-2 leading-7\" [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input #radiorange type=\"radio\" formControlName=\"option\" id=\"date-filter-custom-range\" value=\"custom-range\" (click)=\"select()\" />\n\n <div\n class=\"flex @max-[340px]:flex-wrap grow gap-1 p-1 @container\"\n daterangepicker\n datepicker-buttons\n [datepicker-language]=\"lang()\"\n [datepicker-min]=\"form.get('customRange.from')?.value || undefined\"\n [datepicker-max]=\"form.get('customRange.to')?.value ?? today.toISOString()\"\n (click)=\"radiorange.click()\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10\">{{ 'from' | transloco }}</label>\n <input id=\"datepicker-range-start\" name=\"start\" type=\"text\" class=\"h-8 min-w-[13ch]\" />\n </div>\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-end\" class=\"text-right min-w-10\">{{ 'to' | transloco }}</label>\n <input id=\"datepicker-range-end\" name=\"end\" type=\"text\" class=\"h-8 min-w-[13ch]\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n", styles: [":host{display:block;width:340px;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"], dependencies: [{ 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\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button,[role=\"button\"]", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: DateRangePickerDirective, selector: "[daterangepicker]", inputs: ["datepicker-title", "datepicker-autohide", "datepicker-clear", "datepicker-today", "datepicker-buttons", "datepicker-today-highlight", "datepicker-language", "datepicker-format", "datepicker-max", "datepicker-min", "datepicker-orientation"] }, { kind: "component", type: ChevronRightIconComponent, selector: "chevron-right, ChevronRight, chevronright", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
|
|
10494
10509
|
}
|
|
10495
10510
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: DateComponent, decorators: [{
|
|
10496
10511
|
type: Component,
|
|
10497
|
-
args: [{ selector:
|
|
10512
|
+
args: [{ selector: "date-filter,DateFilter", standalone: true, providers: [provideTranslocoScope("filters")], imports: [
|
|
10498
10513
|
InputComponent,
|
|
10499
10514
|
ButtonComponent,
|
|
10500
10515
|
ListItemComponent,
|
|
@@ -10503,7 +10518,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
|
|
|
10503
10518
|
SyslangPipe,
|
|
10504
10519
|
DateRangePickerDirective,
|
|
10505
10520
|
ChevronRightIconComponent
|
|
10506
|
-
],
|
|
10521
|
+
], host: {
|
|
10522
|
+
class: "@container"
|
|
10523
|
+
}, template: "<details (toggle)=\"onToggle($event)\" [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full select-none items-center pl-1 text-sm font-semibold\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @if (aggregation()?.icon) {\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\n }\n <span class=\"grow\">{{ aggregation()?.display | syslang | transloco }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n [attr.title]=\"'filters.clearFilters' | transloco\"\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\n (click)=\"clear()\"\n (keydown.enter)=\"clear()\">\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\n </button>\n }\n\n @if (selection() && validSelection()) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n [attr.title]=\"'filters.applyFilters' | transloco\"\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\n (click)=\"apply()\"\n (keydown.enter)=\"apply()\">\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (collapsible()) {\n <button variant=\"none\" title=\"Open/Close\" class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul class=\"flex flex-col gap-1 pt-2 scrollbar-thin max-h-[calc(var(--height,100%)-100px)] snap-y snap-start overflow-auto\" role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label for=\"date-filter-{{ option.display }}\" class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li role=\"listitem\" aria-label=\"custom range\" class=\"flex px-2 leading-7\" [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input #radiorange type=\"radio\" formControlName=\"option\" id=\"date-filter-custom-range\" value=\"custom-range\" (click)=\"select()\" />\n\n <div\n class=\"flex @max-[340px]:flex-wrap grow gap-1 p-1 @container\"\n daterangepicker\n datepicker-buttons\n [datepicker-language]=\"lang()\"\n [datepicker-min]=\"form.get('customRange.from')?.value || undefined\"\n [datepicker-max]=\"form.get('customRange.to')?.value ?? today.toISOString()\"\n (click)=\"radiorange.click()\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10\">{{ 'from' | transloco }}</label>\n <input id=\"datepicker-range-start\" name=\"start\" type=\"text\" class=\"h-8 min-w-[13ch]\" />\n </div>\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-end\" class=\"text-right min-w-10\">{{ 'to' | transloco }}</label>\n <input id=\"datepicker-range-end\" name=\"end\" type=\"text\" class=\"h-8 min-w-[13ch]\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n", styles: [":host{display:block;width:340px;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
|
|
10507
10524
|
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { datepicker: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DateRangePickerDirective), { isSignal: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], displayEmptyDistributionIntervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayEmptyDistributionIntervals", required: false }] }] } });
|
|
10508
10525
|
|
|
10509
10526
|
class FilterButtonComponent {
|
|
@@ -10596,13 +10613,19 @@ class FilterButtonComponent {
|
|
|
10596
10613
|
}
|
|
10597
10614
|
</button>
|
|
10598
10615
|
|
|
10599
|
-
<PopoverContent
|
|
10616
|
+
<PopoverContent
|
|
10617
|
+
class="min-w-fit w-max max-w-[90vw]"
|
|
10618
|
+
[position]="position()"
|
|
10619
|
+
[offset]="offset()"
|
|
10620
|
+
>
|
|
10600
10621
|
@if (isDate(filter().column)) {
|
|
10601
10622
|
<DateFilter
|
|
10623
|
+
class="*:details-content:[--height:19lh] w-max max-w-80"
|
|
10602
10624
|
[name]="filter().name"
|
|
10603
10625
|
[column]="filter().column"
|
|
10604
10626
|
id="filter-{{ filter().column }}"
|
|
10605
|
-
[title]="{ label: 'Date', icon: 'far fa-calendar-day' }"
|
|
10627
|
+
[title]="{ label: 'Date', icon: 'far fa-calendar-day' }"
|
|
10628
|
+
/>
|
|
10606
10629
|
} @else {
|
|
10607
10630
|
<Aggregation
|
|
10608
10631
|
class="*:details-content:[--height:19lh] w-max max-w-80"
|
|
@@ -10660,13 +10683,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
|
|
|
10660
10683
|
}
|
|
10661
10684
|
</button>
|
|
10662
10685
|
|
|
10663
|
-
<PopoverContent
|
|
10686
|
+
<PopoverContent
|
|
10687
|
+
class="min-w-fit w-max max-w-[90vw]"
|
|
10688
|
+
[position]="position()"
|
|
10689
|
+
[offset]="offset()"
|
|
10690
|
+
>
|
|
10664
10691
|
@if (isDate(filter().column)) {
|
|
10665
10692
|
<DateFilter
|
|
10693
|
+
class="*:details-content:[--height:19lh] w-max max-w-80"
|
|
10666
10694
|
[name]="filter().name"
|
|
10667
10695
|
[column]="filter().column"
|
|
10668
10696
|
id="filter-{{ filter().column }}"
|
|
10669
|
-
[title]="{ label: 'Date', icon: 'far fa-calendar-day' }"
|
|
10697
|
+
[title]="{ label: 'Date', icon: 'far fa-calendar-day' }"
|
|
10698
|
+
/>
|
|
10670
10699
|
} @else {
|
|
10671
10700
|
<Aggregation
|
|
10672
10701
|
class="*:details-content:[--height:19lh] w-max max-w-80"
|
|
@@ -11043,17 +11072,11 @@ class FiltersBarComponent {
|
|
|
11043
11072
|
* ```
|
|
11044
11073
|
*/
|
|
11045
11074
|
getFilterCriteria = () => {
|
|
11046
|
-
const filtersbyName = this.appStore
|
|
11047
|
-
.filters()
|
|
11048
|
-
.map((f) => f.name)
|
|
11049
|
-
.filter((name) => name !== undefined);
|
|
11050
|
-
const filtersByColumn = this.appStore
|
|
11051
|
-
.filters()
|
|
11052
|
-
.map((f) => f.column)
|
|
11053
|
-
.filter((column) => column !== undefined);
|
|
11054
11075
|
return (filter) => {
|
|
11055
|
-
|
|
11056
|
-
|
|
11076
|
+
return this.appStore
|
|
11077
|
+
.filters()
|
|
11078
|
+
.some((f) => (!!f.name && filter.name === f.name && filter.column === f.column) ||
|
|
11079
|
+
(!f.name && filter.column === f.column));
|
|
11057
11080
|
};
|
|
11058
11081
|
};
|
|
11059
11082
|
constructor() {
|
|
@@ -12405,9 +12428,12 @@ class SignInComponent {
|
|
|
12405
12428
|
config = globalConfig;
|
|
12406
12429
|
class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : []));
|
|
12407
12430
|
changePassword = output();
|
|
12408
|
-
username = model(
|
|
12409
|
-
password = model(
|
|
12410
|
-
credentials = computed(() => ({
|
|
12431
|
+
username = model('', ...(ngDevMode ? [{ debugName: "username" }] : []));
|
|
12432
|
+
password = model('', ...(ngDevMode ? [{ debugName: "password" }] : []));
|
|
12433
|
+
credentials = computed(() => ({
|
|
12434
|
+
username: this.username(),
|
|
12435
|
+
password: this.password(),
|
|
12436
|
+
}), ...(ngDevMode ? [{ debugName: "credentials" }] : []));
|
|
12411
12437
|
authenticated = signal(isAuthenticated(), ...(ngDevMode ? [{ debugName: "authenticated" }] : []));
|
|
12412
12438
|
user = signal(null, ...(ngDevMode ? [{ debugName: "user" }] : []));
|
|
12413
12439
|
returnUrl = signal(null, ...(ngDevMode ? [{ debugName: "returnUrl" }] : []));
|
|
@@ -12416,6 +12442,7 @@ class SignInComponent {
|
|
|
12416
12442
|
principalService = inject(PrincipalService);
|
|
12417
12443
|
applicationService = inject(ApplicationService);
|
|
12418
12444
|
appStore = inject(AppStore);
|
|
12445
|
+
navigationService = inject(NavigationService);
|
|
12419
12446
|
isValid = computed(() => {
|
|
12420
12447
|
const creds = this.credentials();
|
|
12421
12448
|
return creds?.username?.length > 0 && creds?.password?.length > 0;
|
|
@@ -12432,20 +12459,20 @@ class SignInComponent {
|
|
|
12432
12459
|
});
|
|
12433
12460
|
effect(() => {
|
|
12434
12461
|
if (this.returnUrl() !== null) {
|
|
12435
|
-
const [url] = this.returnUrl() || [
|
|
12462
|
+
const [url] = this.returnUrl() || ['/'];
|
|
12436
12463
|
this.router.navigateByUrl(url);
|
|
12437
12464
|
}
|
|
12438
12465
|
});
|
|
12439
|
-
fromEvent(window,
|
|
12466
|
+
fromEvent(window, 'authenticated')
|
|
12440
12467
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
12441
12468
|
.subscribe((event) => {
|
|
12442
12469
|
this.authenticated.set(event.detail.authenticated);
|
|
12443
|
-
const url = this.route.snapshot.queryParams[
|
|
12470
|
+
const url = this.route.snapshot.queryParams['returnUrl'] || null;
|
|
12444
12471
|
if (url !== null) {
|
|
12445
12472
|
this.returnUrl.set([url]);
|
|
12446
12473
|
}
|
|
12447
12474
|
if (isAuthenticated()) {
|
|
12448
|
-
this.router.navigateByUrl(url ??
|
|
12475
|
+
this.router.navigateByUrl(url ?? '/');
|
|
12449
12476
|
}
|
|
12450
12477
|
});
|
|
12451
12478
|
}
|
|
@@ -12459,8 +12486,8 @@ class SignInComponent {
|
|
|
12459
12486
|
}
|
|
12460
12487
|
async handleLogin() {
|
|
12461
12488
|
login().catch((error) => {
|
|
12462
|
-
console.warn(
|
|
12463
|
-
this.router.navigate([
|
|
12489
|
+
console.warn('An error occurred while logging in', error);
|
|
12490
|
+
this.router.navigate(['error']);
|
|
12464
12491
|
});
|
|
12465
12492
|
}
|
|
12466
12493
|
async handleLoginWithCredentials() {
|
|
@@ -12468,83 +12495,109 @@ class SignInComponent {
|
|
|
12468
12495
|
return;
|
|
12469
12496
|
try {
|
|
12470
12497
|
const response = await login(this.credentials());
|
|
12471
|
-
info(
|
|
12498
|
+
info('SignIn Login response:', response);
|
|
12472
12499
|
if (response) {
|
|
12473
12500
|
const { createRoutes = false } = globalConfig;
|
|
12474
12501
|
this.applicationService.initialize(createRoutes);
|
|
12475
12502
|
}
|
|
12476
12503
|
}
|
|
12477
12504
|
catch (err) {
|
|
12478
|
-
warn(
|
|
12479
|
-
if (typeof err ===
|
|
12480
|
-
notify.error(
|
|
12505
|
+
warn('An error occurred while logging in', err);
|
|
12506
|
+
if (typeof err === 'string') {
|
|
12507
|
+
notify.error('Login', { description: err });
|
|
12481
12508
|
}
|
|
12482
12509
|
else {
|
|
12483
12510
|
const { errorMessage } = err;
|
|
12484
|
-
notify.error(
|
|
12511
|
+
notify.error('Login', { description: errorMessage });
|
|
12485
12512
|
}
|
|
12486
12513
|
}
|
|
12487
12514
|
}
|
|
12488
12515
|
handleBack() {
|
|
12489
|
-
|
|
12490
|
-
window.history.back();
|
|
12491
|
-
}
|
|
12492
|
-
catch (err) {
|
|
12493
|
-
error("Error navigating back:", err);
|
|
12494
|
-
this.router.navigate(["/"]);
|
|
12495
|
-
}
|
|
12516
|
+
this.router.navigate([this.navigationService.urlAfterNavigation || "/"]);
|
|
12496
12517
|
}
|
|
12497
12518
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: SignInComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
12498
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", 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: { changePassword: "changePassword", username: "usernameChange", password: "passwordChange" }, host: { properties: { "class": "cn('grid h-full w-full place-content-center', class())" } }, providers: [provideTranslocoScope(
|
|
12499
|
-
<Card
|
|
12519
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.7", 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: { changePassword: "changePassword", username: "usernameChange", password: "passwordChange" }, host: { properties: { "class": "cn('grid h-full w-full place-content-center', class())" } }, providers: [provideTranslocoScope('login')], ngImport: i0, template: `
|
|
12520
|
+
<Card
|
|
12521
|
+
hover="no"
|
|
12522
|
+
cdkTrapFocus
|
|
12523
|
+
cdkTrapFocusAutoCapture="true"
|
|
12524
|
+
class="bg-card rounded-xl shadow-sm"
|
|
12525
|
+
>
|
|
12500
12526
|
@if (authenticated()) {
|
|
12501
|
-
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
|
|
12508
|
-
|
|
12509
|
-
|
|
12510
|
-
|
|
12511
|
-
|
|
12527
|
+
<CardHeader class="flex flex-row items-start gap-4">
|
|
12528
|
+
<img class="content-(--logo-large) h-12" alt="logo" />
|
|
12529
|
+
<div class="space-y-1">
|
|
12530
|
+
<h3 class="text-2xl font-semibold leading-tight">
|
|
12531
|
+
{{
|
|
12532
|
+
'login.welcomeBack' | transloco : { name: user()?.fullName ?? '' }
|
|
12533
|
+
}}
|
|
12534
|
+
</h3>
|
|
12535
|
+
<p class="text-muted-foreground text-sm">
|
|
12536
|
+
{{ 'login.youAreLoggedIn' | transloco }}
|
|
12537
|
+
</p>
|
|
12538
|
+
</div>
|
|
12539
|
+
</CardHeader>
|
|
12512
12540
|
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
</
|
|
12541
|
+
<CardFooter class="grid grid-cols-2 gap-3">
|
|
12542
|
+
<button type="button" (click)="handleLogout()">
|
|
12543
|
+
{{ 'login.disconnect' | transloco }}
|
|
12544
|
+
</button>
|
|
12545
|
+
<button (click)="handleBack()">{{ 'login.back' | transloco }}</button>
|
|
12546
|
+
</CardFooter>
|
|
12517
12547
|
} @else {
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
|
|
12530
|
-
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
+
<CardHeader class="flex flex-col items-center gap-3 text-center">
|
|
12549
|
+
<img class="content-(--logo-large) h-12" alt="logo" />
|
|
12550
|
+
</CardHeader>
|
|
12551
|
+
|
|
12552
|
+
<CardContent class="grid gap-4">
|
|
12553
|
+
@if (!config.autoOAuthProvider && !config.autoSAMLProvider) {
|
|
12554
|
+
<div class="grid gap-2">
|
|
12555
|
+
<label class="text-sm font-medium" for="username">{{
|
|
12556
|
+
'login.username' | transloco
|
|
12557
|
+
}}</label>
|
|
12558
|
+
<input
|
|
12559
|
+
id="username"
|
|
12560
|
+
type="text"
|
|
12561
|
+
required
|
|
12562
|
+
[(ngModel)]="username"
|
|
12563
|
+
(keydown.enter)="handleLoginWithCredentials()"
|
|
12564
|
+
/>
|
|
12565
|
+
</div>
|
|
12566
|
+
|
|
12567
|
+
<div class="grid gap-2">
|
|
12568
|
+
<label class="text-sm font-medium" for="password">{{
|
|
12569
|
+
'login.password' | transloco
|
|
12570
|
+
}}</label>
|
|
12571
|
+
<input
|
|
12572
|
+
id="password"
|
|
12573
|
+
type="password"
|
|
12574
|
+
required
|
|
12575
|
+
[(ngModel)]="password"
|
|
12576
|
+
(keydown.enter)="handleLoginWithCredentials()"
|
|
12577
|
+
/>
|
|
12578
|
+
</div>
|
|
12579
|
+
|
|
12580
|
+
<button
|
|
12581
|
+
variant="primary"
|
|
12582
|
+
[disabled]="!isValid()"
|
|
12583
|
+
(click)="handleLoginWithCredentials()"
|
|
12584
|
+
>
|
|
12585
|
+
{{ 'login.connect' | transloco }}
|
|
12586
|
+
</button>
|
|
12587
|
+
@if (allowChangePassword()) {
|
|
12588
|
+
<button (click)="changePassword.emit()">
|
|
12589
|
+
{{ 'login.changePassword' | transloco }}
|
|
12590
|
+
</button>
|
|
12591
|
+
} } @else {
|
|
12592
|
+
<button (click)="handleLogin()">
|
|
12593
|
+
{{
|
|
12594
|
+
'login.SignInWith'
|
|
12595
|
+
| transloco
|
|
12596
|
+
: { provider: config.autoOAuthProvider ? 'OAuth' : 'SAML' }
|
|
12597
|
+
}}
|
|
12598
|
+
</button>
|
|
12599
|
+
}
|
|
12600
|
+
</CardContent>
|
|
12548
12601
|
}
|
|
12549
12602
|
</Card>
|
|
12550
12603
|
`, isInline: true, 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\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button,[role=\"button\"]", inputs: ["class", "variant", "decoration", "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: "directive", type: CardFooterComponent, selector: ".card-footer, card-footer, CardFooter, cardfooter", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
@@ -12552,7 +12605,7 @@ class SignInComponent {
|
|
|
12552
12605
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImport: i0, type: SignInComponent, decorators: [{
|
|
12553
12606
|
type: Component,
|
|
12554
12607
|
args: [{
|
|
12555
|
-
selector:
|
|
12608
|
+
selector: 'signIn, signin, sign-in',
|
|
12556
12609
|
imports: [
|
|
12557
12610
|
RouterModule,
|
|
12558
12611
|
FormsModule,
|
|
@@ -12563,65 +12616,97 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.7", ngImpor
|
|
|
12563
12616
|
CardComponent,
|
|
12564
12617
|
CardHeaderComponent,
|
|
12565
12618
|
CardContentComponent,
|
|
12566
|
-
CardFooterComponent
|
|
12619
|
+
CardFooterComponent,
|
|
12567
12620
|
],
|
|
12568
|
-
providers: [provideTranslocoScope(
|
|
12621
|
+
providers: [provideTranslocoScope('login')],
|
|
12569
12622
|
template: `
|
|
12570
|
-
<Card
|
|
12623
|
+
<Card
|
|
12624
|
+
hover="no"
|
|
12625
|
+
cdkTrapFocus
|
|
12626
|
+
cdkTrapFocusAutoCapture="true"
|
|
12627
|
+
class="bg-card rounded-xl shadow-sm"
|
|
12628
|
+
>
|
|
12571
12629
|
@if (authenticated()) {
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12630
|
+
<CardHeader class="flex flex-row items-start gap-4">
|
|
12631
|
+
<img class="content-(--logo-large) h-12" alt="logo" />
|
|
12632
|
+
<div class="space-y-1">
|
|
12633
|
+
<h3 class="text-2xl font-semibold leading-tight">
|
|
12634
|
+
{{
|
|
12635
|
+
'login.welcomeBack' | transloco : { name: user()?.fullName ?? '' }
|
|
12636
|
+
}}
|
|
12637
|
+
</h3>
|
|
12638
|
+
<p class="text-muted-foreground text-sm">
|
|
12639
|
+
{{ 'login.youAreLoggedIn' | transloco }}
|
|
12640
|
+
</p>
|
|
12641
|
+
</div>
|
|
12642
|
+
</CardHeader>
|
|
12583
12643
|
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
</
|
|
12644
|
+
<CardFooter class="grid grid-cols-2 gap-3">
|
|
12645
|
+
<button type="button" (click)="handleLogout()">
|
|
12646
|
+
{{ 'login.disconnect' | transloco }}
|
|
12647
|
+
</button>
|
|
12648
|
+
<button (click)="handleBack()">{{ 'login.back' | transloco }}</button>
|
|
12649
|
+
</CardFooter>
|
|
12588
12650
|
} @else {
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12651
|
+
<CardHeader class="flex flex-col items-center gap-3 text-center">
|
|
12652
|
+
<img class="content-(--logo-large) h-12" alt="logo" />
|
|
12653
|
+
</CardHeader>
|
|
12654
|
+
|
|
12655
|
+
<CardContent class="grid gap-4">
|
|
12656
|
+
@if (!config.autoOAuthProvider && !config.autoSAMLProvider) {
|
|
12657
|
+
<div class="grid gap-2">
|
|
12658
|
+
<label class="text-sm font-medium" for="username">{{
|
|
12659
|
+
'login.username' | transloco
|
|
12660
|
+
}}</label>
|
|
12661
|
+
<input
|
|
12662
|
+
id="username"
|
|
12663
|
+
type="text"
|
|
12664
|
+
required
|
|
12665
|
+
[(ngModel)]="username"
|
|
12666
|
+
(keydown.enter)="handleLoginWithCredentials()"
|
|
12667
|
+
/>
|
|
12668
|
+
</div>
|
|
12669
|
+
|
|
12670
|
+
<div class="grid gap-2">
|
|
12671
|
+
<label class="text-sm font-medium" for="password">{{
|
|
12672
|
+
'login.password' | transloco
|
|
12673
|
+
}}</label>
|
|
12674
|
+
<input
|
|
12675
|
+
id="password"
|
|
12676
|
+
type="password"
|
|
12677
|
+
required
|
|
12678
|
+
[(ngModel)]="password"
|
|
12679
|
+
(keydown.enter)="handleLoginWithCredentials()"
|
|
12680
|
+
/>
|
|
12681
|
+
</div>
|
|
12682
|
+
|
|
12683
|
+
<button
|
|
12684
|
+
variant="primary"
|
|
12685
|
+
[disabled]="!isValid()"
|
|
12686
|
+
(click)="handleLoginWithCredentials()"
|
|
12687
|
+
>
|
|
12688
|
+
{{ 'login.connect' | transloco }}
|
|
12689
|
+
</button>
|
|
12690
|
+
@if (allowChangePassword()) {
|
|
12691
|
+
<button (click)="changePassword.emit()">
|
|
12692
|
+
{{ 'login.changePassword' | transloco }}
|
|
12693
|
+
</button>
|
|
12694
|
+
} } @else {
|
|
12695
|
+
<button (click)="handleLogin()">
|
|
12696
|
+
{{
|
|
12697
|
+
'login.SignInWith'
|
|
12698
|
+
| transloco
|
|
12699
|
+
: { provider: config.autoOAuthProvider ? 'OAuth' : 'SAML' }
|
|
12700
|
+
}}
|
|
12701
|
+
</button>
|
|
12702
|
+
}
|
|
12703
|
+
</CardContent>
|
|
12619
12704
|
}
|
|
12620
12705
|
</Card>
|
|
12621
12706
|
`,
|
|
12622
12707
|
host: {
|
|
12623
|
-
|
|
12624
|
-
}
|
|
12708
|
+
'[class]': "cn('grid h-full w-full place-content-center', class())",
|
|
12709
|
+
},
|
|
12625
12710
|
}]
|
|
12626
12711
|
}], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], changePassword: [{ type: i0.Output, args: ["changePassword"] }], 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"] }] } });
|
|
12627
12712
|
|