@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.
@@ -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('?')[0]; // Extract route name
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 !== 'loading' && url !== this.urlAfterNavigation) {
3003
+ if (url && url !== "loading" && url !== this.urlAfterNavigation) {
3004
3004
  this.auditService.notifyRouteChange(url);
3005
3005
  }
3006
- }), tap(event => (this.urlAfterNavigation = event.url)), shareReplay(1));
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: 'root' });
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: 'root'
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('date allow custom range', { factory: () => true });
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: 'Date', icon: 'far fa-calendar-day' }, ...(ngDevMode ? [{ debugName: "title" }] : []));
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('changeDate', this.onDateChange.bind(this), {
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({ field: this.aggregation()?.column, name: this.aggregation()?.name }));
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 && (changes.option !== 'custom-range' || changes.customRange?.from !== null || changes.customRange?.to !== null));
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 { ...agg, items: agg?.items?.filter((item) => item.display !== 'custom-range') ?? [] };
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('Error applying date filter:', err);
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)?.display ?? 'custom-range';
10385
- let from, to;
10386
- if (code === 'custom-range') {
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 'lte':
10403
+ case "lte":
10389
10404
  to = filter.value;
10390
10405
  break;
10391
- case 'gte':
10406
+ case "gte":
10392
10407
  from = filter.value;
10393
10408
  break;
10394
- case 'between':
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 === 'custom-range' ? (from ?? null) : null,
10404
- to: code === 'custom-range' ? (to ?? null) : null
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('filters.selectionInvalid');
10437
+ throw new Error("filters.selectionInvalid");
10423
10438
  }
10424
- if (value.option !== 'custom-range') {
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('filters.aggregationNotFound');
10443
+ throw new Error("filters.aggregationNotFound");
10429
10444
  }
10430
10445
  return {
10431
10446
  name: aggregation.name,
10432
- operator: dateOption?.operator || 'eq',
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('filters.aggregationNotFound');
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 = 'between';
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 = 'gte';
10473
+ filter.operator = "gte";
10459
10474
  filter.value = value.customRange.from;
10460
10475
  }
10461
10476
  else if (value.customRange.to) {
10462
- filter.operator = 'lte';
10477
+ filter.operator = "lte";
10463
10478
  filter.value = value.customRange.to;
10464
10479
  }
10465
10480
  else {
10466
- throw new Error('filters.customRangeInvalid');
10481
+ throw new Error("filters.customRangeInvalid");
10467
10482
  }
10468
10483
  return filter;
10469
10484
  }
10470
- throw new Error('filters.filterInvalid');
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('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 <div class=\"ms-4\">\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 </div>\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul class=\"flex flex-col gap-1 pt-2\" 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 w-[300px] grow gap-1 p-1\"\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 <label for=\"datepicker-range-start\">{{ 'from' | transloco }}</label>\n\n <input id=\"datepicker-range-start\" name=\"start\" type=\"text\" class=\"h-8\" />\n\n <label for=\"datepicker-range-end\">{{ 'to' | transloco }}</label>\n\n <input id=\"datepicker-range-end\" name=\"end\" type=\"text\" class=\"h-8\" />\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n", styles: [":host{display:block}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" }] });
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: 'date-filter,DateFilter', standalone: true, providers: [provideTranslocoScope('filters')], imports: [
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
- ], 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 <div class=\"ms-4\">\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 </div>\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul class=\"flex flex-col gap-1 pt-2\" 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 w-[300px] grow gap-1 p-1\"\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 <label for=\"datepicker-range-start\">{{ 'from' | transloco }}</label>\n\n <input id=\"datepicker-range-start\" name=\"start\" type=\"text\" class=\"h-8\" />\n\n <label for=\"datepicker-range-end\">{{ 'to' | transloco }}</label>\n\n <input id=\"datepicker-range-end\" name=\"end\" type=\"text\" class=\"h-8\" />\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n", styles: [":host{display:block}ul[role=list]{scrollbar-width:thin}\n"] }]
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 class="min-w-fit" [position]="position()" [offset]="offset()">
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 class="min-w-fit" [position]="position()" [offset]="offset()">
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
- const useColumnFilter = filtersbyName.length === 0;
11056
- return useColumnFilter ? filtersByColumn.includes(filter.column) : filtersbyName.includes(filter.name);
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("", ...(ngDevMode ? [{ debugName: "username" }] : []));
12409
- password = model("", ...(ngDevMode ? [{ debugName: "password" }] : []));
12410
- credentials = computed(() => ({ username: this.username(), password: this.password() }), ...(ngDevMode ? [{ debugName: "credentials" }] : []));
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, "authenticated")
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["returnUrl"] || null;
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("An error occurred while logging in", error);
12463
- this.router.navigate(["error"]);
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("SignIn Login response:", response);
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("An error occurred while logging in", err);
12479
- if (typeof err === "string") {
12480
- notify.error("Login", { description: err });
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("Login", { description: errorMessage });
12511
+ notify.error('Login', { description: errorMessage });
12485
12512
  }
12486
12513
  }
12487
12514
  }
12488
12515
  handleBack() {
12489
- try {
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("login")], ngImport: i0, template: `
12499
- <Card hover="no" cdkTrapFocus cdkTrapFocusAutoCapture="true" class="bg-card rounded-xl shadow-sm">
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
- <CardHeader class="flex flex-row items-start gap-4">
12502
- <img class="content-(--logo-large) h-12" alt="logo" />
12503
- <div class="space-y-1">
12504
- <h3 class="text-2xl font-semibold leading-tight">
12505
- {{ 'login.welcomeBack' | transloco: { name: user()?.fullName ?? '' } }}
12506
- </h3>
12507
- <p class="text-muted-foreground text-sm">
12508
- {{ 'login.youAreLoggedIn' | transloco }}
12509
- </p>
12510
- </div>
12511
- </CardHeader>
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
- <CardFooter class="grid grid-cols-2 gap-3">
12514
- <button type="button" (click)="handleLogout()">{{ 'login.disconnect' | transloco }}</button>
12515
- <button (click)="handleBack()">{{ 'login.back' | transloco }}</button>
12516
- </CardFooter>
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
- <CardHeader class="flex flex-col items-center gap-3 text-center">
12519
- <img class="content-(--logo-large) h-12" alt="logo" />
12520
- </CardHeader>
12521
-
12522
- <CardContent class="grid gap-4">
12523
- @if (!config.autoOAuthProvider && !config.autoSAMLProvider) {
12524
- <div class="grid gap-2">
12525
- <label class="text-sm font-medium" for="username">{{ 'login.username' | transloco }}</label>
12526
- <input id="username" type="text" required [(ngModel)]="username" (keydown.enter)="handleLoginWithCredentials()" />
12527
- </div>
12528
-
12529
- <div class="grid gap-2">
12530
- <label class="text-sm font-medium" for="password">{{ 'login.password' | transloco }}</label>
12531
- <input id="password" type="password" required [(ngModel)]="password" (keydown.enter)="handleLoginWithCredentials()" />
12532
- </div>
12533
-
12534
- <button variant="primary" [disabled]="!isValid()" (click)="handleLoginWithCredentials()">
12535
- {{ 'login.connect' | transloco }}
12536
- </button>
12537
- @if (allowChangePassword()) {
12538
- <button (click)="changePassword.emit()">
12539
- {{ 'login.changePassword' | transloco }}
12540
- </button>
12541
- }
12542
- } @else {
12543
- <button (click)="handleLogin()">
12544
- {{ 'login.SignInWith' | transloco: { provider: config.autoOAuthProvider ? 'OAuth' : 'SAML' } }}
12545
- </button>
12546
- }
12547
- </CardContent>
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: "signIn, signin, sign-in",
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("login")],
12621
+ providers: [provideTranslocoScope('login')],
12569
12622
  template: `
12570
- <Card hover="no" cdkTrapFocus cdkTrapFocusAutoCapture="true" class="bg-card rounded-xl shadow-sm">
12623
+ <Card
12624
+ hover="no"
12625
+ cdkTrapFocus
12626
+ cdkTrapFocusAutoCapture="true"
12627
+ class="bg-card rounded-xl shadow-sm"
12628
+ >
12571
12629
  @if (authenticated()) {
12572
- <CardHeader class="flex flex-row items-start gap-4">
12573
- <img class="content-(--logo-large) h-12" alt="logo" />
12574
- <div class="space-y-1">
12575
- <h3 class="text-2xl font-semibold leading-tight">
12576
- {{ 'login.welcomeBack' | transloco: { name: user()?.fullName ?? '' } }}
12577
- </h3>
12578
- <p class="text-muted-foreground text-sm">
12579
- {{ 'login.youAreLoggedIn' | transloco }}
12580
- </p>
12581
- </div>
12582
- </CardHeader>
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
- <CardFooter class="grid grid-cols-2 gap-3">
12585
- <button type="button" (click)="handleLogout()">{{ 'login.disconnect' | transloco }}</button>
12586
- <button (click)="handleBack()">{{ 'login.back' | transloco }}</button>
12587
- </CardFooter>
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
- <CardHeader class="flex flex-col items-center gap-3 text-center">
12590
- <img class="content-(--logo-large) h-12" alt="logo" />
12591
- </CardHeader>
12592
-
12593
- <CardContent class="grid gap-4">
12594
- @if (!config.autoOAuthProvider && !config.autoSAMLProvider) {
12595
- <div class="grid gap-2">
12596
- <label class="text-sm font-medium" for="username">{{ 'login.username' | transloco }}</label>
12597
- <input id="username" type="text" required [(ngModel)]="username" (keydown.enter)="handleLoginWithCredentials()" />
12598
- </div>
12599
-
12600
- <div class="grid gap-2">
12601
- <label class="text-sm font-medium" for="password">{{ 'login.password' | transloco }}</label>
12602
- <input id="password" type="password" required [(ngModel)]="password" (keydown.enter)="handleLoginWithCredentials()" />
12603
- </div>
12604
-
12605
- <button variant="primary" [disabled]="!isValid()" (click)="handleLoginWithCredentials()">
12606
- {{ 'login.connect' | transloco }}
12607
- </button>
12608
- @if (allowChangePassword()) {
12609
- <button (click)="changePassword.emit()">
12610
- {{ 'login.changePassword' | transloco }}
12611
- </button>
12612
- }
12613
- } @else {
12614
- <button (click)="handleLogin()">
12615
- {{ 'login.SignInWith' | transloco: { provider: config.autoOAuthProvider ? 'OAuth' : 'SAML' } }}
12616
- </button>
12617
- }
12618
- </CardContent>
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
- "[class]": "cn('grid h-full w-full place-content-center', class())"
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