@sinequa/atomic-angular 0.4.22 → 0.4.37

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.
@@ -1,15 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, HostBinding, Component, Pipe, InjectionToken, computed, ChangeDetectorRef, DestroyRef, LOCALE_ID, Inject, Optional, input, output, signal, effect, assertInInjectionContext, runInInjectionContext, Injector, EventEmitter, Directive, viewChild, ElementRef, afterNextRender, untracked, linkedSignal, model, TemplateRef, HostListener, Renderer2, contentChildren, contentChild, booleanAttribute, resource, ViewContainerRef, viewChildren, numberAttribute, afterEveryRender } from '@angular/core';
2
+ import { Injectable, inject, HostBinding, Component, Pipe, InjectionToken, computed, ChangeDetectorRef, DestroyRef, LOCALE_ID, Inject, Optional, input, output, signal, effect, assertInInjectionContext, runInInjectionContext, Injector, EventEmitter, Directive, viewChild, ElementRef, afterNextRender, untracked, linkedSignal, model, TemplateRef, HostListener, Renderer2, contentChildren, contentChild, booleanAttribute, ChangeDetectionStrategy, resource, ViewContainerRef, viewChildren, numberAttribute, afterEveryRender } from '@angular/core';
3
3
  import { BehaviorSubject, Subscription, catchError, EMPTY, firstValueFrom, map, Subject, of, tap, throwError, filter, shareReplay, fromEvent, debounceTime, from, switchMap } from 'rxjs';
4
4
  import { TranslocoService, TranslocoPipe, provideTranslocoScope } from '@jsverse/transloco';
5
- import { DropdownComponent, DropdownContentComponent, InputComponent, ButtonComponent, cn, EllipsisIcon, ChevronRightIcon, MenuComponent, MenuContentComponent, MenuItemComponent, BadgeComponent, DialogComponent, DialogHeaderComponent, DialogTitleComponent, DialogContentComponent, DialogFooterComponent, ListItemComponent, SwitchComponent, SelectOptionDirective, DialogService, TabsComponent, TabsListComponent, TabComponent, ChevronLeftIconComponent, ChevronsLeftIconComponent, ChevronsRightIconComponent, Separator, SheetCloseDirective, SheetService, ButtonGroup, InputGroupInput, InputGroupComponent, InputGroupAddonComponent, SearchIcon, FilterIcon, DateRangePickerDirective, LoadingCircleIconComponent, CircleCheckIconComponent, PopoverComponent, HorizontalDividerComponent, CardComponent, CardHeaderComponent, CardContentComponent, CardFooterComponent, PopoverContentComponent, BookmarkIcon, UserIcon, TrashIcon, FolderIcon, VerticalDividerComponent, BreakpointObserverService, FlagEnglishIconComponent, FlagFrenchIconComponent, EditIcon, UndoIcon, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent } from '@sinequa/ui';
5
+ import { DropdownComponent, DropdownContentComponent, InputComponent, ButtonComponent, cn, EllipsisIcon, ChevronRightIcon, MenuComponent, MenuContentComponent, MenuItemComponent, BadgeComponent, DialogComponent, DialogHeaderComponent, DialogTitleComponent, DialogContentComponent, DialogFooterComponent, ListItemComponent, SwitchComponent, SelectOptionDirective, DialogService, TabsComponent, TabsListComponent, TabComponent, ChevronLeftIconComponent, ChevronsLeftIconComponent, ChevronsRightIconComponent, Separator, SheetCloseDirective, SheetService, DateRangePickerDirective, DatepickerDirective, ButtonGroup, InputGroupInput, InputGroupComponent, InputGroupAddonComponent, SearchIcon, FilterIcon, LoadingCircleIconComponent, CircleCheckIconComponent, PopoverComponent, CardComponent, CardHeaderComponent, CardContentComponent, CardFooterComponent, PopoverContentComponent, BookmarkIcon, UserIcon, TrashIcon, FolderIcon, VerticalDividerComponent, BreakpointObserverService, HorizontalDividerComponent, FlagEnglishIconComponent, FlagFrenchIconComponent, EditIcon, UndoIcon, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent } from '@sinequa/ui';
6
6
  import highlightWords from 'highlight-words';
7
7
  import { ActivatedRoute, Router, NavigationEnd, RouterLink, RouterModule } from '@angular/router';
8
8
  import { withDevtools } from '@angular-architects/ngrx-toolkit';
9
9
  import { signalStore, signalStoreFeature, withState, withMethods, patchState, getState, withComputed } from '@ngrx/signals';
10
10
  import { globalConfig, EngineType, extraColumns, sysLang, getQueryParamsFromUrl, logout, login, info, warn, error, setGlobalConfig, notify, addConcepts, queryParamsFromUrl, patchUserSettings, deleteUserSettings, fetchUserSettings, buildPathsAndLevels, escapeExpr, isAuthenticated, isExpired, debug, fetchSuggest, isObject, Audit, getMetadata, bisect, isNotInputEvent, fetchSponsoredLinks, fetchQuery, translateAggregationToDateOptions, aggItemRegex, parseValueAndOperatorFromItem, fetchSuggestField, fetchSimilarDocuments, fetchChangePassword, fetchSendPasswordResetEmail, expiresSoon, suggestionsToTreeAggregationNodes, labels, fetchLabels, guid, getRelativeDate, createUserProfile, deleteUserProfileProperty, patchUserProfile, isJsonable, addAuditAdditionalInfo, getToken, setToken, createHeaders } from '@sinequa/atomic';
11
11
  import { HttpClient, HttpParams, httpResource, HttpResponse, HttpHeaders, HttpContextToken } from '@angular/common/http';
12
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
12
+ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
13
13
  import { DatePipe, DATE_PIPE_DEFAULT_TIMEZONE, DATE_PIPE_DEFAULT_OPTIONS, Location, NgTemplateOutlet, NgStyle, NgClass, NgComponentOutlet } from '@angular/common';
14
14
  import { Title, DomSanitizer } from '@angular/platform-browser';
15
15
  import { cva } from 'class-variance-authority';
@@ -1242,6 +1242,8 @@ const initialPrincipal = {
1242
1242
  fullName: "",
1243
1243
  isAdministrator: false,
1244
1244
  isDelegatedAdmin: false,
1245
+ editablePartition: undefined,
1246
+ passwordExpirationDate: null,
1245
1247
  description: "",
1246
1248
  param1: "",
1247
1249
  param2: "",
@@ -1264,6 +1266,7 @@ const PrincipalStore = signalStore({ providedIn: 'root' }, withDevtools('Princip
1264
1266
  if (!fullName)
1265
1267
  return '';
1266
1268
  return fullName
1269
+ .trim()
1267
1270
  .split(' ')
1268
1271
  .map(word => word[0]?.toUpperCase())
1269
1272
  .join('');
@@ -4137,9 +4140,10 @@ class PreviewService {
4137
4140
  };
4138
4141
  // reset preview data
4139
4142
  this.previewData = undefined;
4143
+ this.events.set("loading");
4140
4144
  return this.http
4141
4145
  .post(`${this.API_URL}/preview`, body)
4142
- .pipe(tap((data) => this.setPreviewData(data)));
4146
+ .pipe(tap((data) => this.setPreviewData(data)), tap(() => this.events.set("loaded")));
4143
4147
  }
4144
4148
  /**
4145
4149
  * Closes the preview with the specified ID and updates the audit log.
@@ -4817,8 +4821,8 @@ class UserProfileService {
4817
4821
  * @param id - The ID of the user.
4818
4822
  * @returns An Observable that emits an the UserProfile object.
4819
4823
  */
4820
- getUserProfile(principal) {
4821
- return httpResource(() => (principal()?.userId ? `${this.API_URL}/${principal()?.userId}` : undefined), {
4824
+ getUserProfile(userId) {
4825
+ return httpResource(() => (userId() ? `${this.API_URL}/${userId()}` : undefined), {
4822
4826
  parse: (response) => {
4823
4827
  return response;
4824
4828
  }
@@ -4882,7 +4886,7 @@ class PagerComponent {
4882
4886
  </button>
4883
4887
  }
4884
4888
  </div>
4885
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
4889
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
4886
4890
  }
4887
4891
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: PagerComponent, decorators: [{
4888
4892
  type: Component,
@@ -5074,7 +5078,7 @@ class DocumentLocatorComponent {
5074
5078
 
5075
5079
  <div #documentLocator class="flex grow items-center gap-2 overflow-auto">
5076
5080
  @for (segment of visibleSegments(); track $index) {
5077
- <button decoration="underline" class="text-foreground h-auto cursor-pointer whitespace-nowrap p-0" (click)="navigateToSegment($index)">
5081
+ <button variant="link" class="text-foreground h-auto cursor-pointer whitespace-nowrap p-0" (click)="navigateToSegment($index)">
5078
5082
  {{ segment }}
5079
5083
  </button>
5080
5084
 
@@ -5103,7 +5107,7 @@ class DocumentLocatorComponent {
5103
5107
  </menu>
5104
5108
  }
5105
5109
  </div>
5106
- `, isInline: true, dependencies: [{ kind: "component", type: EllipsisIcon, selector: "ellipsis-icon, EllipsisIcon, ellipsisicon", inputs: ["class", "orientation"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "component", type: SourceComponent, selector: "source, Source", inputs: ["collection", "connector"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }] });
5110
+ `, isInline: true, dependencies: [{ kind: "component", type: EllipsisIcon, selector: "ellipsis-icon, EllipsisIcon, ellipsisicon", inputs: ["class", "orientation"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "component", type: SourceComponent, selector: "source, Source", inputs: ["collection", "connector"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }] });
5107
5111
  }
5108
5112
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DocumentLocatorComponent, decorators: [{
5109
5113
  type: Component,
@@ -5137,7 +5141,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
5137
5141
 
5138
5142
  <div #documentLocator class="flex grow items-center gap-2 overflow-auto">
5139
5143
  @for (segment of visibleSegments(); track $index) {
5140
- <button decoration="underline" class="text-foreground h-auto cursor-pointer whitespace-nowrap p-0" (click)="navigateToSegment($index)">
5144
+ <button variant="link" class="text-foreground h-auto cursor-pointer whitespace-nowrap p-0" (click)="navigateToSegment($index)">
5141
5145
  {{ segment }}
5142
5146
  </button>
5143
5147
 
@@ -5550,11 +5554,11 @@ class CollectionsDialog {
5550
5554
  }
5551
5555
 
5552
5556
  <DialogFooter class="flex flex-col">
5553
- <button decoration="outline" #closeBtn (click)="onClose()" >
5557
+ <button variant="outline" #closeBtn (click)="onClose()" >
5554
5558
  {{ 'collections.close' | transloco }}
5555
5559
  </button>
5556
5560
  <button
5557
- [decoration]="creating() ? 'outline' : undefined"
5561
+ [variant]="creating() ? 'outline' : undefined"
5558
5562
  tabindex="0"
5559
5563
  [attr.title]="(creating() ? 'collections.cancelCreation' : 'collections.createCollection') | transloco"
5560
5564
  (click)="onCreate()">
@@ -5572,7 +5576,7 @@ class CollectionsDialog {
5572
5576
  </DialogFooter>
5573
5577
  </DialogContent>
5574
5578
  </dialog>
5575
- `, isInline: true, dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
5579
+ `, isInline: true, dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
5576
5580
  }
5577
5581
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CollectionsDialog, decorators: [{
5578
5582
  type: Component,
@@ -5634,11 +5638,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
5634
5638
  }
5635
5639
 
5636
5640
  <DialogFooter class="flex flex-col">
5637
- <button decoration="outline" #closeBtn (click)="onClose()" >
5641
+ <button variant="outline" #closeBtn (click)="onClose()" >
5638
5642
  {{ 'collections.close' | transloco }}
5639
5643
  </button>
5640
5644
  <button
5641
- [decoration]="creating() ? 'outline' : undefined"
5645
+ [variant]="creating() ? 'outline' : undefined"
5642
5646
  tabindex="0"
5643
5647
  [attr.title]="(creating() ? 'collections.cancelCreation' : 'collections.createCollection') | transloco"
5644
5648
  (click)="onCreate()">
@@ -5889,7 +5893,7 @@ class ExportDialog {
5889
5893
  </section>
5890
5894
 
5891
5895
  <DialogFooter>
5892
- <button decoration="outline" (click)="dialog.close()">
5896
+ <button variant="outline" (click)="dialog.close()">
5893
5897
  {{ 'cancel' | transloco }}
5894
5898
  </button>
5895
5899
  <button tabindex="0" [attr.title]="'export.download' | transloco" (click)="onDownload()">
@@ -5898,7 +5902,7 @@ class ExportDialog {
5898
5902
  </DialogFooter>
5899
5903
  </DialogContent>
5900
5904
  </dialog>
5901
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "component", type: SwitchComponent, selector: "switch, Switch", inputs: ["toggled", "disabled", "class", "variant", "size"], outputs: ["toggledChange"] }, { kind: "directive", type: SelectOptionDirective, selector: "option", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
5905
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "component", type: SwitchComponent, selector: "switch, Switch", inputs: ["toggled", "disabled", "class", "variant", "size"], outputs: ["toggledChange"] }, { kind: "directive", type: SelectOptionDirective, selector: "option", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
5902
5906
  }
5903
5907
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ExportDialog, decorators: [{
5904
5908
  type: Component,
@@ -5978,7 +5982,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
5978
5982
  </section>
5979
5983
 
5980
5984
  <DialogFooter>
5981
- <button decoration="outline" (click)="dialog.close()">
5985
+ <button variant="outline" (click)="dialog.close()">
5982
5986
  {{ 'cancel' | transloco }}
5983
5987
  </button>
5984
5988
  <button tabindex="0" [attr.title]="'export.download' | transloco" (click)="onDownload()">
@@ -6906,11 +6910,18 @@ class OverflowManagerDirective {
6906
6910
  /**
6907
6911
  * Counts the number of items that can fit before the stop element.
6908
6912
  * Emits the count if it has changed.
6909
- * Debounces the count to avoid multiple updates.
6910
6913
  */
6911
6914
  countItems() {
6912
6915
  if (!this.items() || this.items().length === 0 || !this.stop())
6913
6916
  return;
6917
+ // Reset all items to their natural size before measuring so that previously
6918
+ // hidden items (display: none) don't corrupt the layout and position of
6919
+ // their siblings.
6920
+ this.items().forEach((item) => {
6921
+ item.nativeElement.style.display = "";
6922
+ });
6923
+ // getBoundingClientRect() forces a synchronous reflow, so positions are
6924
+ // accurate after the reset above.
6914
6925
  const stopRect = this.stop().nativeElement.getBoundingClientRect();
6915
6926
  const itemsRects = this.items().map((item) => item.nativeElement.getBoundingClientRect());
6916
6927
  let count = 0;
@@ -6924,10 +6935,14 @@ class OverflowManagerDirective {
6924
6935
  else
6925
6936
  break;
6926
6937
  }
6927
- if (this._lastCount === count)
6928
- return;
6929
- this._lastCount = count;
6930
- this.count.emit(count);
6938
+ if (this._lastCount !== count) {
6939
+ this._lastCount = count;
6940
+ this.count.emit(count);
6941
+ }
6942
+ else {
6943
+ // Count unchanged but items were reset above — re-apply the hidden state.
6944
+ this.toggleToCount(count);
6945
+ }
6931
6946
  }
6932
6947
  /**
6933
6948
  * Toggles the visibility of the items based on the count.
@@ -6935,11 +6950,9 @@ class OverflowManagerDirective {
6935
6950
  */
6936
6951
  toggleToCount(count) {
6937
6952
  this.items().forEach((item, index) => {
6938
- const state = index < count ? "visible" : "hidden";
6939
- // apply equivalent of tailwind invisible class
6940
- item.nativeElement.style.visibility = state;
6941
- item.nativeElement.style.height = state === "hidden" ? "0px" : "";
6942
- item.nativeElement.style.width = state === "hidden" ? "0px" : "";
6953
+ // display: none removes the item from the flex flow entirely, including
6954
+ // its gap contribution, which keeps sibling positions accurate.
6955
+ item.nativeElement.style.display = index < count ? "" : "none";
6943
6956
  });
6944
6957
  }
6945
6958
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OverflowManagerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -7051,8 +7064,6 @@ class NavbarTabsComponent {
7051
7064
  class = input(...(ngDevMode ? [undefined, { debugName: "class" }] : []));
7052
7065
  router = inject(Router);
7053
7066
  route = inject(ActivatedRoute);
7054
- drawerStack = inject(DrawerStackService);
7055
- drawerOpened = computed(() => this.drawerStack.isOpened(), ...(ngDevMode ? [{ debugName: "drawerOpened" }] : []));
7056
7067
  queryParamsStore = inject(QueryParamsStore);
7057
7068
  // Injecting the QueryService to access last search results
7058
7069
  queryService = inject(QueryService);
@@ -7064,6 +7075,8 @@ class NavbarTabsComponent {
7064
7075
  * This works only if tabSearch is enabled in the administration panel.
7065
7076
  */
7066
7077
  showCount = input(true, ...(ngDevMode ? [{ debugName: "showCount", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
7078
+ noTruncate = input(false, ...(ngDevMode ? [{ debugName: "noTruncate", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
7079
+ minTabWidth = input(...(ngDevMode ? [undefined, { debugName: "minTabWidth" }] : []));
7067
7080
  /**
7068
7081
  * The base path for the search routes.
7069
7082
  * This value is provided as an input property and defaults to "search".
@@ -7117,23 +7130,22 @@ class NavbarTabsComponent {
7117
7130
  return r;
7118
7131
  }, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
7119
7132
  moreTabs = computed(() => this.tabs().slice(this.visibleTabCount()), ...(ngDevMode ? [{ debugName: "moreTabs" }] : []));
7120
- changeTab() {
7121
- // we use the routerlink to navigate, so just close the drawer and remove the id parameter from the query params
7122
- this.drawerStack.closeAll();
7123
- }
7133
+ changeTab() { }
7124
7134
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: NavbarTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7125
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: NavbarTabsComponent, isStandalone: true, selector: "navbar-tabs", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, showCount: { classPropertyName: "showCount", publicName: "showCount", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "cn('block', class())" } }, ngImport: i0, template: `
7135
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: NavbarTabsComponent, isStandalone: true, selector: "navbar-tabs", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, showCount: { classPropertyName: "showCount", publicName: "showCount", isSignal: true, isRequired: false, transformFunction: null }, noTruncate: { classPropertyName: "noTruncate", publicName: "noTruncate", isSignal: true, isRequired: false, transformFunction: null }, minTabWidth: { classPropertyName: "minTabWidth", publicName: "minTabWidth", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "cn('block', class())" } }, ngImport: i0, template: `
7126
7136
  <!-- do not display the tabs if there are no tabs -->
7127
7137
  @if (tabs().length > 0) {
7128
- <div overflowManager (count)="visibleTabCount.set($event)" class="relative flex rounded-[inherit] bg-inherit">
7129
- <Tabs class="w-full overflow-hidden">
7138
+ <div overflowManager (count)="visibleTabCount.set($event)" class="flex items-end rounded-[inherit] bg-inherit">
7139
+ <Tabs class="flex-1 min-w-0 overflow-hidden">
7130
7140
  <TabsList class="w-full">
7131
7141
  @for (tab of tabs(); track $index) {
7132
7142
  <Tab
7133
- class="group min-w-20"
7143
+ class="group"
7134
7144
  title="{{ tab.display | syslang | transloco }}"
7135
7145
  value="{{ tab.display }}"
7136
7146
  overflowItem
7147
+ [noTruncate]="noTruncate()"
7148
+ [style.--tab-min-width]="minTabWidth()"
7137
7149
  [attr.aria-selected]="this.currentPath() === tab.path"
7138
7150
  [active]="this.currentPath() === tab.path"
7139
7151
  [routerLink]="[tab.routerLink]"
@@ -7141,13 +7153,13 @@ class NavbarTabsComponent {
7141
7153
  (click)="changeTab()"
7142
7154
  (keydown.enter)="router.navigate([tab.routerLink], { queryParams: { n: tab.queryName, q: searchText(), t: tab.wsQueryTab, f: undefined, sort: undefined, id: undefined, page: undefined } })"
7143
7155
  >
7144
- <div class="flex items-center content-start w-full overflow-hidden gap-1 min-w-0">
7156
+ <div [class]="cn('flex items-center content-start w-full gap-1', !noTruncate() && 'overflow-hidden min-w-0')">
7145
7157
  @if (tab.icon) {
7146
7158
  <i class="fa-fw {{ tab.icon }} " aria-hidden="true"></i>
7147
7159
  }
7148
- <span class="truncate">{{ tab.display | syslang | transloco }}</span>
7160
+ <span [class]="noTruncate() ? '' : 'truncate'">{{ tab.display | syslang | transloco }}</span>
7149
7161
  <!-- Show count badge only if count is > 0 -->
7150
- @if(tab.count || 0 > 0) {
7162
+ @if((tab.count ?? 0) > 0) {
7151
7163
  <Badge class="empty:hidden ml-auto px-1 group-[[variant=secondary]]:bg-primary group-[[variant=secondary]]:text-[#fff] bg-sage-200 text-primary group-[[disabled]]:bg-gray-800 group-[[disabled]]:text-[#fff] text-2xs">{{ tab.count }}</Badge>
7152
7164
  }
7153
7165
  </div>
@@ -7156,37 +7168,39 @@ class NavbarTabsComponent {
7156
7168
  </TabsList>
7157
7169
  </Tabs>
7158
7170
 
7159
- @if (moreTabs().length > 0) {
7160
- <Menu class="absolute right-0 top-1" overflowStop>
7161
- <button variant="ghost" size="icon" class="mb-1 truncate me-1" aria-label="more tabs">
7162
- <EllipsisIcon orientation="vertical"></EllipsisIcon>
7163
- </button>
7171
+ <!-- Always mounted so the stop position is stable; hidden when all tabs fit -->
7172
+ <Menu
7173
+ overflowStop
7174
+ class="shrink-0 top-1"
7175
+ [class.invisible]="moreTabs().length === 0"
7176
+ [class.pointer-events-none]="moreTabs().length === 0"
7177
+ >
7178
+ <button variant="ghost" size="icon" class="mb-1 truncate me-1" aria-label="more tabs">
7179
+ <EllipsisIcon orientation="vertical"></EllipsisIcon>
7180
+ </button>
7164
7181
 
7165
- <MenuContent class="z-500 w-fit" position="bottom-end">
7166
- @for (tab of moreTabs(); track $index) {
7167
- <MenuItem>
7168
- <a
7169
- class="inline-block whitespace-nowrap first-letter:capitalize"
7170
- [routerLink]="[tab.routerLink]"
7171
- [queryParams]="{ n: tab.queryName, q: searchText(), t: tab.wsQueryTab, f: undefined, sort: undefined, id: undefined, page: undefined }"
7172
- [attr.aria-selected]="this.currentPath() === tab.path"
7173
- [attr.aria-label]="tab.display | syslang | transloco"
7174
- (click)="changeTab()">
7175
- @if (tab.icon) {
7176
- <i class="fa-fw {{ tab.icon }} " aria-hidden="true"></i>
7177
- }
7178
- {{ tab.display | syslang | transloco }}
7179
- </a>
7180
- </MenuItem>
7181
- }
7182
- </MenuContent>
7183
- </Menu>
7184
- } @else {
7185
- <div class="absolute right-0" overflowStop></div>
7186
- }
7182
+ <MenuContent class="z-500 w-fit" position="bottom-end">
7183
+ @for (tab of moreTabs(); track $index) {
7184
+ <MenuItem>
7185
+ <a
7186
+ class="inline-block whitespace-nowrap first-letter:capitalize"
7187
+ [routerLink]="[tab.routerLink]"
7188
+ [queryParams]="{ n: tab.queryName, q: searchText(), t: tab.wsQueryTab, f: undefined, sort: undefined, id: undefined, page: undefined }"
7189
+ [attr.aria-selected]="this.currentPath() === tab.path"
7190
+ [attr.aria-label]="tab.display | syslang | transloco"
7191
+ (click)="changeTab()">
7192
+ @if (tab.icon) {
7193
+ <i class="fa-fw {{ tab.icon }} " aria-hidden="true"></i>
7194
+ }
7195
+ {{ tab.display | syslang | transloco }}
7196
+ </a>
7197
+ </MenuItem>
7198
+ }
7199
+ </MenuContent>
7200
+ </Menu>
7187
7201
  </div>
7188
7202
  }
7189
- `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: EllipsisIcon, selector: "ellipsis-icon, EllipsisIcon, ellipsisicon", inputs: ["class", "orientation"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
7203
+ `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "noTruncate", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: EllipsisIcon, selector: "ellipsis-icon, EllipsisIcon, ellipsisicon", inputs: ["class", "orientation"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
7190
7204
  }
7191
7205
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: NavbarTabsComponent, decorators: [{
7192
7206
  type: Component,
@@ -7213,15 +7227,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
7213
7227
  template: `
7214
7228
  <!-- do not display the tabs if there are no tabs -->
7215
7229
  @if (tabs().length > 0) {
7216
- <div overflowManager (count)="visibleTabCount.set($event)" class="relative flex rounded-[inherit] bg-inherit">
7217
- <Tabs class="w-full overflow-hidden">
7230
+ <div overflowManager (count)="visibleTabCount.set($event)" class="flex items-end rounded-[inherit] bg-inherit">
7231
+ <Tabs class="flex-1 min-w-0 overflow-hidden">
7218
7232
  <TabsList class="w-full">
7219
7233
  @for (tab of tabs(); track $index) {
7220
7234
  <Tab
7221
- class="group min-w-20"
7235
+ class="group"
7222
7236
  title="{{ tab.display | syslang | transloco }}"
7223
7237
  value="{{ tab.display }}"
7224
7238
  overflowItem
7239
+ [noTruncate]="noTruncate()"
7240
+ [style.--tab-min-width]="minTabWidth()"
7225
7241
  [attr.aria-selected]="this.currentPath() === tab.path"
7226
7242
  [active]="this.currentPath() === tab.path"
7227
7243
  [routerLink]="[tab.routerLink]"
@@ -7229,13 +7245,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
7229
7245
  (click)="changeTab()"
7230
7246
  (keydown.enter)="router.navigate([tab.routerLink], { queryParams: { n: tab.queryName, q: searchText(), t: tab.wsQueryTab, f: undefined, sort: undefined, id: undefined, page: undefined } })"
7231
7247
  >
7232
- <div class="flex items-center content-start w-full overflow-hidden gap-1 min-w-0">
7248
+ <div [class]="cn('flex items-center content-start w-full gap-1', !noTruncate() && 'overflow-hidden min-w-0')">
7233
7249
  @if (tab.icon) {
7234
7250
  <i class="fa-fw {{ tab.icon }} " aria-hidden="true"></i>
7235
7251
  }
7236
- <span class="truncate">{{ tab.display | syslang | transloco }}</span>
7252
+ <span [class]="noTruncate() ? '' : 'truncate'">{{ tab.display | syslang | transloco }}</span>
7237
7253
  <!-- Show count badge only if count is > 0 -->
7238
- @if(tab.count || 0 > 0) {
7254
+ @if((tab.count ?? 0) > 0) {
7239
7255
  <Badge class="empty:hidden ml-auto px-1 group-[[variant=secondary]]:bg-primary group-[[variant=secondary]]:text-[#fff] bg-sage-200 text-primary group-[[disabled]]:bg-gray-800 group-[[disabled]]:text-[#fff] text-2xs">{{ tab.count }}</Badge>
7240
7256
  }
7241
7257
  </div>
@@ -7244,34 +7260,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
7244
7260
  </TabsList>
7245
7261
  </Tabs>
7246
7262
 
7247
- @if (moreTabs().length > 0) {
7248
- <Menu class="absolute right-0 top-1" overflowStop>
7249
- <button variant="ghost" size="icon" class="mb-1 truncate me-1" aria-label="more tabs">
7250
- <EllipsisIcon orientation="vertical"></EllipsisIcon>
7251
- </button>
7263
+ <!-- Always mounted so the stop position is stable; hidden when all tabs fit -->
7264
+ <Menu
7265
+ overflowStop
7266
+ class="shrink-0 top-1"
7267
+ [class.invisible]="moreTabs().length === 0"
7268
+ [class.pointer-events-none]="moreTabs().length === 0"
7269
+ >
7270
+ <button variant="ghost" size="icon" class="mb-1 truncate me-1" aria-label="more tabs">
7271
+ <EllipsisIcon orientation="vertical"></EllipsisIcon>
7272
+ </button>
7252
7273
 
7253
- <MenuContent class="z-500 w-fit" position="bottom-end">
7254
- @for (tab of moreTabs(); track $index) {
7255
- <MenuItem>
7256
- <a
7257
- class="inline-block whitespace-nowrap first-letter:capitalize"
7258
- [routerLink]="[tab.routerLink]"
7259
- [queryParams]="{ n: tab.queryName, q: searchText(), t: tab.wsQueryTab, f: undefined, sort: undefined, id: undefined, page: undefined }"
7260
- [attr.aria-selected]="this.currentPath() === tab.path"
7261
- [attr.aria-label]="tab.display | syslang | transloco"
7262
- (click)="changeTab()">
7263
- @if (tab.icon) {
7264
- <i class="fa-fw {{ tab.icon }} " aria-hidden="true"></i>
7265
- }
7266
- {{ tab.display | syslang | transloco }}
7267
- </a>
7268
- </MenuItem>
7269
- }
7270
- </MenuContent>
7271
- </Menu>
7272
- } @else {
7273
- <div class="absolute right-0" overflowStop></div>
7274
- }
7274
+ <MenuContent class="z-500 w-fit" position="bottom-end">
7275
+ @for (tab of moreTabs(); track $index) {
7276
+ <MenuItem>
7277
+ <a
7278
+ class="inline-block whitespace-nowrap first-letter:capitalize"
7279
+ [routerLink]="[tab.routerLink]"
7280
+ [queryParams]="{ n: tab.queryName, q: searchText(), t: tab.wsQueryTab, f: undefined, sort: undefined, id: undefined, page: undefined }"
7281
+ [attr.aria-selected]="this.currentPath() === tab.path"
7282
+ [attr.aria-label]="tab.display | syslang | transloco"
7283
+ (click)="changeTab()">
7284
+ @if (tab.icon) {
7285
+ <i class="fa-fw {{ tab.icon }} " aria-hidden="true"></i>
7286
+ }
7287
+ {{ tab.display | syslang | transloco }}
7288
+ </a>
7289
+ </MenuItem>
7290
+ }
7291
+ </MenuContent>
7292
+ </Menu>
7275
7293
  </div>
7276
7294
  }
7277
7295
  `,
@@ -7279,7 +7297,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
7279
7297
  "[class]": "cn('block', class())"
7280
7298
  }
7281
7299
  }]
7282
- }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], showCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCount", required: false }] }], path: [{ type: i0.Input, args: [{ isSignal: true, alias: "path", required: false }] }] } });
7300
+ }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], showCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCount", required: false }] }], noTruncate: [{ type: i0.Input, args: [{ isSignal: true, alias: "noTruncate", required: false }] }], minTabWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTabWidth", required: false }] }], path: [{ type: i0.Input, args: [{ isSignal: true, alias: "path", required: false }] }] } });
7283
7301
 
7284
7302
  class NoResultComponent {
7285
7303
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: NoResultComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -7389,7 +7407,7 @@ class PreviewNavigator {
7389
7407
  [disabled]="isLast()">
7390
7408
  <chevrons-right />
7391
7409
  </button>
7392
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: ChevronLeftIconComponent, selector: "chevron-left, ChevronLeft, chevronleft", inputs: ["class"] }, { kind: "component", type: ChevronsLeftIconComponent, selector: "chevrons-left, ChevronsLeft, chevronsleft", inputs: ["class"] }, { kind: "component", type: ChevronsRightIconComponent, selector: "chevrons-right, ChevronsRight, chevronsright", inputs: ["class"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }] });
7410
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: ChevronLeftIconComponent, selector: "chevron-left, ChevronLeft, chevronleft", inputs: ["class"] }, { kind: "component", type: ChevronsLeftIconComponent, selector: "chevrons-left, ChevronsLeft, chevronsleft", inputs: ["class"] }, { kind: "component", type: ChevronsRightIconComponent, selector: "chevrons-right, ChevronsRight, chevronsright", inputs: ["class"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }] });
7393
7411
  }
7394
7412
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: PreviewNavigator, decorators: [{
7395
7413
  type: Component,
@@ -7509,7 +7527,7 @@ class SortSelectorComponent {
7509
7527
  }
7510
7528
  }
7511
7529
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SortSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7512
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SortSelectorComponent, isStandalone: true, selector: "sort-selector, sortselector, SortSelector", inputs: { result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSort: "onSort" }, providers: [provideTranslocoScope('sort-selector')], viewQueries: [{ propertyName: "dropdown", first: true, predicate: DropdownComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<menu>\n <button tabindex=\"0\" variant=\"ghost\" [attr.title]=\"'sortSelector.selectSort' | transloco\">\n <i class=\"fa-fw fa-regular fa-arrow-{{ sort()?.$isDesc ? 'down' : 'up' }}-big-small me-1\"></i>\n <span class=\"min-w-10 hidden sm:inline truncate\">{{ sort()?.display | transloco }}</span>\n </button>\n\n <MenuContent [position]=\"position()\" class=\"min-w-max\">\n @if (sortOptions().length > 0) {\n @for (option of sortOptions(); track $index) {\n <menu-item (click)=\"onSortOptionClicked(option)\" class=\"justify-between\">\n <span>{{ option.display | transloco }}</span>\n <i class=\"fa-fw fa-regular fa-arrow-{{ option.$isDesc ? 'down' : 'up' }}-big-small\"></i>\n </menu-item>\n }\n }\n </MenuContent>\n</menu>\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
7530
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SortSelectorComponent, isStandalone: true, selector: "sort-selector, sortselector, SortSelector", inputs: { result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSort: "onSort" }, providers: [provideTranslocoScope('sort-selector')], viewQueries: [{ propertyName: "dropdown", first: true, predicate: DropdownComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<menu>\n <button tabindex=\"0\" variant=\"ghost\" [attr.title]=\"'sortSelector.selectSort' | transloco\">\n <i class=\"fa-fw fa-regular fa-arrow-{{ sort()?.$isDesc ? 'down' : 'up' }}-big-small me-1\"></i>\n <span class=\"min-w-10 hidden sm:inline truncate\">{{ sort()?.display | transloco }}</span>\n </button>\n\n <MenuContent [position]=\"position()\" class=\"min-w-max\">\n @if (sortOptions().length > 0) {\n @for (option of sortOptions(); track $index) {\n <menu-item (click)=\"onSortOptionClicked(option)\" class=\"justify-between\">\n <span>{{ option.display | transloco }}</span>\n <i class=\"fa-fw fa-regular fa-arrow-{{ option.$isDesc ? 'down' : 'up' }}-big-small\"></i>\n </menu-item>\n }\n }\n </MenuContent>\n</menu>\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
7513
7531
  }
7514
7532
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SortSelectorComponent, decorators: [{
7515
7533
  type: Component,
@@ -7737,7 +7755,7 @@ class SheetNavbarComponent {
7737
7755
 
7738
7756
  <ng-content></ng-content>
7739
7757
  </menu>
7740
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "directive", type: SheetCloseDirective, selector: "[sheetClose]" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
7758
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "directive", type: SheetCloseDirective, selector: "[sheetClose]" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
7741
7759
  }
7742
7760
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SheetNavbarComponent, decorators: [{
7743
7761
  type: Component,
@@ -8073,7 +8091,7 @@ class AdvancedFiltersComponent {
8073
8091
  return res;
8074
8092
  }
8075
8093
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AdvancedFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8076
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AdvancedFiltersComponent, isStandalone: true, selector: "advanced-filters", host: { classAttribute: "contents" }, providers: [SyslangPipe, TranslocoPipe, provideTranslocoScope("drawers")], ngImport: i0, template: "<div class=\"flex h-full flex-col overflow-auto\">\n <sheet-navbar class=\"border-foreground/10 block border-b pb-2\">\n <button [attr.title]=\"'drawers.search' | transloco\" (click)=\"onSearch()\">\n {{ 'drawers.search' | transloco }}\n </button>\n </sheet-navbar>\n\n <div class=\"flex h-full grow flex-col overflow-auto p-4\">\n <section class=\"flex flex-col gap-4\" [formGroup]=\"form\">\n <!-- FIND IN -->\n <h1 class=\"text-xl font-bold\">{{ 'drawers.findInContent' | transloco }}</h1>\n <div class=\"flex items-center gap-4\" formGroupName=\"content\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInContent' | transloco }}</span>\n <select\n id=\"content-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input\n [variant]=\"inputVariant()\"\n id=\"content-value\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"getPlaceholder('content.operator')\"\n formControlName=\"value\" />\n </div>\n @if (enableFieldedSearch()) {\n <div class=\"flex items-center gap-4\" formGroupName=\"title\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInTitle' | transloco }}</span>\n <select\n id=\"title-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input id=\"title-value\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\" [placeholder]=\"getPlaceholder('title.operator')\" formControlName=\"value\" />\n </div>\n }\n\n <!-- TABS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.inScope' | transloco }}&nbsp;&quot;{{ currentTab() }}&quot;</h1>\n\n <Tabs>\n <TabsList variant=\"ghost\">\n @for (tab of tabs(); track $index) {\n <Tab class=\"w-fit\" [value]=\"tab.path\" [active]=\"tab.path === currentTab()\" (click)=\"onTabChange(tab.path)\">\n {{ tab.display | syslang | transloco }}\n </Tab>\n }\n </TabsList>\n </Tabs>\n\n <!-- FILTERS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.applyFilters' | transloco }}</h1>\n @for (filter of filters(); track $index) {\n <DropdownInput\n [suggestions]=\"suggestions()\"\n [selected]=\"getItems(filter.column)\"\n [label]=\"filter.display || filter.alias | syslang | transloco\"\n [placeholder]=\"'drawers.startTyping' | transloco\"\n [noResultLabel]=\"'drawers.noResult' | transloco\"\n (onFocus)=\"setFilterFocus($event, filter)\"\n (onKeyUp)=\"onInputTyping($event)\"\n (removeItem)=\"removeItem($event, filter)\"\n (addItem)=\"addItem($event, filter)\" />\n } @empty {\n {{ 'drawers.noFilters' | transloco }}\n }\n </section>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: DropdownInputComponent, selector: "dropdown-input, DropdownInput", inputs: ["label", "placeholder", "noResultLabel", "suggestions", "selected"], outputs: ["onFocus", "onKeyUp", "removeItem", "addItem"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "component", type: SheetNavbarComponent, selector: "SheetNavbar, sheetnavbar, sheet-navbar" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
8094
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AdvancedFiltersComponent, isStandalone: true, selector: "advanced-filters", host: { classAttribute: "contents" }, providers: [SyslangPipe, TranslocoPipe, provideTranslocoScope("drawers")], ngImport: i0, template: "<div class=\"flex h-full flex-col overflow-auto\">\n <sheet-navbar class=\"border-foreground/10 block border-b pb-2\">\n <button [attr.title]=\"'drawers.search' | transloco\" (click)=\"onSearch()\">\n {{ 'drawers.search' | transloco }}\n </button>\n </sheet-navbar>\n\n <div class=\"flex h-full grow flex-col overflow-auto p-4\">\n <section class=\"flex flex-col gap-4\" [formGroup]=\"form\">\n <!-- FIND IN -->\n <h1 class=\"text-xl font-bold\">{{ 'drawers.findInContent' | transloco }}</h1>\n <div class=\"flex items-center gap-4\" formGroupName=\"content\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInContent' | transloco }}</span>\n <select\n id=\"content-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input\n [variant]=\"inputVariant()\"\n id=\"content-value\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"getPlaceholder('content.operator')\"\n formControlName=\"value\" />\n </div>\n @if (enableFieldedSearch()) {\n <div class=\"flex items-center gap-4\" formGroupName=\"title\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInTitle' | transloco }}</span>\n <select\n id=\"title-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input id=\"title-value\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\" [placeholder]=\"getPlaceholder('title.operator')\" formControlName=\"value\" />\n </div>\n }\n\n <!-- TABS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.inScope' | transloco }}&nbsp;&quot;{{ currentTab() }}&quot;</h1>\n\n <Tabs>\n <TabsList variant=\"ghost\">\n @for (tab of tabs(); track $index) {\n <Tab class=\"w-fit\" [value]=\"tab.path\" [active]=\"tab.path === currentTab()\" (click)=\"onTabChange(tab.path)\">\n {{ tab.display | syslang | transloco }}\n </Tab>\n }\n </TabsList>\n </Tabs>\n\n <!-- FILTERS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.applyFilters' | transloco }}</h1>\n @for (filter of filters(); track $index) {\n <DropdownInput\n [suggestions]=\"suggestions()\"\n [selected]=\"getItems(filter.column)\"\n [label]=\"filter.display || filter.alias | syslang | transloco\"\n [placeholder]=\"'drawers.startTyping' | transloco\"\n [noResultLabel]=\"'drawers.noResult' | transloco\"\n (onFocus)=\"setFilterFocus($event, filter)\"\n (onKeyUp)=\"onInputTyping($event)\"\n (removeItem)=\"removeItem($event, filter)\"\n (addItem)=\"addItem($event, filter)\" />\n } @empty {\n {{ 'drawers.noFilters' | transloco }}\n }\n </section>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: DropdownInputComponent, selector: "dropdown-input, DropdownInput", inputs: ["label", "placeholder", "noResultLabel", "suggestions", "selected"], outputs: ["onFocus", "onKeyUp", "removeItem", "addItem"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "noTruncate", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "component", type: SheetNavbarComponent, selector: "SheetNavbar, sheetnavbar, sheet-navbar" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
8077
8095
  }
8078
8096
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AdvancedFiltersComponent, decorators: [{
8079
8097
  type: Component,
@@ -8093,6 +8111,291 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
8093
8111
  }, template: "<div class=\"flex h-full flex-col overflow-auto\">\n <sheet-navbar class=\"border-foreground/10 block border-b pb-2\">\n <button [attr.title]=\"'drawers.search' | transloco\" (click)=\"onSearch()\">\n {{ 'drawers.search' | transloco }}\n </button>\n </sheet-navbar>\n\n <div class=\"flex h-full grow flex-col overflow-auto p-4\">\n <section class=\"flex flex-col gap-4\" [formGroup]=\"form\">\n <!-- FIND IN -->\n <h1 class=\"text-xl font-bold\">{{ 'drawers.findInContent' | transloco }}</h1>\n <div class=\"flex items-center gap-4\" formGroupName=\"content\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInContent' | transloco }}</span>\n <select\n id=\"content-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input\n [variant]=\"inputVariant()\"\n id=\"content-value\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"getPlaceholder('content.operator')\"\n formControlName=\"value\" />\n </div>\n @if (enableFieldedSearch()) {\n <div class=\"flex items-center gap-4\" formGroupName=\"title\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInTitle' | transloco }}</span>\n <select\n id=\"title-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input id=\"title-value\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\" [placeholder]=\"getPlaceholder('title.operator')\" formControlName=\"value\" />\n </div>\n }\n\n <!-- TABS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.inScope' | transloco }}&nbsp;&quot;{{ currentTab() }}&quot;</h1>\n\n <Tabs>\n <TabsList variant=\"ghost\">\n @for (tab of tabs(); track $index) {\n <Tab class=\"w-fit\" [value]=\"tab.path\" [active]=\"tab.path === currentTab()\" (click)=\"onTabChange(tab.path)\">\n {{ tab.display | syslang | transloco }}\n </Tab>\n }\n </TabsList>\n </Tabs>\n\n <!-- FILTERS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.applyFilters' | transloco }}</h1>\n @for (filter of filters(); track $index) {\n <DropdownInput\n [suggestions]=\"suggestions()\"\n [selected]=\"getItems(filter.column)\"\n [label]=\"filter.display || filter.alias | syslang | transloco\"\n [placeholder]=\"'drawers.startTyping' | transloco\"\n [noResultLabel]=\"'drawers.noResult' | transloco\"\n (onFocus)=\"setFilterFocus($event, filter)\"\n (onKeyUp)=\"onInputTyping($event)\"\n (removeItem)=\"removeItem($event, filter)\"\n (addItem)=\"addItem($event, filter)\" />\n } @empty {\n {{ 'drawers.noFilters' | transloco }}\n }\n </section>\n </div>\n</div>\n" }]
8094
8112
  }], ctorParameters: () => [] });
8095
8113
 
8114
+ class AggregationDateCustomRangeComponent {
8115
+ el = inject(ElementRef);
8116
+ lang = input("en", ...(ngDevMode ? [{ debugName: "lang" }] : []));
8117
+ min = input(undefined, ...(ngDevMode ? [{ debugName: "min" }] : []));
8118
+ max = input(undefined, ...(ngDevMode ? [{ debugName: "max" }] : []));
8119
+ datepicker = viewChild(DateRangePickerDirective, ...(ngDevMode ? [{ debugName: "datepicker" }] : []));
8120
+ dateSelected = output();
8121
+ constructor(destroyRef) {
8122
+ afterNextRender(() => {
8123
+ const dmin = this.min() ? new Date(this.min()) : undefined;
8124
+ const dmax = this.max() ? new Date(this.max()) : undefined;
8125
+ if (dmin && dmax)
8126
+ this.datepicker()?.setDates(dmin, dmax);
8127
+ const onChangeDate = () => this.dateSelected.emit();
8128
+ this.el.nativeElement.addEventListener('changeDate', onChangeDate);
8129
+ destroyRef.onDestroy(() => this.el.nativeElement.removeEventListener('changeDate', onChangeDate));
8130
+ });
8131
+ }
8132
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateCustomRangeComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
8133
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.18", type: AggregationDateCustomRangeComponent, isStandalone: true, selector: "aggregation-date-custom-range", inputs: { lang: { classPropertyName: "lang", publicName: "lang", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateSelected: "dateSelected" }, viewQueries: [{ propertyName: "datepicker", first: true, predicate: DateRangePickerDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
8134
+ <div
8135
+ class="@container flex grow gap-1 p-1"
8136
+ daterangepicker
8137
+ [datepicker-language]="lang()"
8138
+ [datepicker-min]="min()"
8139
+ [datepicker-max]="max()">
8140
+ <div class="flex gap-1">
8141
+ <label for="datepicker-range-start" class="min-w-10">{{
8142
+ "from" | transloco
8143
+ }}</label>
8144
+ <input
8145
+ id="datepicker-range-start"
8146
+ name="start"
8147
+ type="text"
8148
+ class="h-8 min-w-[13ch]" />
8149
+ </div>
8150
+ <div class="flex gap-1">
8151
+ <label for="datepicker-range-end" class="min-w-10 text-right">{{
8152
+ "to" | transloco
8153
+ }}</label>
8154
+ <input
8155
+ id="datepicker-range-end"
8156
+ name="end"
8157
+ type="text"
8158
+ class="h-8 min-w-[13ch]" />
8159
+ </div>
8160
+ </div>
8161
+ `, isInline: true, dependencies: [{ 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", "datepicker-container"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8162
+ }
8163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateCustomRangeComponent, decorators: [{
8164
+ type: Component,
8165
+ args: [{
8166
+ selector: "aggregation-date-custom-range",
8167
+ standalone: true,
8168
+ changeDetection: ChangeDetectionStrategy.OnPush,
8169
+ imports: [TranslocoPipe, DateRangePickerDirective, InputComponent],
8170
+ template: `
8171
+ <div
8172
+ class="@container flex grow gap-1 p-1"
8173
+ daterangepicker
8174
+ [datepicker-language]="lang()"
8175
+ [datepicker-min]="min()"
8176
+ [datepicker-max]="max()">
8177
+ <div class="flex gap-1">
8178
+ <label for="datepicker-range-start" class="min-w-10">{{
8179
+ "from" | transloco
8180
+ }}</label>
8181
+ <input
8182
+ id="datepicker-range-start"
8183
+ name="start"
8184
+ type="text"
8185
+ class="h-8 min-w-[13ch]" />
8186
+ </div>
8187
+ <div class="flex gap-1">
8188
+ <label for="datepicker-range-end" class="min-w-10 text-right">{{
8189
+ "to" | transloco
8190
+ }}</label>
8191
+ <input
8192
+ id="datepicker-range-end"
8193
+ name="end"
8194
+ type="text"
8195
+ class="h-8 min-w-[13ch]" />
8196
+ </div>
8197
+ </div>
8198
+ `
8199
+ }]
8200
+ }], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { lang: [{ type: i0.Input, args: [{ isSignal: true, alias: "lang", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], datepicker: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DateRangePickerDirective), { isSignal: true }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }] } });
8201
+
8202
+ class AggregationDateDualPickersComponent {
8203
+ el = inject(ElementRef);
8204
+ lang = input("en", ...(ngDevMode ? [{ debugName: "lang" }] : []));
8205
+ min = input(undefined, ...(ngDevMode ? [{ debugName: "min" }] : []));
8206
+ max = input(undefined, ...(ngDevMode ? [{ debugName: "max" }] : []));
8207
+ datepickerStart = viewChild('datepickerStart', ...(ngDevMode ? [{ debugName: "datepickerStart" }] : []));
8208
+ datepickerEnd = viewChild('datepickerEnd', ...(ngDevMode ? [{ debugName: "datepickerEnd" }] : []));
8209
+ dateSelected = output();
8210
+ constructor(destroyRef) {
8211
+ afterNextRender(() => {
8212
+ const dmin = this.min() ? new Date(this.min()) : undefined;
8213
+ const dmax = this.max() ? new Date(this.max()) : undefined;
8214
+ if (dmin)
8215
+ this.datepickerStart()?.setDate(dmin);
8216
+ if (dmax)
8217
+ this.datepickerEnd()?.setDate(dmax);
8218
+ const onChangeDate = () => this.dateSelected.emit();
8219
+ this.el.nativeElement.addEventListener('changeDate', onChangeDate);
8220
+ destroyRef.onDestroy(() => this.el.nativeElement.removeEventListener('changeDate', onChangeDate));
8221
+ });
8222
+ }
8223
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateDualPickersComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
8224
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.18", type: AggregationDateDualPickersComponent, isStandalone: true, selector: "aggregation-date-dual-pickers", inputs: { lang: { classPropertyName: "lang", publicName: "lang", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateSelected: "dateSelected" }, viewQueries: [{ propertyName: "datepickerStart", first: true, predicate: ["datepickerStart"], descendants: true, isSignal: true }, { propertyName: "datepickerEnd", first: true, predicate: ["datepickerEnd"], descendants: true, isSignal: true }], ngImport: i0, template: `
8225
+ <div class="flex">
8226
+ <div class="flex flex-col gap-1">
8227
+ <span class="m-auto font-bold">{{ 'from' | transloco }}</span>
8228
+ <div
8229
+ datepicker #datepickerStart="datepicker"
8230
+ [datepicker-min]="min()"
8231
+ [datepicker-max]="max()"
8232
+ [datepicker-language]="lang()"></div>
8233
+ </div>
8234
+ <div class="flex flex-col gap-1">
8235
+ <span class="m-auto font-bold">{{ 'to' | transloco }}</span>
8236
+ <div
8237
+ datepicker #datepickerEnd="datepicker"
8238
+ [datepicker-min]="min()"
8239
+ [datepicker-max]="max()"
8240
+ [datepicker-language]="lang()"></div>
8241
+ </div>
8242
+ </div>
8243
+ `, isInline: true, dependencies: [{ kind: "directive", type: DatepickerDirective, selector: "[datepicker]", inputs: ["datepicker-title", "datepicker-autohide", "datepicker-clear", "datepicker-today", "datepicker-buttons", "datepicker-today-highlight", "datepicker-language", "datepicker-format", "datepicker-max", "datepicker-min"], exportAs: ["datepicker"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8244
+ }
8245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateDualPickersComponent, decorators: [{
8246
+ type: Component,
8247
+ args: [{
8248
+ selector: "aggregation-date-dual-pickers",
8249
+ standalone: true,
8250
+ changeDetection: ChangeDetectionStrategy.OnPush,
8251
+ imports: [TranslocoPipe, DatepickerDirective],
8252
+ template: `
8253
+ <div class="flex">
8254
+ <div class="flex flex-col gap-1">
8255
+ <span class="m-auto font-bold">{{ 'from' | transloco }}</span>
8256
+ <div
8257
+ datepicker #datepickerStart="datepicker"
8258
+ [datepicker-min]="min()"
8259
+ [datepicker-max]="max()"
8260
+ [datepicker-language]="lang()"></div>
8261
+ </div>
8262
+ <div class="flex flex-col gap-1">
8263
+ <span class="m-auto font-bold">{{ 'to' | transloco }}</span>
8264
+ <div
8265
+ datepicker #datepickerEnd="datepicker"
8266
+ [datepicker-min]="min()"
8267
+ [datepicker-max]="max()"
8268
+ [datepicker-language]="lang()"></div>
8269
+ </div>
8270
+ </div>
8271
+ `
8272
+ }]
8273
+ }], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { lang: [{ type: i0.Input, args: [{ isSignal: true, alias: "lang", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], datepickerStart: [{ type: i0.ViewChild, args: ['datepickerStart', { isSignal: true }] }], datepickerEnd: [{ type: i0.ViewChild, args: ['datepickerEnd', { isSignal: true }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }] } });
8274
+
8275
+ class AggregationDateRangeDialogComponent {
8276
+ cn = cn;
8277
+ hasSelection = signal(false, ...(ngDevMode ? [{ debugName: "hasSelection" }] : []));
8278
+ dialog = viewChild(DialogComponent, ...(ngDevMode ? [{ debugName: "dialog" }] : []));
8279
+ customRange = viewChild('customRange', ...(ngDevMode ? [{ debugName: "customRange" }] : []));
8280
+ dualPickers = viewChild('dualPickers', ...(ngDevMode ? [{ debugName: "dualPickers" }] : []));
8281
+ min = input(undefined, ...(ngDevMode ? [{ debugName: "min" }] : []));
8282
+ max = input(undefined, ...(ngDevMode ? [{ debugName: "max" }] : []));
8283
+ lang = input("en", ...(ngDevMode ? [{ debugName: "lang" }] : []));
8284
+ /**
8285
+ * Whether to use the date range picker or two separate date pickers for start and end dates.
8286
+ * The date range picker is used when the user can select a range of dates, while the separate date pickers are used when the user can only select a single
8287
+ * date (e.g., for "last week" or "last month" options).
8288
+ *
8289
+ * @defaultValue false
8290
+ */
8291
+ useDateRange = input(false, ...(ngDevMode ? [{ debugName: "useDateRange", transform: Boolean }] : [{ transform: Boolean }]));
8292
+ rangeSelected = output();
8293
+ open() {
8294
+ this.hasSelection.set(false);
8295
+ this.dialog()?.open();
8296
+ }
8297
+ confirm() {
8298
+ const customRange = this.customRange();
8299
+ const dualPickers = this.dualPickers();
8300
+ if (customRange) {
8301
+ const [start, end] = customRange.datepicker()?.getDates() ?? [];
8302
+ if (!start && !end)
8303
+ return;
8304
+ this.rangeSelected.emit({
8305
+ from: start?.toISOString() ?? null,
8306
+ to: end?.toISOString() ?? null
8307
+ });
8308
+ }
8309
+ if (dualPickers) {
8310
+ const start = dualPickers.datepickerStart()?.getDate();
8311
+ const end = dualPickers.datepickerEnd()?.getDate();
8312
+ if (!start && !end)
8313
+ return;
8314
+ this.rangeSelected.emit({
8315
+ from: start?.toISOString() ?? null,
8316
+ to: end?.toISOString() ?? null
8317
+ });
8318
+ }
8319
+ this.dialog()?.close();
8320
+ }
8321
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateRangeDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8322
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationDateRangeDialogComponent, isStandalone: true, selector: "aggregation-date-range-dialog", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, lang: { classPropertyName: "lang", publicName: "lang", isSignal: true, isRequired: false, transformFunction: null }, useDateRange: { classPropertyName: "useDateRange", publicName: "useDateRange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeSelected: "rangeSelected" }, viewQueries: [{ propertyName: "dialog", first: true, predicate: DialogComponent, descendants: true, isSignal: true }, { propertyName: "customRange", first: true, predicate: ["customRange"], descendants: true, isSignal: true }, { propertyName: "dualPickers", first: true, predicate: ["dualPickers"], descendants: true, isSignal: true }], ngImport: i0, template: `
8323
+ <div dialog #dialog="dialog">
8324
+ <DialogContent [class]="cn(!useDateRange() && 'max-w-fit!')">
8325
+ <DialogHeader>
8326
+ <DialogTitle>{{ 'filters.customRange' | transloco }}</DialogTitle>
8327
+ </DialogHeader>
8328
+
8329
+ @if(!useDateRange()) {
8330
+ <aggregation-date-dual-pickers #dualPickers
8331
+ [min]="min()"
8332
+ [max]="max()"
8333
+ [lang]="lang()"
8334
+ (dateSelected)="hasSelection.set(true)" />
8335
+ } @else {
8336
+ <aggregation-date-custom-range #customRange
8337
+ [min]="min()"
8338
+ [max]="max()"
8339
+ [lang]="lang()"
8340
+ (dateSelected)="hasSelection.set(true)" />
8341
+ }
8342
+
8343
+ <DialogFooter>
8344
+ <button variant="outline" (click)="dialog.cancel()">{{ 'cancel' | transloco }}</button>
8345
+ <button [disabled]="!hasSelection()" (click)="confirm()">{{ 'filters.validate' | transloco }}</button>
8346
+ </DialogFooter>
8347
+ </DialogContent>
8348
+ </div>
8349
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "component", type: AggregationDateCustomRangeComponent, selector: "aggregation-date-custom-range", inputs: ["lang", "min", "max"], outputs: ["dateSelected"] }, { kind: "component", type: AggregationDateDualPickersComponent, selector: "aggregation-date-dual-pickers", inputs: ["lang", "min", "max"], outputs: ["dateSelected"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8350
+ }
8351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateRangeDialogComponent, decorators: [{
8352
+ type: Component,
8353
+ args: [{
8354
+ selector: "aggregation-date-range-dialog",
8355
+ standalone: true,
8356
+ changeDetection: ChangeDetectionStrategy.OnPush,
8357
+ imports: [
8358
+ TranslocoPipe,
8359
+ ButtonComponent,
8360
+ DialogComponent,
8361
+ DialogContentComponent,
8362
+ DialogHeaderComponent,
8363
+ DialogTitleComponent,
8364
+ DialogFooterComponent,
8365
+ AggregationDateCustomRangeComponent,
8366
+ AggregationDateDualPickersComponent
8367
+ ],
8368
+ template: `
8369
+ <div dialog #dialog="dialog">
8370
+ <DialogContent [class]="cn(!useDateRange() && 'max-w-fit!')">
8371
+ <DialogHeader>
8372
+ <DialogTitle>{{ 'filters.customRange' | transloco }}</DialogTitle>
8373
+ </DialogHeader>
8374
+
8375
+ @if(!useDateRange()) {
8376
+ <aggregation-date-dual-pickers #dualPickers
8377
+ [min]="min()"
8378
+ [max]="max()"
8379
+ [lang]="lang()"
8380
+ (dateSelected)="hasSelection.set(true)" />
8381
+ } @else {
8382
+ <aggregation-date-custom-range #customRange
8383
+ [min]="min()"
8384
+ [max]="max()"
8385
+ [lang]="lang()"
8386
+ (dateSelected)="hasSelection.set(true)" />
8387
+ }
8388
+
8389
+ <DialogFooter>
8390
+ <button variant="outline" (click)="dialog.cancel()">{{ 'cancel' | transloco }}</button>
8391
+ <button [disabled]="!hasSelection()" (click)="confirm()">{{ 'filters.validate' | transloco }}</button>
8392
+ </DialogFooter>
8393
+ </DialogContent>
8394
+ </div>
8395
+ `
8396
+ }]
8397
+ }], propDecorators: { dialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DialogComponent), { isSignal: true }] }], customRange: [{ type: i0.ViewChild, args: ['customRange', { isSignal: true }] }], dualPickers: [{ type: i0.ViewChild, args: ['dualPickers', { isSignal: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], lang: [{ type: i0.Input, args: [{ isSignal: true, alias: "lang", required: false }] }], useDateRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "useDateRange", required: false }] }], rangeSelected: [{ type: i0.Output, args: ["rangeSelected"] }] } });
8398
+
8096
8399
  /**
8097
8400
  * Injection token that indicates whether custom date ranges are allowed.
8098
8401
  *
@@ -8192,6 +8495,8 @@ class AggregationListComponent {
8192
8495
  name = input.required(...(ngDevMode ? [{ debugName: "name" }] : []));
8193
8496
  column = input.required(...(ngDevMode ? [{ debugName: "column" }] : []));
8194
8497
  onSelect = output();
8498
+ onApply = output();
8499
+ onClear = output();
8195
8500
  /**
8196
8501
  * Determines whether the aggregation component can be collapsed or expanded.
8197
8502
  * When true, the component will display collapse/expand controls allowing users
@@ -8363,6 +8668,7 @@ class AggregationListComponent {
8363
8668
  this.isAllSelected.set(false);
8364
8669
  }
8365
8670
  this.onSelect.emit([]);
8671
+ this.onClear.emit();
8366
8672
  }
8367
8673
  /**
8368
8674
  * Select all filters for the aggregation column.
@@ -8434,6 +8740,7 @@ class AggregationListComponent {
8434
8740
  }
8435
8741
  this.searchText.set("");
8436
8742
  this.selection.set(false);
8743
+ this.onApply.emit();
8437
8744
  }
8438
8745
  loadMore() {
8439
8746
  const q = this.queryParamsStore.getQuery();
@@ -8549,7 +8856,7 @@ class AggregationListComponent {
8549
8856
  this.isCollapsed.set(e.newState === "closed");
8550
8857
  }
8551
8858
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8552
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationListComponent, isStandalone: true, selector: "AggregationList, aggregation-list, aggregationlist", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", searchText: "searchTextChange" }, host: { properties: { "class": "cn(\"block h-[inherit] max-h-[inherit]\",class())" } }, viewQueries: [{ propertyName: "scrollElement", first: true, predicate: ["scrollElement"], descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (aggregation()?.isTree) {\r\n <div class=\"p-2 text-sm text-red-500\">\r\n <i class=\"fa-fw fas fa-triangle-exclamation mr-1\"></i>\r\n The aggregation component no longer supports tree aggregations. Please use\r\n the &lt;AggregationTree /&gt; component instead.\r\n </div>\r\n}\r\n<details\r\n [attr.open]=\"expanded()\"\r\n [attr.name]=\"id()\"\r\n class=\"group space-y-2\"\r\n (toggle)=\"onToggle($event)\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\r\n [class.text-muted-foreground]=\"isEmpty()\"\r\n class=\"m-0 mt-1 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow truncate\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (showFiltersCount() && filtersCount() > 0) {\r\n <!-- count -->\r\n <Badge size=\"xs\" class=\"ml-1 pb-0.5\">\r\n {{ filtersCount() }}\r\n </Badge>\r\n }\r\n <!-- apply filter block -->\r\n @if (!isCollapsed()) {\r\n <ButtonGroup>\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.clearFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n @if (selection()) {\r\n <button\r\n variant=\"primary\"\r\n size=\"xs\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); apply()\"\r\n class=\"h-4 px-1\">\r\n <FilterIcon class=\"size-4\" />\r\n {{ \"filters.apply\" | transloco }}\r\n </button>\r\n }\r\n\r\n <!-- select / unselect all -->\r\n @if (isAllSelected()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.unselectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.unselectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); unselectAll()\">\r\n <i class=\"fa-fw far fa-check-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.unselectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n } @else {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.selectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.selectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); selectAll()\">\r\n <i class=\"fa-fw far fa-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.selectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n </ButtonGroup>\r\n }\r\n\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n @if (aggregation()?.searchable && items().length) {\r\n <InputGroup class=\"group/item mt-1\">\r\n <input\r\n #searchInput\r\n input-group\r\n id=\"aggregation-input-{{ column() }}\"\r\n type=\"text\"\r\n [attr.placeholder]=\"'search' | transloco\"\r\n [(ngModel)]=\"searchText\"\r\n class=\"mt-1\" />\r\n <InputGroupAddon>\r\n <SearchIcon\r\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\r\n </InputGroupAddon>\r\n </InputGroup>\r\n }\r\n\r\n <div\r\n #scrollElement\r\n class=\"scrollbar-thin max-h-[calc(var(--height,100%)-100px)] w-full overflow-auto\">\r\n <div\r\n class=\"relative w-full\"\r\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\r\n role=\"list\"\r\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\r\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\r\n @let item = items()[vItem.index];\r\n <div\r\n class=\"absolute w-full\"\r\n [style.transform]=\"'translateY(' + vItem.start + 'px)'\"\r\n role=\"listitem\">\r\n <AggregationListItem\r\n [node]=\"item\"\r\n [field]=\"aggregation()?.column\"\r\n (onSelect)=\"select()\"\r\n (onFilter)=\"apply()\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n @if (aggregation()?.$hasMore && this.searchedItems().length === 0) {\r\n <button\r\n variant=\"link\"\r\n class=\"mt-1 flex w-full justify-center\"\r\n [attr.aria-label]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore()\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n</details>\r\n", styles: ["AggregationItem:has(+AggregationItem){margin-bottom:var(--agg-item-gap, 0)}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: AggregationListItemComponent, selector: "aggregation-list-item, AggregationListItem, aggregationlistitem", inputs: ["node", "field"], outputs: ["onSelect", "onOpen", "onFilter"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "directive", type: ButtonGroup, selector: "button-group, ButtonGroup", inputs: ["class", "orientation"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "component", type: SearchIcon, selector: "SearchIcon", inputs: ["class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
8859
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationListComponent, isStandalone: true, selector: "AggregationList, aggregation-list, aggregationlist", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", onApply: "onApply", onClear: "onClear", searchText: "searchTextChange" }, host: { properties: { "class": "cn(\"block h-[inherit] max-h-[inherit]\",class())" } }, viewQueries: [{ propertyName: "scrollElement", first: true, predicate: ["scrollElement"], descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (aggregation()?.isTree) {\r\n <div class=\"p-2 text-sm text-red-500\">\r\n <i class=\"fa-fw fas fa-triangle-exclamation mr-1\"></i>\r\n The aggregation component no longer supports tree aggregations. Please use\r\n the &lt;AggregationTree /&gt; component instead.\r\n </div>\r\n}\r\n<details\r\n [attr.open]=\"expanded()\"\r\n [attr.name]=\"id()\"\r\n class=\"group space-y-2\"\r\n (toggle)=\"onToggle($event)\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\r\n [class.text-muted-foreground]=\"isEmpty()\"\r\n class=\"m-0 mt-1 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow truncate\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (showFiltersCount() && filtersCount() > 0) {\r\n <!-- count -->\r\n <Badge size=\"xs\" class=\"ml-1 pb-0.5\">\r\n {{ filtersCount() }}\r\n </Badge>\r\n }\r\n <!-- apply filter block -->\r\n @if (!isCollapsed()) {\r\n <ButtonGroup>\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.clearFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n @if (selection()) {\r\n <button\r\n variant=\"primary\"\r\n size=\"xs\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); apply()\"\r\n class=\"h-4 px-1\">\r\n <FilterIcon class=\"size-4\" />\r\n {{ \"filters.apply\" | transloco }}\r\n </button>\r\n }\r\n\r\n <!-- select / unselect all -->\r\n @if (isAllSelected()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.unselectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.unselectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); unselectAll()\">\r\n <i class=\"fa-fw far fa-check-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.unselectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n } @else {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.selectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.selectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); selectAll()\">\r\n <i class=\"fa-fw far fa-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.selectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n </ButtonGroup>\r\n }\r\n\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n @if (aggregation()?.searchable && items().length) {\r\n <InputGroup class=\"group/item mt-1\">\r\n <input\r\n #searchInput\r\n input-group\r\n id=\"aggregation-input-{{ column() }}\"\r\n type=\"text\"\r\n [attr.placeholder]=\"'search' | transloco\"\r\n [(ngModel)]=\"searchText\"\r\n class=\"mt-1\" />\r\n <InputGroupAddon>\r\n <SearchIcon\r\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\r\n </InputGroupAddon>\r\n </InputGroup>\r\n }\r\n\r\n <div\r\n #scrollElement\r\n class=\"scrollbar-thin max-h-[calc(var(--height,100%)-100px)] w-full overflow-auto\">\r\n <div\r\n class=\"relative w-full\"\r\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\r\n role=\"list\"\r\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\r\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\r\n @let item = items()[vItem.index];\r\n <div\r\n class=\"absolute w-full\"\r\n [style.transform]=\"'translateY(' + vItem.start + 'px)'\"\r\n role=\"listitem\">\r\n <AggregationListItem\r\n [node]=\"item\"\r\n [field]=\"aggregation()?.column\"\r\n (onSelect)=\"select()\"\r\n (onFilter)=\"apply()\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n @if (aggregation()?.$hasMore && this.searchedItems().length === 0) {\r\n <button\r\n variant=\"link\"\r\n class=\"mt-1 flex w-full justify-center\"\r\n [attr.aria-label]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore()\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n</details>\r\n", styles: ["AggregationItem:has(+AggregationItem){margin-bottom:var(--agg-item-gap, 0)}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: AggregationListItemComponent, selector: "aggregation-list-item, AggregationListItem, aggregationlistitem", inputs: ["node", "field"], outputs: ["onSelect", "onOpen", "onFilter"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "directive", type: ButtonGroup, selector: "button-group, ButtonGroup", inputs: ["class", "orientation"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "component", type: SearchIcon, selector: "SearchIcon", inputs: ["class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
8553
8860
  }
8554
8861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationListComponent, decorators: [{
8555
8862
  type: Component,
@@ -8572,11 +8879,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
8572
8879
  ], standalone: true, host: {
8573
8880
  "[class]": 'cn("block h-[inherit] max-h-[inherit]",class())'
8574
8881
  }, template: "@if (aggregation()?.isTree) {\r\n <div class=\"p-2 text-sm text-red-500\">\r\n <i class=\"fa-fw fas fa-triangle-exclamation mr-1\"></i>\r\n The aggregation component no longer supports tree aggregations. Please use\r\n the &lt;AggregationTree /&gt; component instead.\r\n </div>\r\n}\r\n<details\r\n [attr.open]=\"expanded()\"\r\n [attr.name]=\"id()\"\r\n class=\"group space-y-2\"\r\n (toggle)=\"onToggle($event)\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\r\n [class.text-muted-foreground]=\"isEmpty()\"\r\n class=\"m-0 mt-1 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow truncate\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (showFiltersCount() && filtersCount() > 0) {\r\n <!-- count -->\r\n <Badge size=\"xs\" class=\"ml-1 pb-0.5\">\r\n {{ filtersCount() }}\r\n </Badge>\r\n }\r\n <!-- apply filter block -->\r\n @if (!isCollapsed()) {\r\n <ButtonGroup>\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.clearFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n @if (selection()) {\r\n <button\r\n variant=\"primary\"\r\n size=\"xs\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); apply()\"\r\n class=\"h-4 px-1\">\r\n <FilterIcon class=\"size-4\" />\r\n {{ \"filters.apply\" | transloco }}\r\n </button>\r\n }\r\n\r\n <!-- select / unselect all -->\r\n @if (isAllSelected()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.unselectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.unselectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); unselectAll()\">\r\n <i class=\"fa-fw far fa-check-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.unselectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n } @else {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.selectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.selectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); selectAll()\">\r\n <i class=\"fa-fw far fa-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.selectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n </ButtonGroup>\r\n }\r\n\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n @if (aggregation()?.searchable && items().length) {\r\n <InputGroup class=\"group/item mt-1\">\r\n <input\r\n #searchInput\r\n input-group\r\n id=\"aggregation-input-{{ column() }}\"\r\n type=\"text\"\r\n [attr.placeholder]=\"'search' | transloco\"\r\n [(ngModel)]=\"searchText\"\r\n class=\"mt-1\" />\r\n <InputGroupAddon>\r\n <SearchIcon\r\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\r\n </InputGroupAddon>\r\n </InputGroup>\r\n }\r\n\r\n <div\r\n #scrollElement\r\n class=\"scrollbar-thin max-h-[calc(var(--height,100%)-100px)] w-full overflow-auto\">\r\n <div\r\n class=\"relative w-full\"\r\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\r\n role=\"list\"\r\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\r\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\r\n @let item = items()[vItem.index];\r\n <div\r\n class=\"absolute w-full\"\r\n [style.transform]=\"'translateY(' + vItem.start + 'px)'\"\r\n role=\"listitem\">\r\n <AggregationListItem\r\n [node]=\"item\"\r\n [field]=\"aggregation()?.column\"\r\n (onSelect)=\"select()\"\r\n (onFilter)=\"apply()\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n @if (aggregation()?.$hasMore && this.searchedItems().length === 0) {\r\n <button\r\n variant=\"link\"\r\n class=\"mt-1 flex w-full justify-center\"\r\n [attr.aria-label]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore()\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n</details>\r\n", styles: ["AggregationItem:has(+AggregationItem){margin-bottom:var(--agg-item-gap, 0)}\n"] }]
8575
- }], ctorParameters: () => [], propDecorators: { scrollElement: [{ type: i0.ViewChild, args: ["scrollElement", { isSignal: true }] }], searchInput: [{ type: i0.ViewChild, args: ["searchInput", { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }] } });
8882
+ }], ctorParameters: () => [], propDecorators: { scrollElement: [{ type: i0.ViewChild, args: ["scrollElement", { isSignal: true }] }], searchInput: [{ type: i0.ViewChild, args: ["searchInput", { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], onApply: [{ type: i0.Output, args: ["onApply"] }], onClear: [{ type: i0.Output, args: ["onClear"] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }] } });
8576
8883
 
8577
8884
  class AggregationDateComponent extends AggregationListComponent {
8578
8885
  destroyRef;
8579
- datepicker = viewChild(DateRangePickerDirective, ...(ngDevMode ? [{ debugName: "datepicker" }] : []));
8886
+ dateRangeDialog = viewChild(AggregationDateRangeDialogComponent, ...(ngDevMode ? [{ debugName: "dateRangeDialog" }] : []));
8580
8887
  title = input({ label: "Date", icon: "far fa-calendar-day" }, ...(ngDevMode ? [{ debugName: "title" }] : []));
8581
8888
  displayEmptyDistributionIntervals = input(false, ...(ngDevMode ? [{ debugName: "displayEmptyDistributionIntervals" }] : []));
8582
8889
  allowCustomRange = inject(FILTER_DATE_ALLOW_CUSTOM_RANGE);
@@ -8592,16 +8899,20 @@ class AggregationDateComponent extends AggregationListComponent {
8592
8899
  today = new Date();
8593
8900
  lang = signal(this.transloco.getActiveLang(), ...(ngDevMode ? [{ debugName: "lang" }] : []));
8594
8901
  validSelection = signal(false, ...(ngDevMode ? [{ debugName: "validSelection" }] : []));
8902
+ formValue = toSignal(this.form.valueChanges, { initialValue: this.form.value });
8903
+ customRangeLabel = computed(() => {
8904
+ const { from, to } = this.formValue().customRange ?? {};
8905
+ if (!from && !to)
8906
+ return null;
8907
+ const locale = this.lang();
8908
+ const fmt = (iso) => iso ? new Date(iso).toLocaleDateString(locale) : "…";
8909
+ return `${fmt(from ?? null)} – ${fmt(to ?? null)}`;
8910
+ }, ...(ngDevMode ? [{ debugName: "customRangeLabel" }] : []));
8595
8911
  constructor(destroyRef) {
8596
8912
  super();
8597
8913
  this.destroyRef = destroyRef;
8598
8914
  this.transloco.langChanges$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((lang) => {
8599
8915
  this.lang.set(lang);
8600
- this.datepicker()?.setOptions({ language: lang });
8601
- });
8602
- const abortController = new AbortController();
8603
- addEventListener("changeDate", this.onDateChange.bind(this), {
8604
- signal: abortController.signal
8605
8916
  });
8606
8917
  // apply current date filter from queryParamsStore
8607
8918
  effect(() => {
@@ -8614,9 +8925,6 @@ class AggregationDateComponent extends AggregationListComponent {
8614
8925
  this.validSelection.set(!!changes.option &&
8615
8926
  (changes.option !== "custom-range" || changes.customRange?.from !== null || changes.customRange?.to !== null));
8616
8927
  });
8617
- destroyRef.onDestroy(() => {
8618
- abortController.abort();
8619
- });
8620
8928
  }
8621
8929
  aggregation = computed(() => {
8622
8930
  const name = this.name();
@@ -8634,6 +8942,7 @@ class AggregationDateComponent extends AggregationListComponent {
8634
8942
  const filter = this.getFormValueFilter();
8635
8943
  this.queryParamsStore.updateFilter(filter);
8636
8944
  this.selection.set(false);
8945
+ this.onApply.emit();
8637
8946
  }
8638
8947
  catch (err) {
8639
8948
  warn("Error applying date filter:", err);
@@ -8653,8 +8962,16 @@ class AggregationDateComponent extends AggregationListComponent {
8653
8962
  const agg = this.aggregation();
8654
8963
  if (agg && notify) {
8655
8964
  this.queryParamsStore.removeFilterByName(agg.name);
8965
+ this.onClear.emit();
8656
8966
  }
8657
8967
  }
8968
+ onRangeSelected(range) {
8969
+ this.form.patchValue({
8970
+ option: "custom-range",
8971
+ customRange: { from: range.from, to: range.to }
8972
+ });
8973
+ this.select();
8974
+ }
8658
8975
  updateForm(filter) {
8659
8976
  if (!filter) {
8660
8977
  this.clear(false);
@@ -8686,15 +9003,6 @@ class AggregationDateComponent extends AggregationListComponent {
8686
9003
  }
8687
9004
  };
8688
9005
  this.form.setValue(formValue);
8689
- // Update the date range picker
8690
- const datepicker = this.datepicker();
8691
- if (datepicker) {
8692
- const start = new Date(formValue.customRange.from || "");
8693
- const end = new Date(formValue.customRange.to || "");
8694
- setTimeout(() => {
8695
- datepicker.rangeDatepicker?.setDates(start, end);
8696
- }, 1000);
8697
- }
8698
9006
  }
8699
9007
  getFormValueFilter() {
8700
9008
  const value = this.form.value;
@@ -8750,44 +9058,23 @@ class AggregationDateComponent extends AggregationListComponent {
8750
9058
  }
8751
9059
  throw new Error("filters.filterInvalid");
8752
9060
  }
8753
- onDateChange() {
8754
- // Get the selected dates
8755
- const [start, end] = this.datepicker()?.getDates() || [];
8756
- // If both start and end are not selected, reset the datepicker options
8757
- if (!start && !end) {
8758
- this.datepicker()?.setOptions({
8759
- minDate: undefined,
8760
- maxDate: this.today
8761
- });
8762
- }
8763
- // Update the form with the selected dates
8764
- if (start && end) {
8765
- this.form.patchValue({
8766
- customRange: {
8767
- from: start.toISOString(),
8768
- to: end.toISOString()
8769
- }
8770
- });
8771
- }
8772
- }
8773
9061
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
8774
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationDateComponent, isStandalone: true, selector: "aggregation-date, AggregationDate, aggregationdate", 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 [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"custom range\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n #radiorange\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-custom-range\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <div\r\n class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\"\r\n daterangepicker\r\n datepicker-buttons\r\n [datepicker-language]=\"lang()\"\r\n [datepicker-min]=\"form.get('customRange.from')?.value || undefined\"\r\n [datepicker-max]=\"\r\n form.get('customRange.to')?.value ?? today.toISOString()\r\n \"\r\n (click)=\"radiorange.click()\">\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-start\" class=\"min-w-10\">{{\r\n \"from\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-start\"\r\n name=\"start\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-end\" class=\"min-w-10 text-right\">{{\r\n \"to\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-end\"\r\n name=\"end\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n", styles: [":host{display:block;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\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "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: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
9062
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationDateComponent, isStandalone: true, selector: "aggregation-date, AggregationDate, aggregationdate", 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: "dateRangeDialog", first: true, predicate: AggregationDateRangeDialogComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"open date range picker\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-range-dialog\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <label\r\n for=\"date-filter-range-dialog\"\r\n class=\"flex grow cursor-pointer items-center gap-1 p-1\"\r\n (click)=\"dateRangeDialog()?.open()\">\r\n @let rangeLabel = customRangeLabel();\r\n @if (rangeLabel) {\r\n <span class=\"w-full\">{{ rangeLabel }}</span>\r\n } @else {\r\n <span>{{ \"filters.selectDateRange\" | transloco }}</span>\r\n }\r\n </label>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n\r\n<aggregation-date-range-dialog\r\n [lang]=\"lang()\"\r\n [useDateRange]=\"false\"\r\n [min]=\"form.get('customRange.from')?.value || undefined\"\r\n [max]=\"form.get('customRange.to')?.value || undefined\"\r\n (rangeSelected)=\"onRangeSelected($event)\" />\r\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "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: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "component", type: AggregationDateRangeDialogComponent, selector: "aggregation-date-range-dialog", inputs: ["min", "max", "lang", "useDateRange"], outputs: ["rangeSelected"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
8775
9063
  }
8776
9064
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationDateComponent, decorators: [{
8777
9065
  type: Component,
8778
9066
  args: [{ selector: "aggregation-date, AggregationDate, aggregationdate", standalone: true, providers: [provideTranslocoScope("filters")], imports: [
8779
- InputComponent,
8780
9067
  ButtonComponent,
8781
9068
  ListItemComponent,
8782
9069
  ReactiveFormsModule,
8783
9070
  TranslocoPipe,
8784
9071
  SyslangPipe,
8785
- DateRangePickerDirective,
8786
- ChevronRightIcon
9072
+ ChevronRightIcon,
9073
+ AggregationDateRangeDialogComponent
8787
9074
  ], host: {
8788
9075
  class: "@container"
8789
- }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"custom range\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n #radiorange\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-custom-range\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <div\r\n class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\"\r\n daterangepicker\r\n datepicker-buttons\r\n [datepicker-language]=\"lang()\"\r\n [datepicker-min]=\"form.get('customRange.from')?.value || undefined\"\r\n [datepicker-max]=\"\r\n form.get('customRange.to')?.value ?? today.toISOString()\r\n \"\r\n (click)=\"radiorange.click()\">\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-start\" class=\"min-w-10\">{{\r\n \"from\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-start\"\r\n name=\"start\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-end\" class=\"min-w-10 text-right\">{{\r\n \"to\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-end\"\r\n name=\"end\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
8790
- }], 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 }] }] } });
9076
+ }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"open date range picker\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-range-dialog\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <label\r\n for=\"date-filter-range-dialog\"\r\n class=\"flex grow cursor-pointer items-center gap-1 p-1\"\r\n (click)=\"dateRangeDialog()?.open()\">\r\n @let rangeLabel = customRangeLabel();\r\n @if (rangeLabel) {\r\n <span class=\"w-full\">{{ rangeLabel }}</span>\r\n } @else {\r\n <span>{{ \"filters.selectDateRange\" | transloco }}</span>\r\n }\r\n </label>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n\r\n<aggregation-date-range-dialog\r\n [lang]=\"lang()\"\r\n [useDateRange]=\"false\"\r\n [min]=\"form.get('customRange.from')?.value || undefined\"\r\n [max]=\"form.get('customRange.to')?.value || undefined\"\r\n (rangeSelected)=\"onRangeSelected($event)\" />\r\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
9077
+ }], ctorParameters: () => [{ type: i0.DestroyRef }], propDecorators: { dateRangeDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationDateRangeDialogComponent), { isSignal: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], displayEmptyDistributionIntervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayEmptyDistributionIntervals", required: false }] }] } });
8791
9078
 
8792
9079
  /**
8793
9080
  * Component that allows users to select a date or a date range for filtering search results.
@@ -8796,22 +9083,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
8796
9083
  */
8797
9084
  class DateComponent extends AggregationDateComponent {
8798
9085
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DateComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
8799
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DateComponent, isStandalone: true, selector: "date-filter,DateFilter", host: { classAttribute: "@container" }, providers: [provideTranslocoScope("filters")], usesInheritance: true, ngImport: i0, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"custom range\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n #radiorange\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-custom-range\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <div\r\n class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\"\r\n daterangepicker\r\n datepicker-buttons\r\n [datepicker-language]=\"lang()\"\r\n [datepicker-min]=\"form.get('customRange.from')?.value || undefined\"\r\n [datepicker-max]=\"\r\n form.get('customRange.to')?.value ?? today.toISOString()\r\n \"\r\n (click)=\"radiorange.click()\">\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-start\" class=\"min-w-10\">{{\r\n \"from\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-start\"\r\n name=\"start\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-end\" class=\"min-w-10 text-right\">{{\r\n \"to\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-end\"\r\n name=\"end\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n", styles: [":host{display:block;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\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "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: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
9086
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DateComponent, isStandalone: true, selector: "date-filter,DateFilter", host: { classAttribute: "@container" }, providers: [provideTranslocoScope("filters")], usesInheritance: true, ngImport: i0, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"open date range picker\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-range-dialog\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <label\r\n for=\"date-filter-range-dialog\"\r\n class=\"flex grow cursor-pointer items-center gap-1 p-1\"\r\n (click)=\"dateRangeDialog()?.open()\">\r\n @let rangeLabel = customRangeLabel();\r\n @if (rangeLabel) {\r\n <span class=\"w-full\">{{ rangeLabel }}</span>\r\n } @else {\r\n <span>{{ \"filters.selectDateRange\" | transloco }}</span>\r\n }\r\n </label>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n\r\n<aggregation-date-range-dialog\r\n [lang]=\"lang()\"\r\n [useDateRange]=\"false\"\r\n [min]=\"form.get('customRange.from')?.value || undefined\"\r\n [max]=\"form.get('customRange.to')?.value || undefined\"\r\n (rangeSelected)=\"onRangeSelected($event)\" />\r\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "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: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "component", type: AggregationDateRangeDialogComponent, selector: "aggregation-date-range-dialog", inputs: ["min", "max", "lang", "useDateRange"], outputs: ["rangeSelected"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
8800
9087
  }
8801
9088
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DateComponent, decorators: [{
8802
9089
  type: Component,
8803
9090
  args: [{ selector: "date-filter,DateFilter", standalone: true, providers: [provideTranslocoScope("filters")], imports: [
8804
- InputComponent,
8805
9091
  ButtonComponent,
8806
9092
  ListItemComponent,
8807
9093
  ReactiveFormsModule,
8808
9094
  TranslocoPipe,
8809
9095
  SyslangPipe,
8810
- DateRangePickerDirective,
8811
- ChevronRightIcon
9096
+ ChevronRightIcon,
9097
+ AggregationDateRangeDialogComponent
8812
9098
  ], host: {
8813
9099
  class: "@container"
8814
- }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"custom range\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n #radiorange\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-custom-range\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <div\r\n class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\"\r\n daterangepicker\r\n datepicker-buttons\r\n [datepicker-language]=\"lang()\"\r\n [datepicker-min]=\"form.get('customRange.from')?.value || undefined\"\r\n [datepicker-max]=\"\r\n form.get('customRange.to')?.value ?? today.toISOString()\r\n \"\r\n (click)=\"radiorange.click()\">\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-start\" class=\"min-w-10\">{{\r\n \"from\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-start\"\r\n name=\"start\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n <div class=\"flex gap-1\">\r\n <label for=\"datepicker-range-end\" class=\"min-w-10 text-right\">{{\r\n \"to\" | transloco\r\n }}</label>\r\n <input\r\n id=\"datepicker-range-end\"\r\n name=\"end\"\r\n type=\"text\"\r\n class=\"h-8 min-w-[13ch]\" />\r\n </div>\r\n </div>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
9100
+ }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible()\"\r\n class=\"m-0 flex h-8 w-full items-center pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"clear()\"\r\n (keydown.enter)=\"clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.clearFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n @if (selection() && validSelection()) {\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"apply()\"\r\n (keydown.enter)=\"apply()\">\r\n <i class=\"fa-fw far fa-filter\" aria-hidden=\"true\"></i>\r\n <span class=\"sr-only\">{{ \"filters.applyFilters\" | transloco }}</span>\r\n </button>\r\n }\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n <form [formGroup]=\"form\">\r\n <ul\r\n class=\"scrollbar-thin flex max-h-[calc(var(--height,100%)-100px)] snap-y snap-start flex-col gap-1 overflow-auto pt-2\"\r\n role=\"list\">\r\n @for (option of dateOptions(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n tabindex=\"0\"\r\n (click)=\"radio.click()\"\r\n [attr.aria-label]=\"option.display | syslang | transloco\"\r\n [class]=\"\r\n cn(\r\n 'flex p-0 px-2 leading-7',\r\n form.get('option')?.value === option.display && 'bg-accent',\r\n option.hidden && 'hidden',\r\n option.disabled && 'disabled pointer-events-none text-neutral-300'\r\n )\r\n \"\r\n [attr.aria-hidden]=\"option.disabled\">\r\n <input\r\n #radio\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-{{ option.display }}\"\r\n [attr.disabled]=\"option.disabled ? true : null\"\r\n [attr.aria-disabled]=\"option.disabled\"\r\n (click)=\"select()\"\r\n value=\"{{ option.display }}\" />\r\n\r\n <label\r\n for=\"date-filter-{{ option.display }}\"\r\n class=\"grow cursor-pointer p-1\">\r\n {{ option.display | syslang | transloco }}\r\n </label>\r\n </li>\r\n }\r\n\r\n @if (allowCustomRange) {\r\n <li\r\n role=\"listitem\"\r\n aria-label=\"open date range picker\"\r\n class=\"flex px-2 leading-7\"\r\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\r\n <input\r\n type=\"radio\"\r\n formControlName=\"option\"\r\n id=\"date-filter-range-dialog\"\r\n value=\"custom-range\"\r\n (click)=\"select()\" />\r\n\r\n <label\r\n for=\"date-filter-range-dialog\"\r\n class=\"flex grow cursor-pointer items-center gap-1 p-1\"\r\n (click)=\"dateRangeDialog()?.open()\">\r\n @let rangeLabel = customRangeLabel();\r\n @if (rangeLabel) {\r\n <span class=\"w-full\">{{ rangeLabel }}</span>\r\n } @else {\r\n <span>{{ \"filters.selectDateRange\" | transloco }}</span>\r\n }\r\n </label>\r\n </li>\r\n }\r\n </ul>\r\n </form>\r\n</details>\r\n\r\n<aggregation-date-range-dialog\r\n [lang]=\"lang()\"\r\n [useDateRange]=\"false\"\r\n [min]=\"form.get('customRange.from')?.value || undefined\"\r\n [max]=\"form.get('customRange.to')?.value || undefined\"\r\n (rangeSelected)=\"onRangeSelected($event)\" />\r\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
8815
9101
  }] });
8816
9102
 
8817
9103
  class ArticleEntities {
@@ -9288,7 +9574,7 @@ class AdvancedSearch {
9288
9574
  this.queryText.set("");
9289
9575
  }
9290
9576
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AdvancedSearch, deps: [], target: i0.ɵɵFactoryTarget.Component });
9291
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AdvancedSearch, isStandalone: true, selector: "advanced-search", inputs: { article: { classPropertyName: "article", publicName: "article", isSignal: true, isRequired: true, transformFunction: null }, previewStrategy: { classPropertyName: "previewStrategy", publicName: "previewStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, providers: [provideTranslocoScope("drawers")], ngImport: i0, template: "@if (article()) {\n <div\n [class]=\"\n cn(\n 'scroll-stable flex flex-col overflow-x-hidden overflow-y-auto pb-6 pl-6 pr-3',\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\n )\n \">\n <section class=\"mb-4 mt-6 flex w-full flex-col gap-6\">\n <header\n id=\"panel-control\"\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\n <div class=\"bg-muted flex grow items-center gap-2 rounded-e-none rounded-s px-3\">\n <input\n id=\"advanced-search-input\"\n type=\"search\"\n class=\"grow focus:outline-none\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\n [ngModel]=\"queryText()\"\n (ngModelChange)=\"queryText.set($event)\"\n (keydown.enter)=\"executeSearch()\" />\n\n @if (queryText() !== '') {\n <button\n variant=\"icon\"\n size=\"xs\"\n [attr.title]=\"'clear' | transloco\"\n [attr.aria-label]=\"'clear' | transloco\"\n (click)=\"clearInput()\"\n (keydown.enter)=\"clearInput()\">\n <i class=\"fa-fw far fa-xmark\" aria-hidden=\"true\"></i>\n <span class=\"sr-only\">{{ 'clear' | transloco }}</span>\n </button>\n }\n </div>\n\n <button\n size=\"default\"\n class=\"size-8 rounded-e rounded-s-none\"\n [disabled]=\"queryText() === '' || null\"\n [attr.title]=\"'search' | transloco\"\n [attr.aria-label]=\"'search' | transloco\"\n (click)=\"executeSearch()\">\n <i class=\"fa-fw far fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <span class=\"sr-only\">{{ 'search' | transloco }}</span>\n </button>\n </header>\n </section>\n\n <!-- the same name is used everywhere to simulate an accordion -->\n <!-- extracts -->\n <article-extracts [article]=\"article()\" />\n\n <!-- labels -->\n <article-labels [article]=\"article()\" />\n\n <!-- entities -->\n <article-entities [article]=\"article()\" />\n\n <!-- similar documents -->\n <article-similar-documents [article]=\"article()\" [strategy]=\"previewStrategy()\" (selected)=\"selected.emit($event)\" />\n </div>\n}\n", styles: [":host{--panel-max-height: none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: ArticleExtracts, selector: "article-extracts, ArticleExtracts, articleextracts", inputs: ["article"] }, { kind: "component", type: ArticleEntities, selector: "article-entities,ArticleEntities,articleentities", inputs: ["article"] }, { kind: "component", type: ArticleLabels, selector: "article-labels, ArticleLabels, articlelabels", inputs: ["article"] }, { kind: "component", type: ArticleSimilarDocuments, selector: "article-similar-documents, ArticleSimilarDocuments, articlesimilardocuments", inputs: ["article", "strategy"], outputs: ["selected"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
9577
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AdvancedSearch, isStandalone: true, selector: "advanced-search", inputs: { article: { classPropertyName: "article", publicName: "article", isSignal: true, isRequired: true, transformFunction: null }, previewStrategy: { classPropertyName: "previewStrategy", publicName: "previewStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, providers: [provideTranslocoScope("drawers")], ngImport: i0, template: "@if (article()) {\n <div\n [class]=\"\n cn(\n 'scroll-stable flex flex-col overflow-x-hidden overflow-y-auto pb-6 pl-6 pr-3',\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\n )\n \">\n <section class=\"mb-4 mt-6 flex w-full flex-col gap-6\">\n <header\n id=\"panel-control\"\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\n <div class=\"bg-muted flex grow items-center gap-2 rounded-e-none rounded-s px-3\">\n <input\n id=\"advanced-search-input\"\n type=\"search\"\n class=\"grow focus:outline-none\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\n [ngModel]=\"queryText()\"\n (ngModelChange)=\"queryText.set($event)\"\n (keydown.enter)=\"executeSearch()\" />\n\n @if (queryText() !== '') {\n <button\n variant=\"icon\"\n size=\"xs\"\n [attr.title]=\"'clear' | transloco\"\n [attr.aria-label]=\"'clear' | transloco\"\n (click)=\"clearInput()\"\n (keydown.enter)=\"clearInput()\">\n <i class=\"fa-fw far fa-xmark\" aria-hidden=\"true\"></i>\n <span class=\"sr-only\">{{ 'clear' | transloco }}</span>\n </button>\n }\n </div>\n\n <button\n size=\"default\"\n class=\"size-8 rounded-e rounded-s-none\"\n [disabled]=\"queryText() === '' || null\"\n [attr.title]=\"'search' | transloco\"\n [attr.aria-label]=\"'search' | transloco\"\n (click)=\"executeSearch()\">\n <i class=\"fa-fw far fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <span class=\"sr-only\">{{ 'search' | transloco }}</span>\n </button>\n </header>\n </section>\n\n <!-- the same name is used everywhere to simulate an accordion -->\n <!-- extracts -->\n <article-extracts [article]=\"article()\" />\n\n <!-- labels -->\n <article-labels [article]=\"article()\" />\n\n <!-- entities -->\n <article-entities [article]=\"article()\" />\n\n <!-- similar documents -->\n <article-similar-documents [article]=\"article()\" [strategy]=\"previewStrategy()\" (selected)=\"selected.emit($event)\" />\n </div>\n}\n", styles: [":host{--panel-max-height: none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: ArticleExtracts, selector: "article-extracts, ArticleExtracts, articleextracts", inputs: ["article"] }, { kind: "component", type: ArticleEntities, selector: "article-entities,ArticleEntities,articleentities", inputs: ["article"] }, { kind: "component", type: ArticleLabels, selector: "article-labels, ArticleLabels, articlelabels", inputs: ["article"] }, { kind: "component", type: ArticleSimilarDocuments, selector: "article-similar-documents, ArticleSimilarDocuments, articlesimilardocuments", inputs: ["article", "strategy"], outputs: ["selected"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
9292
9578
  }
9293
9579
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AdvancedSearch, decorators: [{
9294
9580
  type: Component,
@@ -9535,12 +9821,12 @@ class AlertDialog {
9535
9821
  @if (alert || canUpdateQuery()) {
9536
9822
  <div class="flex w-full flex-col gap-2">
9537
9823
  @if (alert) {
9538
- <button decoration="outline" (click)="execute()" [disabled]="!canUpdateQuery()">
9824
+ <button variant="outline" (click)="execute()" [disabled]="!canUpdateQuery()">
9539
9825
  {{ 'alerts.execute' | transloco }}
9540
9826
  </button>
9541
9827
  }
9542
9828
  @if (canUpdateQuery()) {
9543
- <button [disabled]="updateStatus() !== 'idle'" decoration="outline" (click)="updateQuery()">
9829
+ <button [disabled]="updateStatus() !== 'idle'" variant="outline" (click)="updateQuery()">
9544
9830
  @switch (updateStatus()) {
9545
9831
  @case ('updating') {
9546
9832
  <LoadingCircle class="size-4 animate-spin" width="16" height="16" />
@@ -9559,7 +9845,7 @@ class AlertDialog {
9559
9845
  </div>
9560
9846
  }
9561
9847
  <div class="ml-auto flex justify-end gap-2">
9562
- <button decoration="outline" (click)="dialog.cancel()">
9848
+ <button variant="outline" (click)="dialog.cancel()">
9563
9849
  {{ 'cancel' | transloco }}
9564
9850
  </button>
9565
9851
  <button (click)="confirm()" [disabled]="invalidForm()">
@@ -9569,7 +9855,7 @@ class AlertDialog {
9569
9855
  </DialogFooter>
9570
9856
  </DialogContent>
9571
9857
  </dialog>
9572
- `, isInline: true, styles: [".weekdays-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "component", type: LoadingCircleIconComponent, selector: "loading-circle, LoadingCircle, loadingcircle", inputs: ["class"] }, { kind: "component", type: CircleCheckIconComponent, selector: "circle-check, CircleCheck, circlecheck", inputs: ["class"] }, { kind: "directive", type: SelectOptionDirective, selector: "option", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
9858
+ `, isInline: true, styles: [".weekdays-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "component", type: LoadingCircleIconComponent, selector: "loading-circle, LoadingCircle, loadingcircle", inputs: ["class"] }, { kind: "component", type: CircleCheckIconComponent, selector: "circle-check, CircleCheck, circlecheck", inputs: ["class"] }, { kind: "directive", type: SelectOptionDirective, selector: "option", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
9573
9859
  }
9574
9860
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AlertDialog, decorators: [{
9575
9861
  type: Component,
@@ -9665,12 +9951,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
9665
9951
  @if (alert || canUpdateQuery()) {
9666
9952
  <div class="flex w-full flex-col gap-2">
9667
9953
  @if (alert) {
9668
- <button decoration="outline" (click)="execute()" [disabled]="!canUpdateQuery()">
9954
+ <button variant="outline" (click)="execute()" [disabled]="!canUpdateQuery()">
9669
9955
  {{ 'alerts.execute' | transloco }}
9670
9956
  </button>
9671
9957
  }
9672
9958
  @if (canUpdateQuery()) {
9673
- <button [disabled]="updateStatus() !== 'idle'" decoration="outline" (click)="updateQuery()">
9959
+ <button [disabled]="updateStatus() !== 'idle'" variant="outline" (click)="updateQuery()">
9674
9960
  @switch (updateStatus()) {
9675
9961
  @case ('updating') {
9676
9962
  <LoadingCircle class="size-4 animate-spin" width="16" height="16" />
@@ -9689,7 +9975,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
9689
9975
  </div>
9690
9976
  }
9691
9977
  <div class="ml-auto flex justify-end gap-2">
9692
- <button decoration="outline" (click)="dialog.cancel()">
9978
+ <button variant="outline" (click)="dialog.cancel()">
9693
9979
  {{ 'cancel' | transloco }}
9694
9980
  </button>
9695
9981
  <button (click)="confirm()" [disabled]="invalidForm()">
@@ -9745,11 +10031,11 @@ class AlertsComponent {
9745
10031
  this.tmpAlerts.splice(drop.currentIndex, 0, this.tmpAlerts.splice(drop.previousIndex, 1)[0]);
9746
10032
  }
9747
10033
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AlertsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9748
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AlertsComponent, isStandalone: true, selector: "Alerts", providers: [provideTranslocoScope('alerts')], viewQueries: [{ propertyName: "alertFormDialog", first: true, predicate: AlertDialog, descendants: true, isSignal: true }], ngImport: i0, template: "<ul\n role=\"list\"\n class=\"flex min-w-80 flex-col p-2\"\n cdkDropList\n [cdkDropListData]=\"tmpAlerts\"\n [cdkDropListDisabled]=\"!reordering()\"\n (cdkDropListDropped)=\"dropped($event)\">\n @if (floating) {\n <label class=\"text-xl font-bold\">{{ 'alerts.label' | transloco }}</label>\n <HorizontalDivider />\n }\n @for (alert of tmpAlerts; track $index) {\n <li role=\"listitem\" class=\"group h-10\" tabindex=\"0\" cdkDrag (click)=\"onClick($index)\" (keydown.enter)=\"onClick($index)\">\n <i class=\"fa-fw fas fa-bell shrink-0\" aria-hidden=\"true\"></i>\n <p class=\"line-clamp-1\">{{ alert.name }}</p>\n @if (!reordering()) {\n <button\n class=\"text-destructive hover:text-destructive invisible ms-auto transition-transform hover:scale-125 group-hover:visible\"\n title=\"{{ 'alerts.deleteAlert' | transloco }}\"\n [attr.aria-label]=\"'alerts.deleteAlert' | transloco\"\n (click)=\"deleteAlert($event, $index)\">\n <i class=\"fa-fw fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <i class=\"fa-fw fa-regular fa-bars\"></i>\n }\n </li>\n } @empty {\n <li role=\"listitem\" class=\"py-4 text-center text-neutral-500\">{{ 'alerts.noAlerts' | transloco }}</li>\n }\n</ul>\n<div class=\"flex flex-col gap-2 p-2\">\n <button decoration=\"outline\" class=\"w-full\" tabindex=\"0\" [attr.title]=\"'alerts.manageAlerts' | transloco\" [disabled]=\"!alerts().length\" (click)=\"reorder()\">\n {{ (reordering() ? 'save' : 'alerts.manageAlerts') | transloco }}\n </button>\n <button class=\"w-full\" [attr.title]=\"'alerts.createAlert' | transloco\" (click)=\"createAlert()\">\n {{ 'alerts.createAlert' | transloco }}\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: HorizontalDividerComponent, selector: "horizontal-divider, HorizontalDivider, horizontaldivider" }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10034
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AlertsComponent, isStandalone: true, selector: "Alerts", providers: [provideTranslocoScope('alerts')], viewQueries: [{ propertyName: "alertFormDialog", first: true, predicate: AlertDialog, descendants: true, isSignal: true }], ngImport: i0, template: "<ul\r\n role=\"list\"\r\n class=\"flex min-w-80 flex-col p-2\"\r\n cdkDropList\r\n [cdkDropListData]=\"tmpAlerts\"\r\n [cdkDropListDisabled]=\"!reordering()\"\r\n (cdkDropListDropped)=\"dropped($event)\">\r\n @if (floating) {\r\n <label class=\"text-xl font-bold\">{{ \"alerts.label\" | transloco }}</label>\r\n <Separator />\r\n }\r\n @for (alert of tmpAlerts; track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n cdkDrag\r\n (click)=\"onClick($index)\"\r\n (keydown.enter)=\"onClick($index)\">\r\n <i class=\"fa-fw fas fa-bell shrink-0\" aria-hidden=\"true\"></i>\r\n <p class=\"line-clamp-1\">{{ alert.name }}</p>\r\n @if (!reordering()) {\r\n <button\r\n class=\"text-destructive hover:text-destructive invisible ms-auto transition-transform group-hover:visible hover:scale-125\"\r\n title=\"{{ 'alerts.deleteAlert' | transloco }}\"\r\n [attr.aria-label]=\"'alerts.deleteAlert' | transloco\"\r\n (click)=\"deleteAlert($event, $index)\">\r\n <i class=\"fa-fw fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\r\n </button>\r\n } @else {\r\n <i class=\"fa-fw fa-regular fa-bars\"></i>\r\n }\r\n </li>\r\n } @empty {\r\n <li role=\"listitem\" class=\"py-4 text-center text-neutral-500\">\r\n {{ \"alerts.noAlerts\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n<div class=\"flex flex-col gap-2 p-2\">\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'alerts.manageAlerts' | transloco\"\r\n [disabled]=\"!alerts().length\"\r\n (click)=\"reorder()\">\r\n {{ (reordering() ? \"save\" : \"alerts.manageAlerts\") | transloco }}\r\n </button>\r\n <button\r\n class=\"w-full\"\r\n [attr.title]=\"'alerts.createAlert' | transloco\"\r\n (click)=\"createAlert()\">\r\n {{ \"alerts.createAlert\" | transloco }}\r\n </button>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
9749
10035
  }
9750
10036
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AlertsComponent, decorators: [{
9751
10037
  type: Component,
9752
- args: [{ selector: 'Alerts', standalone: true, imports: [TranslocoPipe, ButtonComponent, HorizontalDividerComponent, ListItemComponent, DragDropModule], providers: [provideTranslocoScope('alerts')], template: "<ul\n role=\"list\"\n class=\"flex min-w-80 flex-col p-2\"\n cdkDropList\n [cdkDropListData]=\"tmpAlerts\"\n [cdkDropListDisabled]=\"!reordering()\"\n (cdkDropListDropped)=\"dropped($event)\">\n @if (floating) {\n <label class=\"text-xl font-bold\">{{ 'alerts.label' | transloco }}</label>\n <HorizontalDivider />\n }\n @for (alert of tmpAlerts; track $index) {\n <li role=\"listitem\" class=\"group h-10\" tabindex=\"0\" cdkDrag (click)=\"onClick($index)\" (keydown.enter)=\"onClick($index)\">\n <i class=\"fa-fw fas fa-bell shrink-0\" aria-hidden=\"true\"></i>\n <p class=\"line-clamp-1\">{{ alert.name }}</p>\n @if (!reordering()) {\n <button\n class=\"text-destructive hover:text-destructive invisible ms-auto transition-transform hover:scale-125 group-hover:visible\"\n title=\"{{ 'alerts.deleteAlert' | transloco }}\"\n [attr.aria-label]=\"'alerts.deleteAlert' | transloco\"\n (click)=\"deleteAlert($event, $index)\">\n <i class=\"fa-fw fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <i class=\"fa-fw fa-regular fa-bars\"></i>\n }\n </li>\n } @empty {\n <li role=\"listitem\" class=\"py-4 text-center text-neutral-500\">{{ 'alerts.noAlerts' | transloco }}</li>\n }\n</ul>\n<div class=\"flex flex-col gap-2 p-2\">\n <button decoration=\"outline\" class=\"w-full\" tabindex=\"0\" [attr.title]=\"'alerts.manageAlerts' | transloco\" [disabled]=\"!alerts().length\" (click)=\"reorder()\">\n {{ (reordering() ? 'save' : 'alerts.manageAlerts') | transloco }}\n </button>\n <button class=\"w-full\" [attr.title]=\"'alerts.createAlert' | transloco\" (click)=\"createAlert()\">\n {{ 'alerts.createAlert' | transloco }}\n </button>\n</div>\n" }]
10038
+ args: [{ selector: 'Alerts', standalone: true, imports: [TranslocoPipe, ButtonComponent, ListItemComponent, DragDropModule, Separator], providers: [provideTranslocoScope('alerts')], template: "<ul\r\n role=\"list\"\r\n class=\"flex min-w-80 flex-col p-2\"\r\n cdkDropList\r\n [cdkDropListData]=\"tmpAlerts\"\r\n [cdkDropListDisabled]=\"!reordering()\"\r\n (cdkDropListDropped)=\"dropped($event)\">\r\n @if (floating) {\r\n <label class=\"text-xl font-bold\">{{ \"alerts.label\" | transloco }}</label>\r\n <Separator />\r\n }\r\n @for (alert of tmpAlerts; track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n cdkDrag\r\n (click)=\"onClick($index)\"\r\n (keydown.enter)=\"onClick($index)\">\r\n <i class=\"fa-fw fas fa-bell shrink-0\" aria-hidden=\"true\"></i>\r\n <p class=\"line-clamp-1\">{{ alert.name }}</p>\r\n @if (!reordering()) {\r\n <button\r\n class=\"text-destructive hover:text-destructive invisible ms-auto transition-transform group-hover:visible hover:scale-125\"\r\n title=\"{{ 'alerts.deleteAlert' | transloco }}\"\r\n [attr.aria-label]=\"'alerts.deleteAlert' | transloco\"\r\n (click)=\"deleteAlert($event, $index)\">\r\n <i class=\"fa-fw fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\r\n </button>\r\n } @else {\r\n <i class=\"fa-fw fa-regular fa-bars\"></i>\r\n }\r\n </li>\r\n } @empty {\r\n <li role=\"listitem\" class=\"py-4 text-center text-neutral-500\">\r\n {{ \"alerts.noAlerts\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n<div class=\"flex flex-col gap-2 p-2\">\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'alerts.manageAlerts' | transloco\"\r\n [disabled]=\"!alerts().length\"\r\n (click)=\"reorder()\">\r\n {{ (reordering() ? \"save\" : \"alerts.manageAlerts\") | transloco }}\r\n </button>\r\n <button\r\n class=\"w-full\"\r\n [attr.title]=\"'alerts.createAlert' | transloco\"\r\n (click)=\"createAlert()\">\r\n {{ \"alerts.createAlert\" | transloco }}\r\n </button>\r\n</div>\r\n" }]
9753
10039
  }], ctorParameters: () => [], propDecorators: { alertFormDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AlertDialog), { isSignal: true }] }] } });
9754
10040
 
9755
10041
  class ChangePasswordComponent {
@@ -9971,7 +10257,7 @@ class ChangePasswordComponent {
9971
10257
  </button>
9972
10258
  </CardFooter>
9973
10259
  </Card>
9974
- `, isInline: true, styles: ["input::-ms-reveal{display:none}\n"], dependencies: [{ 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: ButtonComponent, selector: "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: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10260
+ `, isInline: true, styles: ["input::-ms-reveal{display:none}\n"], dependencies: [{ 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: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: CardComponent, selector: ".card, card, Card", inputs: ["class", "variant", "hover"] }, { kind: "directive", type: CardHeaderComponent, selector: ".card-header, card-header, CardHeader, cardheader", inputs: ["class"] }, { kind: "directive", type: CardContentComponent, selector: ".card-content, card-content, CardContent, cardcontent", inputs: ["class"] }, { kind: "directive", type: CardFooterComponent, selector: ".card-footer, card-footer, CardFooter, cardfooter", inputs: ["class"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
9975
10261
  }
9976
10262
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ChangePasswordComponent, decorators: [{
9977
10263
  type: Component,
@@ -10168,7 +10454,7 @@ class ForgotPasswordComponent {
10168
10454
 
10169
10455
  </CardFooter>
10170
10456
  </Card>
10171
- `, isInline: true, dependencies: [{ 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: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "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" }] });
10457
+ `, isInline: true, dependencies: [{ 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: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: CardComponent, selector: ".card, card, Card", inputs: ["class", "variant", "hover"] }, { kind: "directive", type: CardHeaderComponent, selector: ".card-header, card-header, CardHeader, cardheader", inputs: ["class"] }, { kind: "directive", type: CardContentComponent, selector: ".card-content, card-content, CardContent, cardcontent", inputs: ["class"] }, { kind: "directive", type: CardFooterComponent, selector: ".card-footer, card-footer, CardFooter, cardfooter", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10172
10458
  }
10173
10459
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ForgotPasswordComponent, decorators: [{
10174
10460
  type: Component,
@@ -10348,7 +10634,7 @@ class SignInComponent {
10348
10634
  cdkTrapFocusAutoCapture="true"
10349
10635
  class="bg-card rounded-xl shadow-sm">
10350
10636
  <CardHeader class="flex flex-col items-center gap-3 text-center">
10351
- <img class="h-12 content-(--logo-large)" alt="logo" />
10637
+ <img class="h-12 content-(--logo-large-alt)" alt="logo" />
10352
10638
  </CardHeader>
10353
10639
 
10354
10640
  <CardContent class="grid gap-4">
@@ -10388,7 +10674,7 @@ class SignInComponent {
10388
10674
  (keydown.enter)="forgotPassword.emit()">
10389
10675
  {{ "login.forgotPassword" | transloco }}
10390
10676
  </span>
10391
- <button
10677
+ <button variant="primary"
10392
10678
  [disabled]="!isValid()"
10393
10679
  (click)="handleLoginWithCredentials()">
10394
10680
  {{ "login.connect" | transloco }}
@@ -10405,7 +10691,7 @@ class SignInComponent {
10405
10691
  } @else {
10406
10692
  <app-wait />
10407
10693
  }
10408
- `, isInline: true, styles: ["input{background-color:var(--background)}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i2.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "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: "component", type: LoadingComponent, selector: "app-wait" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10694
+ `, isInline: true, styles: ["input{background-color:var(--background)}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i2.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: CardComponent, selector: ".card, card, Card", inputs: ["class", "variant", "hover"] }, { kind: "directive", type: CardHeaderComponent, selector: ".card-header, card-header, CardHeader, cardheader", inputs: ["class"] }, { kind: "directive", type: CardContentComponent, selector: ".card-content, card-content, CardContent, cardcontent", inputs: ["class"] }, { kind: "component", type: LoadingComponent, selector: "app-wait" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10409
10695
  }
10410
10696
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SignInComponent, decorators: [{
10411
10697
  type: Component,
@@ -10428,7 +10714,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10428
10714
  cdkTrapFocusAutoCapture="true"
10429
10715
  class="bg-card rounded-xl shadow-sm">
10430
10716
  <CardHeader class="flex flex-col items-center gap-3 text-center">
10431
- <img class="h-12 content-(--logo-large)" alt="logo" />
10717
+ <img class="h-12 content-(--logo-large-alt)" alt="logo" />
10432
10718
  </CardHeader>
10433
10719
 
10434
10720
  <CardContent class="grid gap-4">
@@ -10468,7 +10754,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10468
10754
  (keydown.enter)="forgotPassword.emit()">
10469
10755
  {{ "login.forgotPassword" | transloco }}
10470
10756
  </span>
10471
- <button
10757
+ <button variant="primary"
10472
10758
  [disabled]="!isValid()"
10473
10759
  (click)="handleLoginWithCredentials()">
10474
10760
  {{ "login.connect" | transloco }}
@@ -10700,7 +10986,7 @@ class BookmarksComponent {
10700
10986
  this.range.set(this.range() + (this.config.itemsPerPage ?? 10));
10701
10987
  }
10702
10988
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: BookmarksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10703
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: BookmarksComponent, isStandalone: true, selector: "bookmarks, Bookmarks", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("bookmarks")], ngImport: i0, template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{ 'bookmarks.label' | transloco }}</label>\n <Separator />\n </div>\n}\n\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\" role=\"list\">\n @for (bookmark of paginatedBookmarks(); track $index) {\n <li role=\"listitem\" class=\"group h-10\" tabindex=\"0\" (click)=\"onClick(bookmark)\" (keydown.enter)=\"onClick(bookmark)\">\n <BookmarkIcon solid class=\"shrink-0\" />\n\n <p class=\"line-clamp-1\">{{ bookmark.label }}</p>\n\n @if (bookmark.author) {\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\n <UserIcon class=\"size-3\"/>\n <span class=\"line-clamp-1\">{{ bookmark.author }}</span>\n </Badge>\n }\n @if (bookmark.parentFolder) {\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\n <FolderIcon class=\"size-3\"/>\n <span class=\"line-clamp-1\">{{ bookmark.parentFolder }}</span>\n </Badge>\n }\n\n <button\n variant=\"ghost\"\n size=\"icon\"\n title=\"{{ 'bookmarks.openBookmark' | transloco }}\"\n class=\"text-destructive ms-auto group-hover:visible\"\n [attr.title]=\"'bookmarks.removeBookmark' | transloco\"\n [attr.aria-label]=\"'bookmarks.removeBookmark' | transloco\"\n (click)=\"onDelete(bookmark, $event)\">\n <TrashIcon />\n </button>\n </li>\n } @empty {\n <li class=\"py-4 text-center text-neutral-500\">{{ 'bookmarks.noBookmarks' | transloco }}</li>\n }\n</ul>\n\n<div class=\"flex flex-col px-2\">\n @if (hasMore() && config.showLoadMore) {\n <button variant=\"ghost\" class=\"w-full\" tabindex=\"0\" [attr.title]=\"'loadMore' | transloco\" (click)=\"loadMore($event)\">\n {{ 'loadMore' | transloco }}\n </button>\n }\n <button decoration=\"underline\" class=\"ml-auto\" [attr.title]=\"'seeMore' | transloco\" [routerLink]=\"[config.routerLink]\">{{ 'seeMore' | transloco }}</button>\n</div>\n", styles: [":host ul{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "component", type: BookmarkIcon, selector: "bookmark-icon, BookmarkIcon", inputs: ["class", "solid"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: FolderIcon, selector: "folder-icon, FolderIcon", inputs: ["class"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10989
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: BookmarksComponent, isStandalone: true, selector: "bookmarks, Bookmarks", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("bookmarks")], ngImport: i0, template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{ \"bookmarks.label\" | transloco }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\" role=\"list\">\r\n @for (bookmark of paginatedBookmarks(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(bookmark)\"\r\n (keydown.enter)=\"onClick(bookmark)\">\r\n <BookmarkIcon solid class=\"shrink-0\" />\r\n\r\n <p class=\"line-clamp-1\">{{ bookmark.label }}</p>\r\n\r\n @if (bookmark.author) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <UserIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.author }}</span>\r\n </Badge>\r\n }\r\n @if (bookmark.parentFolder) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <FolderIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.parentFolder }}</span>\r\n </Badge>\r\n }\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title=\"{{ 'bookmarks.openBookmark' | transloco }}\"\r\n class=\"text-destructive ms-auto group-hover:visible\"\r\n [attr.title]=\"'bookmarks.removeBookmark' | transloco\"\r\n [attr.aria-label]=\"'bookmarks.removeBookmark' | transloco\"\r\n (click)=\"onDelete(bookmark, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"py-4 text-center text-neutral-500\">\r\n {{ \"bookmarks.noBookmarks\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"ghost\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n", styles: [":host ul{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "component", type: BookmarkIcon, selector: "bookmark-icon, BookmarkIcon", inputs: ["class", "solid"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: FolderIcon, selector: "folder-icon, FolderIcon", inputs: ["class"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10704
10990
  }
10705
10991
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: BookmarksComponent, decorators: [{
10706
10992
  type: Component,
@@ -10715,7 +11001,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10715
11001
  TrashIcon,
10716
11002
  FolderIcon,
10717
11003
  BadgeComponent
10718
- ], providers: [provideTranslocoScope("bookmarks")], template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{ 'bookmarks.label' | transloco }}</label>\n <Separator />\n </div>\n}\n\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\" role=\"list\">\n @for (bookmark of paginatedBookmarks(); track $index) {\n <li role=\"listitem\" class=\"group h-10\" tabindex=\"0\" (click)=\"onClick(bookmark)\" (keydown.enter)=\"onClick(bookmark)\">\n <BookmarkIcon solid class=\"shrink-0\" />\n\n <p class=\"line-clamp-1\">{{ bookmark.label }}</p>\n\n @if (bookmark.author) {\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\n <UserIcon class=\"size-3\"/>\n <span class=\"line-clamp-1\">{{ bookmark.author }}</span>\n </Badge>\n }\n @if (bookmark.parentFolder) {\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\n <FolderIcon class=\"size-3\"/>\n <span class=\"line-clamp-1\">{{ bookmark.parentFolder }}</span>\n </Badge>\n }\n\n <button\n variant=\"ghost\"\n size=\"icon\"\n title=\"{{ 'bookmarks.openBookmark' | transloco }}\"\n class=\"text-destructive ms-auto group-hover:visible\"\n [attr.title]=\"'bookmarks.removeBookmark' | transloco\"\n [attr.aria-label]=\"'bookmarks.removeBookmark' | transloco\"\n (click)=\"onDelete(bookmark, $event)\">\n <TrashIcon />\n </button>\n </li>\n } @empty {\n <li class=\"py-4 text-center text-neutral-500\">{{ 'bookmarks.noBookmarks' | transloco }}</li>\n }\n</ul>\n\n<div class=\"flex flex-col px-2\">\n @if (hasMore() && config.showLoadMore) {\n <button variant=\"ghost\" class=\"w-full\" tabindex=\"0\" [attr.title]=\"'loadMore' | transloco\" (click)=\"loadMore($event)\">\n {{ 'loadMore' | transloco }}\n </button>\n }\n <button decoration=\"underline\" class=\"ml-auto\" [attr.title]=\"'seeMore' | transloco\" [routerLink]=\"[config.routerLink]\">{{ 'seeMore' | transloco }}</button>\n</div>\n", styles: [":host ul{scrollbar-width:thin}\n"] }]
11004
+ ], providers: [provideTranslocoScope("bookmarks")], template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{ \"bookmarks.label\" | transloco }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\" role=\"list\">\r\n @for (bookmark of paginatedBookmarks(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(bookmark)\"\r\n (keydown.enter)=\"onClick(bookmark)\">\r\n <BookmarkIcon solid class=\"shrink-0\" />\r\n\r\n <p class=\"line-clamp-1\">{{ bookmark.label }}</p>\r\n\r\n @if (bookmark.author) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <UserIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.author }}</span>\r\n </Badge>\r\n }\r\n @if (bookmark.parentFolder) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <FolderIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.parentFolder }}</span>\r\n </Badge>\r\n }\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title=\"{{ 'bookmarks.openBookmark' | transloco }}\"\r\n class=\"text-destructive ms-auto group-hover:visible\"\r\n [attr.title]=\"'bookmarks.removeBookmark' | transloco\"\r\n [attr.aria-label]=\"'bookmarks.removeBookmark' | transloco\"\r\n (click)=\"onDelete(bookmark, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"py-4 text-center text-neutral-500\">\r\n {{ \"bookmarks.noBookmarks\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"ghost\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n", styles: [":host ul{scrollbar-width:thin}\n"] }]
10719
11005
  }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
10720
11006
 
10721
11007
  class DeleteCollectionDialog {
@@ -10748,7 +11034,7 @@ class DeleteCollectionDialog {
10748
11034
  <p>{{ 'collections.confirmDelete' | transloco }} {{ collection()?.name }}?</p>
10749
11035
 
10750
11036
  <DialogFooter>
10751
- <button decoration="outline" (click)="dialog.cancel()">
11037
+ <button variant="outline" (click)="dialog.cancel()">
10752
11038
  {{ 'cancel' | transloco }}
10753
11039
  </button>
10754
11040
 
@@ -10758,7 +11044,7 @@ class DeleteCollectionDialog {
10758
11044
  </DialogFooter>
10759
11045
  </DialogContent>
10760
11046
  </dialog>
10761
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11047
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10762
11048
  }
10763
11049
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DeleteCollectionDialog, decorators: [{
10764
11050
  type: Component,
@@ -10785,7 +11071,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10785
11071
  <p>{{ 'collections.confirmDelete' | transloco }} {{ collection()?.name }}?</p>
10786
11072
 
10787
11073
  <DialogFooter>
10788
- <button decoration="outline" (click)="dialog.cancel()">
11074
+ <button variant="outline" (click)="dialog.cancel()">
10789
11075
  {{ 'cancel' | transloco }}
10790
11076
  </button>
10791
11077
 
@@ -10840,7 +11126,7 @@ class CollectionsComponent {
10840
11126
  this.range.set(this.range() + (this.config.itemsPerPage ?? 10));
10841
11127
  }
10842
11128
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CollectionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10843
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CollectionsComponent, isStandalone: true, selector: "app-collections", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("collections")], viewQueries: [{ propertyName: "deleteCollectionDialog", first: true, predicate: DeleteCollectionDialog, descendants: true, isSignal: true }], ngImport: i0, template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{ 'collections.label' | transloco }}</label>\n <Separator />\n </div>\n}\n\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\">\n @for (collection of paginatedCollections(); track $index) {\n <li\n role=\"listitem\"\n class=\"group grid grid-cols-[min-content_auto_min-content] items-center\"\n tabindex=\"0\"\n (click)=\"onClick(collection)\"\n (keydown.enter)=\"onClick(collection)\">\n <i class=\"fas fa-inbox ps-2\"></i>\n\n <p class=\"mx-2 line-clamp-1\">{{ collection.name }}</p>\n\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible group-hover:visible\"\n title=\"{{ 'collections.deleteCollection' | transloco }}\"\n [attr.aria-label]=\"'collections.deleteCollection' | transloco\"\n (click)=\"onDelete(collection, $index, $event)\">\n <TrashIcon />\n </button>\n </li>\n } @empty {\n <li class=\"list-none py-4 text-center text-neutral-500\">{{ 'collections.noCollections' | transloco }}</li>\n }\n</ul>\n\n<div class=\"flex flex-col px-2\">\n @if (hasMore() && config.showLoadMore) {\n <button decoration=\"outline\" class=\"w-full\" tabindex=\"0\" [attr.title]=\"'loadMore' | transloco\" (click)=\"loadMore($event)\">\n {{ 'loadMore' | transloco }}\n </button>\n }\n <button decoration=\"underline\" class=\"ml-auto\" [attr.title]=\"'seeMore' | transloco\" [routerLink]=\"[config.routerLink]\">{{ 'seeMore' | transloco }}</button>\n</div>\n\n<delete-collection-dialog />\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: DeleteCollectionDialog, selector: "delete-collection-dialog" }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11129
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CollectionsComponent, isStandalone: true, selector: "app-collections", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("collections")], viewQueries: [{ propertyName: "deleteCollectionDialog", first: true, predicate: DeleteCollectionDialog, descendants: true, isSignal: true }], ngImport: i0, template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{\r\n \"collections.label\" | transloco\r\n }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\">\r\n @for (collection of paginatedCollections(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group grid grid-cols-[min-content_auto_min-content] items-center\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(collection)\"\r\n (keydown.enter)=\"onClick(collection)\">\r\n <i class=\"fas fa-inbox ps-2\"></i>\r\n\r\n <p class=\"mx-2 line-clamp-1\">{{ collection.name }}</p>\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n class=\"text-destructive invisible group-hover:visible\"\r\n title=\"{{ 'collections.deleteCollection' | transloco }}\"\r\n [attr.aria-label]=\"'collections.deleteCollection' | transloco\"\r\n (click)=\"onDelete(collection, $index, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"list-none py-4 text-center text-neutral-500\">\r\n {{ \"collections.noCollections\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n\r\n<delete-collection-dialog />\r\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: DeleteCollectionDialog, selector: "delete-collection-dialog" }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10844
11130
  }
10845
11131
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CollectionsComponent, decorators: [{
10846
11132
  type: Component,
@@ -10852,7 +11138,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
10852
11138
  ListItemComponent,
10853
11139
  Separator,
10854
11140
  TrashIcon
10855
- ], providers: [provideTranslocoScope("collections")], template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{ 'collections.label' | transloco }}</label>\n <Separator />\n </div>\n}\n\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\">\n @for (collection of paginatedCollections(); track $index) {\n <li\n role=\"listitem\"\n class=\"group grid grid-cols-[min-content_auto_min-content] items-center\"\n tabindex=\"0\"\n (click)=\"onClick(collection)\"\n (keydown.enter)=\"onClick(collection)\">\n <i class=\"fas fa-inbox ps-2\"></i>\n\n <p class=\"mx-2 line-clamp-1\">{{ collection.name }}</p>\n\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible group-hover:visible\"\n title=\"{{ 'collections.deleteCollection' | transloco }}\"\n [attr.aria-label]=\"'collections.deleteCollection' | transloco\"\n (click)=\"onDelete(collection, $index, $event)\">\n <TrashIcon />\n </button>\n </li>\n } @empty {\n <li class=\"list-none py-4 text-center text-neutral-500\">{{ 'collections.noCollections' | transloco }}</li>\n }\n</ul>\n\n<div class=\"flex flex-col px-2\">\n @if (hasMore() && config.showLoadMore) {\n <button decoration=\"outline\" class=\"w-full\" tabindex=\"0\" [attr.title]=\"'loadMore' | transloco\" (click)=\"loadMore($event)\">\n {{ 'loadMore' | transloco }}\n </button>\n }\n <button decoration=\"underline\" class=\"ml-auto\" [attr.title]=\"'seeMore' | transloco\" [routerLink]=\"[config.routerLink]\">{{ 'seeMore' | transloco }}</button>\n</div>\n\n<delete-collection-dialog />\n" }]
11141
+ ], providers: [provideTranslocoScope("collections")], template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{\r\n \"collections.label\" | transloco\r\n }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\">\r\n @for (collection of paginatedCollections(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group grid grid-cols-[min-content_auto_min-content] items-center\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(collection)\"\r\n (keydown.enter)=\"onClick(collection)\">\r\n <i class=\"fas fa-inbox ps-2\"></i>\r\n\r\n <p class=\"mx-2 line-clamp-1\">{{ collection.name }}</p>\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n class=\"text-destructive invisible group-hover:visible\"\r\n title=\"{{ 'collections.deleteCollection' | transloco }}\"\r\n [attr.aria-label]=\"'collections.deleteCollection' | transloco\"\r\n (click)=\"onDelete(collection, $index, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"list-none py-4 text-center text-neutral-500\">\r\n {{ \"collections.noCollections\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n\r\n<delete-collection-dialog />\r\n" }]
10856
11142
  }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], deleteCollectionDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DeleteCollectionDialog), { isSignal: true }] }] } });
10857
11143
 
10858
11144
  class OverrideUserDialogComponent {
@@ -10951,7 +11237,7 @@ class OverrideUserDialogComponent {
10951
11237
  </div>
10952
11238
 
10953
11239
  <DialogFooter>
10954
- <button decoration="outline" (click)="dialog.close()">
11240
+ <button variant="outline" (click)="dialog.close()">
10955
11241
  {{ 'cancel' | transloco }}
10956
11242
  </button>
10957
11243
 
@@ -10961,7 +11247,7 @@ class OverrideUserDialogComponent {
10961
11247
  </DialogFooter>
10962
11248
  </DialogContent>
10963
11249
  </dialog>
10964
- `, isInline: true, dependencies: [{ 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: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11250
+ `, isInline: true, dependencies: [{ 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: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
10965
11251
  }
10966
11252
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OverrideUserDialogComponent, decorators: [{
10967
11253
  type: Component,
@@ -11016,7 +11302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11016
11302
  </div>
11017
11303
 
11018
11304
  <DialogFooter>
11019
- <button decoration="outline" (click)="dialog.close()">
11305
+ <button variant="outline" (click)="dialog.close()">
11020
11306
  {{ 'cancel' | transloco }}
11021
11307
  </button>
11022
11308
 
@@ -11055,7 +11341,7 @@ class ResetUserSettingsDialogComponent {
11055
11341
  <p>{{ 'dialogs.resetUserSettings.message' | transloco }}</p>
11056
11342
 
11057
11343
  <DialogFooter>
11058
- <button decoration="outline" (click)="dialog.close()">
11344
+ <button variant="outline" (click)="dialog.close()">
11059
11345
  {{ 'cancel' | transloco }}
11060
11346
  </button>
11061
11347
 
@@ -11065,7 +11351,7 @@ class ResetUserSettingsDialogComponent {
11065
11351
  </DialogFooter>
11066
11352
  </DialogContent>
11067
11353
  </dialog>
11068
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11354
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11069
11355
  }
11070
11356
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ResetUserSettingsDialogComponent, decorators: [{
11071
11357
  type: Component,
@@ -11092,7 +11378,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
11092
11378
  <p>{{ 'dialogs.resetUserSettings.message' | transloco }}</p>
11093
11379
 
11094
11380
  <DialogFooter>
11095
- <button decoration="outline" (click)="dialog.close()">
11381
+ <button variant="outline" (click)="dialog.close()">
11096
11382
  {{ 'cancel' | transloco }}
11097
11383
  </button>
11098
11384
 
@@ -11348,7 +11634,7 @@ class DrawerNavbarComponent {
11348
11634
 
11349
11635
  <ng-content></ng-content>
11350
11636
  </menu>
11351
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: VerticalDividerComponent, selector: "vertical-divider, VerticalDivider, verticaldivider" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11637
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: VerticalDividerComponent, selector: "vertical-divider, VerticalDivider, verticaldivider" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
11352
11638
  }
11353
11639
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DrawerNavbarComponent, decorators: [{
11354
11640
  type: Component,
@@ -11697,7 +11983,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
11697
11983
  return res;
11698
11984
  }
11699
11985
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DrawerAdvancedFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11700
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DrawerAdvancedFiltersComponent, isStandalone: true, selector: "advanced-filters", host: { classAttribute: "fixed bg-background grid h-full top-0 -right-full justify-end" }, providers: [DrawerService, SyslangPipe, TranslocoPipe, provideTranslocoScope("drawers")], usesInheritance: true, ngImport: i0, template: "<div (click)=\"drawer.toggleExtension()\" (keydown.escape)=\"drawer.toggleExtension()\" [attr.aria-hidden]=\"true\"></div>\n\n<div class=\"flex h-full flex-col overflow-auto\">\n <DrawerNavbar class=\"border-foreground/10 block border-b\">\n <button [attr.title]=\"'drawers.search' | transloco\" (click)=\"onSearch()\">\n {{ 'drawers.search' | transloco }}\n </button>\n </DrawerNavbar>\n\n <div class=\"flex h-full grow flex-col overflow-auto\">\n <section class=\"flex flex-col gap-4 p-6\" [formGroup]=\"form\">\n <!-- FIND IN -->\n <h1 class=\"text-xl font-bold\">{{ 'drawers.findInContent' | transloco }}</h1>\n <div class=\"flex items-center gap-4\" formGroupName=\"content\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInContent' | transloco }}</span>\n <select\n id=\"content-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input\n [variant]=\"inputVariant()\"\n id=\"content-value\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"getPlaceholder('content.operator')\"\n formControlName=\"value\" />\n </div>\n @if (enableFieldedSearch()) {\n <div class=\"flex items-center gap-4\" formGroupName=\"title\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInTitle' | transloco }}</span>\n <select\n id=\"title-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input id=\"title-value\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\" [placeholder]=\"getPlaceholder('title.operator')\" formControlName=\"value\" />\n </div>\n }\n\n <!-- TABS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.inScope' | transloco }}&nbsp;&quot;{{ currentTab() }}&quot;</h1>\n\n <Tabs>\n <TabsList variant=\"ghost\">\n @for (tab of tabs(); track $index) {\n <Tab class=\"w-fit\" [value]=\"tab.path\" [active]=\"tab.path === currentTab()\" (click)=\"onTabChange(tab.path)\">\n {{ tab.display | syslang | transloco }}\n </Tab>\n }\n </TabsList>\n </Tabs>\n\n <!-- FILTERS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.applyFilters' | transloco }}</h1>\n @for (filter of filters(); track $index) {\n <DropdownInput\n [suggestions]=\"suggestions()\"\n [selected]=\"getItems(filter.column)\"\n [label]=\"filter.display || filter.alias | syslang | transloco\"\n [placeholder]=\"'drawers.startTyping' | transloco\"\n [noResultLabel]=\"'drawers.noResult' | transloco\"\n (onFocus)=\"setFilterFocus($event, filter)\"\n (onKeyUp)=\"onInputTyping($event)\"\n (removeItem)=\"removeItem($event, filter)\"\n (addItem)=\"addItem($event, filter)\" />\n } @empty {\n {{ 'drawers.noFilters' | transloco }}\n }\n </section>\n </div>\n</div>\n", styles: [":host{--drawer-width: 46;--drawer-subdrawer-width: 400px;width:calc(100vw / 100 * var(--drawer-width) + var(--drawer-subdrawer-width));z-index:var(--z-drawer);grid-template-columns:0 1fr var(--drawer-subdrawer-width);transition:right .3s ease-in-out,transform .3s ease-in-out}:host[drawer-opened=true]{right:calc(var(--drawer-subdrawer-width) * -1);box-shadow:var(--drawer-box-shadow)}:host[drawer-extended=true]{width:100vw;right:calc(var(--spacing) * 0);grid-template-columns:1fr calc(var(--drawer-width) * 1%) var(--drawer-subdrawer-width);box-shadow:unset}:is() .dropdown{width:100%}:is() .dropdown-content{width:50%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: DrawerNavbarComponent, selector: "DrawerNavbar, drawernavbar" }, { kind: "component", type: DropdownInputComponent, selector: "dropdown-input, DropdownInput", inputs: ["label", "placeholder", "noResultLabel", "suggestions", "selected"], outputs: ["onFocus", "onKeyUp", "removeItem", "addItem"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
11986
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: DrawerAdvancedFiltersComponent, isStandalone: true, selector: "advanced-filters", host: { classAttribute: "fixed bg-background grid h-full top-0 -right-full justify-end" }, providers: [DrawerService, SyslangPipe, TranslocoPipe, provideTranslocoScope("drawers")], usesInheritance: true, ngImport: i0, template: "<div (click)=\"drawer.toggleExtension()\" (keydown.escape)=\"drawer.toggleExtension()\" [attr.aria-hidden]=\"true\"></div>\n\n<div class=\"flex h-full flex-col overflow-auto\">\n <DrawerNavbar class=\"border-foreground/10 block border-b\">\n <button [attr.title]=\"'drawers.search' | transloco\" (click)=\"onSearch()\">\n {{ 'drawers.search' | transloco }}\n </button>\n </DrawerNavbar>\n\n <div class=\"flex h-full grow flex-col overflow-auto\">\n <section class=\"flex flex-col gap-4 p-6\" [formGroup]=\"form\">\n <!-- FIND IN -->\n <h1 class=\"text-xl font-bold\">{{ 'drawers.findInContent' | transloco }}</h1>\n <div class=\"flex items-center gap-4\" formGroupName=\"content\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInContent' | transloco }}</span>\n <select\n id=\"content-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input\n [variant]=\"inputVariant()\"\n id=\"content-value\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"getPlaceholder('content.operator')\"\n formControlName=\"value\" />\n </div>\n @if (enableFieldedSearch()) {\n <div class=\"flex items-center gap-4\" formGroupName=\"title\">\n <span class=\"w-1/3 font-semibold\">{{ 'drawers.findInTitle' | transloco }}</span>\n <select\n id=\"title-operator\"\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 w-full rounded-md border px-2 hover:outline focus:outline\"\n formControlName=\"operator\">\n @for (data of selectData; track $index) {\n <option [value]=\"data.operator\">{{ 'drawers.' + data.display | transloco }}</option>\n }\n </select>\n <input id=\"title-value\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\" [placeholder]=\"getPlaceholder('title.operator')\" formControlName=\"value\" />\n </div>\n }\n\n <!-- TABS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.inScope' | transloco }}&nbsp;&quot;{{ currentTab() }}&quot;</h1>\n\n <Tabs>\n <TabsList variant=\"ghost\">\n @for (tab of tabs(); track $index) {\n <Tab class=\"w-fit\" [value]=\"tab.path\" [active]=\"tab.path === currentTab()\" (click)=\"onTabChange(tab.path)\">\n {{ tab.display | syslang | transloco }}\n </Tab>\n }\n </TabsList>\n </Tabs>\n\n <!-- FILTERS -->\n <h1 class=\"mt-4 text-xl font-bold\">{{ 'drawers.applyFilters' | transloco }}</h1>\n @for (filter of filters(); track $index) {\n <DropdownInput\n [suggestions]=\"suggestions()\"\n [selected]=\"getItems(filter.column)\"\n [label]=\"filter.display || filter.alias | syslang | transloco\"\n [placeholder]=\"'drawers.startTyping' | transloco\"\n [noResultLabel]=\"'drawers.noResult' | transloco\"\n (onFocus)=\"setFilterFocus($event, filter)\"\n (onKeyUp)=\"onInputTyping($event)\"\n (removeItem)=\"removeItem($event, filter)\"\n (addItem)=\"addItem($event, filter)\" />\n } @empty {\n {{ 'drawers.noFilters' | transloco }}\n }\n </section>\n </div>\n</div>\n", styles: [":host{--drawer-width: 46;--drawer-subdrawer-width: 400px;width:calc(100vw / 100 * var(--drawer-width) + var(--drawer-subdrawer-width));z-index:var(--z-drawer);grid-template-columns:0 1fr var(--drawer-subdrawer-width);transition:right .3s ease-in-out,transform .3s ease-in-out}:host[drawer-opened=true]{right:calc(var(--drawer-subdrawer-width) * -1);box-shadow:var(--drawer-box-shadow)}:host[drawer-extended=true]{width:100vw;right:calc(var(--spacing) * 0);grid-template-columns:1fr calc(var(--drawer-width) * 1%) var(--drawer-subdrawer-width);box-shadow:unset}:is() .dropdown{width:100%}:is() .dropdown-content{width:50%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: DrawerNavbarComponent, selector: "DrawerNavbar, drawernavbar" }, { kind: "component", type: DropdownInputComponent, selector: "dropdown-input, DropdownInput", inputs: ["label", "placeholder", "noResultLabel", "suggestions", "selected"], outputs: ["onFocus", "onKeyUp", "removeItem", "addItem"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "noTruncate", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
11701
11987
  }
11702
11988
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DrawerAdvancedFiltersComponent, decorators: [{
11703
11989
  type: Component,
@@ -12226,7 +12512,7 @@ class AdvancedSearchComponent {
12226
12512
  this.queryText.set("");
12227
12513
  }
12228
12514
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AdvancedSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12229
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AdvancedSearchComponent, isStandalone: true, selector: "advanced-search", inputs: { article: { classPropertyName: "article", publicName: "article", isSignal: true, isRequired: true, transformFunction: null }, previewStrategy: { classPropertyName: "previewStrategy", publicName: "previewStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, providers: [provideTranslocoScope("drawers")], ngImport: i0, template: "@if (article()) {\n <div\n [class]=\"\n cn(\n 'scroll-stable flex flex-col overflow-y-auto pb-6 pl-6 pr-3',\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\n )\n \">\n <section class=\"mb-4 mt-6 flex w-full flex-col gap-6\">\n <header\n id=\"panel-control\"\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\n <div class=\"bg-muted flex grow items-center gap-2 rounded-e-none rounded-s px-3\">\n <input\n id=\"advanced-search-input\"\n type=\"search\"\n class=\"grow focus:outline-none\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\n [ngModel]=\"queryText()\"\n (ngModelChange)=\"queryText.set($event)\"\n (keydown.enter)=\"executeSearch()\" />\n\n @if (queryText() !== '') {\n <button\n variant=\"icon\"\n size=\"xs\"\n [attr.title]=\"'clear' | transloco\"\n [attr.aria-label]=\"'clear' | transloco\"\n (click)=\"clearInput()\"\n (keydown.enter)=\"clearInput()\">\n <i class=\"fa-fw far fa-xmark\"></i>\n </button>\n }\n </div>\n\n <button\n size=\"default\"\n class=\"size-8 rounded-e rounded-s-none\"\n [disabled]=\"queryText() === '' || null\"\n [attr.title]=\"'search' | transloco\"\n [attr.aria-label]=\"'search' | transloco\"\n (click)=\"executeSearch()\">\n <i class=\"fa-fw far fa-magnifying-glass\"></i>\n </button>\n </header>\n </section>\n\n <!-- the same name is used everywhere to simulate an accordion -->\n <!-- extracts -->\n <ExtractsPanel [article]=\"article()\" />\n\n <!-- labels -->\n <LabelsPanel [article]=\"article()\" />\n\n <!-- entities -->\n <EntitiesPanel [article]=\"article()\" />\n\n <!-- similar documents -->\n <SimilarDocumentsPanel [article]=\"article()\" [strategy]=\"previewStrategy()\" (selected)=\"selected.emit($event)\" />\n </div>\n}\n", styles: [":host{--panel-max-height: none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: SimilarDocumentsPanel, selector: "similar-documents-panel, SimilarDocumentsPanel, similardocumentspanel", inputs: ["article", "strategy"], outputs: ["selected"] }, { kind: "component", type: EntitiesPanel, selector: "entities-panel,EntitiesPanel,entitiesPanel", inputs: ["article"] }, { kind: "component", type: LabelsPanel, selector: "labels-panel, LabelsPanel, labelspanel", inputs: ["article"] }, { kind: "component", type: ExtractsPanel, selector: "extracts-panel, ExtractsPanel, extractspanel", inputs: ["article"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
12515
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AdvancedSearchComponent, isStandalone: true, selector: "advanced-search", inputs: { article: { classPropertyName: "article", publicName: "article", isSignal: true, isRequired: true, transformFunction: null }, previewStrategy: { classPropertyName: "previewStrategy", publicName: "previewStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected" }, providers: [provideTranslocoScope("drawers")], ngImport: i0, template: "@if (article()) {\n <div\n [class]=\"\n cn(\n 'scroll-stable flex flex-col overflow-y-auto pb-6 pl-6 pr-3',\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\n )\n \">\n <section class=\"mb-4 mt-6 flex w-full flex-col gap-6\">\n <header\n id=\"panel-control\"\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\n <div class=\"bg-muted flex grow items-center gap-2 rounded-e-none rounded-s px-3\">\n <input\n id=\"advanced-search-input\"\n type=\"search\"\n class=\"grow focus:outline-none\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\n [ngModel]=\"queryText()\"\n (ngModelChange)=\"queryText.set($event)\"\n (keydown.enter)=\"executeSearch()\" />\n\n @if (queryText() !== '') {\n <button\n variant=\"icon\"\n size=\"xs\"\n [attr.title]=\"'clear' | transloco\"\n [attr.aria-label]=\"'clear' | transloco\"\n (click)=\"clearInput()\"\n (keydown.enter)=\"clearInput()\">\n <i class=\"fa-fw far fa-xmark\"></i>\n </button>\n }\n </div>\n\n <button\n size=\"default\"\n class=\"size-8 rounded-e rounded-s-none\"\n [disabled]=\"queryText() === '' || null\"\n [attr.title]=\"'search' | transloco\"\n [attr.aria-label]=\"'search' | transloco\"\n (click)=\"executeSearch()\">\n <i class=\"fa-fw far fa-magnifying-glass\"></i>\n </button>\n </header>\n </section>\n\n <!-- the same name is used everywhere to simulate an accordion -->\n <!-- extracts -->\n <ExtractsPanel [article]=\"article()\" />\n\n <!-- labels -->\n <LabelsPanel [article]=\"article()\" />\n\n <!-- entities -->\n <EntitiesPanel [article]=\"article()\" />\n\n <!-- similar documents -->\n <SimilarDocumentsPanel [article]=\"article()\" [strategy]=\"previewStrategy()\" (selected)=\"selected.emit($event)\" />\n </div>\n}\n", styles: [":host{--panel-max-height: none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: SimilarDocumentsPanel, selector: "similar-documents-panel, SimilarDocumentsPanel, similardocumentspanel", inputs: ["article", "strategy"], outputs: ["selected"] }, { kind: "component", type: EntitiesPanel, selector: "entities-panel,EntitiesPanel,entitiesPanel", inputs: ["article"] }, { kind: "component", type: LabelsPanel, selector: "labels-panel, LabelsPanel, labelspanel", inputs: ["article"] }, { kind: "component", type: ExtractsPanel, selector: "extracts-panel, ExtractsPanel, extractspanel", inputs: ["article"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
12230
12516
  }
12231
12517
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AdvancedSearchComponent, decorators: [{
12232
12518
  type: Component,
@@ -12471,16 +12757,16 @@ class FeedbackDialogComponent {
12471
12757
  }
12472
12758
 
12473
12759
  <DialogFooter>
12474
- <button decoration="outline" (click)="dialog.close()">
12760
+ <button variant="outline" (click)="dialog.close()">
12475
12761
  {{ 'cancel' | transloco }}
12476
12762
  </button>
12477
12763
  <button [disabled]="!comment()" (click)="submit()">
12478
- {{ 'send feedback' | transloco }}
12764
+ {{ 'feedback.button' | transloco }}
12479
12765
  </button>
12480
12766
  </DialogFooter>
12481
12767
  </DialogContent>
12482
12768
  </dialog>
12483
- `, isInline: true, dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
12769
+ `, isInline: true, dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
12484
12770
  }
12485
12771
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FeedbackDialogComponent, decorators: [{
12486
12772
  type: Component,
@@ -12516,11 +12802,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
12516
12802
  }
12517
12803
 
12518
12804
  <DialogFooter>
12519
- <button decoration="outline" (click)="dialog.close()">
12805
+ <button variant="outline" (click)="dialog.close()">
12520
12806
  {{ 'cancel' | transloco }}
12521
12807
  </button>
12522
12808
  <button [disabled]="!comment()" (click)="submit()">
12523
- {{ 'send feedback' | transloco }}
12809
+ {{ 'feedback.button' | transloco }}
12524
12810
  </button>
12525
12811
  </DialogFooter>
12526
12812
  </DialogContent>
@@ -12588,11 +12874,11 @@ class SearchFeedbackComponent {
12588
12874
  this.feedbackDialog()?.open(type);
12589
12875
  }
12590
12876
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SearchFeedbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12591
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SearchFeedbackComponent, isStandalone: true, selector: "feedback, Feedback", inputs: { pages: { classPropertyName: "pages", publicName: "pages", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onClose: "onClose" }, providers: [provideTranslocoScope('feedback')], viewQueries: [{ propertyName: "feedbackDialog", first: true, predicate: FeedbackDialogComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<menu>\n <button class=\"border border-foreground/18\" variant=\"outline\" title=\"{{ 'feedback.button' | transloco }}\">\n <i class=\"fa-fw far fa-commenting\" aria-hidden=\"true\"></i>\n {{ 'feedback.label' | transloco }}\n <i class=\"fa-fw fas fa-xmark ms-2\" (click)=\"close($event)\" aria-hidden=\"true\"></i>\n </button>\n\n <MenuContent>\n @if (!disliked()) {\n <menuitem (click)=\"like()\" [attr.aria-label]=\"'feedback.like' | transloco\">\n @if (liked()) {\n <i class=\"fa-fw fas fa-thumbs-up\"></i> {{ 'feedback.liked' | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-up\"></i> {{ 'feedback.like' | transloco }}\n }\n </menuitem>\n }\n @if (!liked()) {\n <menuitem (click)=\"dislike()\" [attr.aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <i class=\"fa-fw fas fa-thumbs-down\"></i> {{ 'feedback.disliked' | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-down\"></i> {{ 'feedback.dislike' | transloco }}\n }\n </menuitem>\n }\n @for (menu of menus; track $index) {\n <menuitem (click)=\"openFeedbackDialog(menu.type)\" [attr.aria-label]=\"'feedback.' + menu.type + '.title' | transloco\">\n <i class=\"fa-fw {{ menu.icon }}\"></i> {{ 'feedback.' + menu.type + '.title' | transloco }}\n </menuitem>\n }\n </MenuContent>\n</menu>\n\n<feedback-dialog />\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: FeedbackDialogComponent, selector: "feedback-dialog, feedbackdialog, FeedbackDialog", inputs: ["comment"], outputs: ["commentChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
12877
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SearchFeedbackComponent, isStandalone: true, selector: "feedback, Feedback", inputs: { pages: { classPropertyName: "pages", publicName: "pages", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { onClose: "onClose" }, providers: [provideTranslocoScope('feedback')], viewQueries: [{ propertyName: "feedbackDialog", first: true, predicate: FeedbackDialogComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<menu>\n <button\n class=\"border-foreground/18 border\"\n variant=\"outline\"\n title=\"{{ 'feedback.label' | transloco }}\">\n <i class=\"fa-fw far fa-commenting\" aria-hidden=\"true\"></i>\n {{ \"feedback.label\" | transloco }}\n <i\n class=\"fa-fw fas fa-xmark ms-2\"\n (click)=\"close($event)\"\n aria-hidden=\"true\"></i>\n </button>\n\n <MenuContent>\n @if (!disliked()) {\n <menuitem\n (click)=\"like()\"\n [attr.aria-label]=\"'feedback.like' | transloco\">\n @if (liked()) {\n <i class=\"fa-fw fas fa-thumbs-up\"></i>\n {{ \"feedback.liked\" | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-up\"></i>\n {{ \"feedback.like\" | transloco }}\n }\n </menuitem>\n }\n @if (!liked()) {\n <menuitem\n (click)=\"dislike()\"\n [attr.aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <i class=\"fa-fw fas fa-thumbs-down\"></i>\n {{ \"feedback.disliked\" | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-down\"></i>\n {{ \"feedback.dislike\" | transloco }}\n }\n </menuitem>\n }\n @for (menu of menus; track $index) {\n <menuitem\n (click)=\"openFeedbackDialog(menu.type)\"\n [attr.aria-label]=\"'feedback.' + menu.type + '.title' | transloco\">\n <i class=\"fa-fw {{ menu.icon }}\"></i>\n {{ \"feedback.\" + menu.type + \".title\" | transloco }}\n </menuitem>\n }\n </MenuContent>\n</menu>\n\n<feedback-dialog />\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: FeedbackDialogComponent, selector: "feedback-dialog, feedbackdialog, FeedbackDialog", inputs: ["comment"], outputs: ["commentChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
12592
12878
  }
12593
12879
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SearchFeedbackComponent, decorators: [{
12594
12880
  type: Component,
12595
- args: [{ selector: 'feedback, Feedback', standalone: true, imports: [ButtonComponent, MenuComponent, MenuContentComponent, MenuItemComponent, TranslocoPipe, FeedbackDialogComponent], providers: [provideTranslocoScope('feedback')], template: "<menu>\n <button class=\"border border-foreground/18\" variant=\"outline\" title=\"{{ 'feedback.button' | transloco }}\">\n <i class=\"fa-fw far fa-commenting\" aria-hidden=\"true\"></i>\n {{ 'feedback.label' | transloco }}\n <i class=\"fa-fw fas fa-xmark ms-2\" (click)=\"close($event)\" aria-hidden=\"true\"></i>\n </button>\n\n <MenuContent>\n @if (!disliked()) {\n <menuitem (click)=\"like()\" [attr.aria-label]=\"'feedback.like' | transloco\">\n @if (liked()) {\n <i class=\"fa-fw fas fa-thumbs-up\"></i> {{ 'feedback.liked' | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-up\"></i> {{ 'feedback.like' | transloco }}\n }\n </menuitem>\n }\n @if (!liked()) {\n <menuitem (click)=\"dislike()\" [attr.aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <i class=\"fa-fw fas fa-thumbs-down\"></i> {{ 'feedback.disliked' | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-down\"></i> {{ 'feedback.dislike' | transloco }}\n }\n </menuitem>\n }\n @for (menu of menus; track $index) {\n <menuitem (click)=\"openFeedbackDialog(menu.type)\" [attr.aria-label]=\"'feedback.' + menu.type + '.title' | transloco\">\n <i class=\"fa-fw {{ menu.icon }}\"></i> {{ 'feedback.' + menu.type + '.title' | transloco }}\n </menuitem>\n }\n </MenuContent>\n</menu>\n\n<feedback-dialog />\n" }]
12881
+ args: [{ selector: 'feedback, Feedback', standalone: true, imports: [ButtonComponent, MenuComponent, MenuContentComponent, MenuItemComponent, TranslocoPipe, FeedbackDialogComponent], providers: [provideTranslocoScope('feedback')], template: "<menu>\n <button\n class=\"border-foreground/18 border\"\n variant=\"outline\"\n title=\"{{ 'feedback.label' | transloco }}\">\n <i class=\"fa-fw far fa-commenting\" aria-hidden=\"true\"></i>\n {{ \"feedback.label\" | transloco }}\n <i\n class=\"fa-fw fas fa-xmark ms-2\"\n (click)=\"close($event)\"\n aria-hidden=\"true\"></i>\n </button>\n\n <MenuContent>\n @if (!disliked()) {\n <menuitem\n (click)=\"like()\"\n [attr.aria-label]=\"'feedback.like' | transloco\">\n @if (liked()) {\n <i class=\"fa-fw fas fa-thumbs-up\"></i>\n {{ \"feedback.liked\" | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-up\"></i>\n {{ \"feedback.like\" | transloco }}\n }\n </menuitem>\n }\n @if (!liked()) {\n <menuitem\n (click)=\"dislike()\"\n [attr.aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <i class=\"fa-fw fas fa-thumbs-down\"></i>\n {{ \"feedback.disliked\" | transloco }}\n } @else {\n <i class=\"fa-fw far fa-thumbs-down\"></i>\n {{ \"feedback.dislike\" | transloco }}\n }\n </menuitem>\n }\n @for (menu of menus; track $index) {\n <menuitem\n (click)=\"openFeedbackDialog(menu.type)\"\n [attr.aria-label]=\"'feedback.' + menu.type + '.title' | transloco\">\n <i class=\"fa-fw {{ menu.icon }}\"></i>\n {{ \"feedback.\" + menu.type + \".title\" | transloco }}\n </menuitem>\n }\n </MenuContent>\n</menu>\n\n<feedback-dialog />\n" }]
12596
12882
  }], propDecorators: { onClose: [{ type: i0.Output, args: ["onClose"] }], feedbackDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => FeedbackDialogComponent), { isSignal: true }] }], pages: [{ type: i0.Input, args: [{ isSignal: true, alias: "pages", required: true }] }] } });
12597
12883
 
12598
12884
  class AggregationTreeItemComponent {
@@ -12742,6 +13028,8 @@ class AggregationTreeComponent {
12742
13028
  return Number.isNaN(n) ? undefined : n;
12743
13029
  } }]));
12744
13030
  onSelect = output();
13031
+ onApply = output();
13032
+ onClear = output();
12745
13033
  /**
12746
13034
  * Determines whether the aggregation component can be collapsed or expanded.
12747
13035
  * When true, the component will display collapse/expand controls allowing users
@@ -12888,6 +13176,8 @@ class AggregationTreeComponent {
12888
13176
  constructor() {
12889
13177
  this.query = buildQuery();
12890
13178
  effect(() => {
13179
+ // if the aggregation store changes, remove previous session storage
13180
+ getState(this.aggregationsStore);
12891
13181
  sessionStorage.removeItem(`agg-${this.column()}`);
12892
13182
  });
12893
13183
  effect(() => {
@@ -12961,6 +13251,7 @@ class AggregationTreeComponent {
12961
13251
  sessionStorage.removeItem(`agg-${this.aggregation()?.column}`);
12962
13252
  this.selection.set(false);
12963
13253
  this.isAllSelected.set(false);
13254
+ this.onClear.emit();
12964
13255
  }
12965
13256
  }
12966
13257
  /**
@@ -13031,6 +13322,7 @@ class AggregationTreeComponent {
13031
13322
  }
13032
13323
  this.searchText.set("");
13033
13324
  this.selection.set(false);
13325
+ this.onApply.emit();
13034
13326
  }
13035
13327
  loadMore() {
13036
13328
  const q = this.queryParamsStore.getQuery();
@@ -13331,7 +13623,7 @@ class AggregationTreeComponent {
13331
13623
  return false;
13332
13624
  }
13333
13625
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13334
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationTreeComponent, isStandalone: true, selector: "AggregationTree, aggregation-tree, aggregationtree", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", searchText: "searchTextChange" }, host: { properties: { "class": "cn(\"block h-[inherit] max-h-[inherit] w-[inherit]\",class())" } }, viewQueries: [{ propertyName: "virtualItems", predicate: ["virtualItem"], descendants: true, isSignal: true }, { propertyName: "scrollElement", first: true, predicate: ["scrollElement"], descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!aggregation()?.isTree) {\r\n <div class=\"p-2 text-sm text-red-500\">\r\n <i class=\"fa-fw fas fa-triangle-exclamation mr-1\"></i>\r\n The aggregationTree component does not support list aggregations. Please use\r\n the &lt;Aggregation /&gt; component instead.\r\n </div>\r\n}\r\n<details\r\n [attr.open]=\"expanded()\"\r\n [attr.name]=\"id()\"\r\n class=\"group space-y-2\"\r\n (toggle)=\"onToggle($event)\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\r\n [class.text-muted-foreground]=\"isEmpty()\"\r\n class=\"m-0 mt-1 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow truncate\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (showFiltersCount() && filtersCount() > 0) {\r\n <!-- count -->\r\n <Badge size=\"xs\" class=\"ml-1 pb-0.5\">\r\n {{ filtersCount() }}\r\n </Badge>\r\n }\r\n <!-- apply filter block -->\r\n @if (!isCollapsed()) {\r\n <ButtonGroup>\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.clearFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n @if (selection()) {\r\n <button\r\n variant=\"primary\"\r\n size=\"xs\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); apply()\"\r\n class=\"h-4 px-1\">\r\n <FilterIcon class=\"size-4\" />\r\n <span class=\"sr-only\">{{ \"filters.apply\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n <!-- select / unselect all -->\r\n @if (isAllSelected()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.unselectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.unselectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); unselectAll()\">\r\n <i class=\"fa-fw far fa-check-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.unselectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n } @else {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.selectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.selectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); selectAll()\">\r\n <i class=\"fa-fw far fa-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.selectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n </ButtonGroup>\r\n }\r\n\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n @if (aggregation()?.searchable && items().length) {\r\n <InputGroup class=\"group/item mt-1\">\r\n <input\r\n #searchInput\r\n input-group\r\n id=\"aggregation-input-{{ column() }}\"\r\n type=\"text\"\r\n [attr.placeholder]=\"'search' | transloco\"\r\n [(ngModel)]=\"searchText\"\r\n class=\"mt-1\" />\r\n <InputGroupAddon>\r\n <SearchIcon\r\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\r\n </InputGroupAddon>\r\n </InputGroup>\r\n }\r\n\r\n <div\r\n #scrollElement\r\n class=\"scrollbar-thin max-h-[calc(var(--height,100%)-100px)] w-full overflow-auto\">\r\n <div\r\n class=\"relative w-full\"\r\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\r\n role=\"list\"\r\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\r\n <div\r\n class=\"absolute top-0 left-0 w-full\"\r\n [style.transform]=\"\r\n 'translateY(' +\r\n (virtualizer.getVirtualItems()[0]\r\n ? virtualizer.getVirtualItems()[0].start\r\n : 0) +\r\n 'px)'\r\n \"\r\n role=\"listitem\">\r\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\r\n @let item = items()[vItem.index];\r\n <div #virtualItem [attr.data-index]=\"vItem.index\">\r\n <AggregationTreeItem\r\n [node]=\"item\"\r\n [path]=\"[]\"\r\n [field]=\"aggregation()?.column\"\r\n (onSelect)=\"select()\"\r\n (onOpen)=\"open($event)\"\r\n (onFilter)=\"apply()\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (aggregation()?.$hasMore && this.searchedItems().length === 0) {\r\n <button\r\n variant=\"link\"\r\n class=\"mt-1 flex w-full justify-center\"\r\n [attr.aria-label]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore()\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n</details>\r\n", styles: ["AggregationTreeItem:has(+AggregationTreeItem){margin-bottom:var(--agg-item-gap, 0)}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: AggregationTreeItemComponent, selector: "aggregation-tree-item, AggregationTreeItem, aggregationtreeitem", inputs: ["node", "path", "field"], outputs: ["onSelect", "onOpen", "onFilter"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "directive", type: ButtonGroup, selector: "button-group, ButtonGroup", inputs: ["class", "orientation"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "component", type: SearchIcon, selector: "SearchIcon", inputs: ["class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
13626
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationTreeComponent, isStandalone: true, selector: "AggregationTree, aggregation-tree, aggregationtree", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", onApply: "onApply", onClear: "onClear", searchText: "searchTextChange" }, host: { properties: { "class": "cn(\"block h-[inherit] max-h-[inherit] w-[inherit]\",class())" } }, viewQueries: [{ propertyName: "virtualItems", predicate: ["virtualItem"], descendants: true, isSignal: true }, { propertyName: "scrollElement", first: true, predicate: ["scrollElement"], descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!aggregation()?.isTree) {\r\n <div class=\"p-2 text-sm text-red-500\">\r\n <i class=\"fa-fw fas fa-triangle-exclamation mr-1\"></i>\r\n The aggregationTree component does not support list aggregations. Please use\r\n the &lt;Aggregation /&gt; component instead.\r\n </div>\r\n}\r\n<details\r\n [attr.open]=\"expanded()\"\r\n [attr.name]=\"id()\"\r\n class=\"group space-y-2\"\r\n (toggle)=\"onToggle($event)\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\r\n [class.text-muted-foreground]=\"isEmpty()\"\r\n class=\"m-0 mt-1 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow truncate\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (showFiltersCount() && filtersCount() > 0) {\r\n <!-- count -->\r\n <Badge size=\"xs\" class=\"ml-1 pb-0.5\">\r\n {{ filtersCount() }}\r\n </Badge>\r\n }\r\n <!-- apply filter block -->\r\n @if (!isCollapsed()) {\r\n <ButtonGroup>\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.clearFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n @if (selection()) {\r\n <button\r\n variant=\"primary\"\r\n size=\"xs\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); apply()\"\r\n class=\"h-4 px-1\">\r\n <FilterIcon class=\"size-4\" />\r\n <span class=\"sr-only\">{{ \"filters.apply\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n <!-- select / unselect all -->\r\n @if (isAllSelected()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.unselectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.unselectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); unselectAll()\">\r\n <i class=\"fa-fw far fa-check-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.unselectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n } @else {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.selectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.selectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); selectAll()\">\r\n <i class=\"fa-fw far fa-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.selectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n </ButtonGroup>\r\n }\r\n\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n @if (aggregation()?.searchable && items().length) {\r\n <InputGroup class=\"group/item mt-1\">\r\n <input\r\n #searchInput\r\n input-group\r\n id=\"aggregation-input-{{ column() }}\"\r\n type=\"text\"\r\n [attr.placeholder]=\"'search' | transloco\"\r\n [(ngModel)]=\"searchText\"\r\n class=\"mt-1\" />\r\n <InputGroupAddon>\r\n <SearchIcon\r\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\r\n </InputGroupAddon>\r\n </InputGroup>\r\n }\r\n\r\n <div\r\n #scrollElement\r\n class=\"scrollbar-thin max-h-[calc(var(--height,100%)-100px)] w-full overflow-auto\">\r\n <div\r\n class=\"relative w-full\"\r\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\r\n role=\"list\"\r\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\r\n <div\r\n class=\"absolute top-0 left-0 w-full\"\r\n [style.transform]=\"\r\n 'translateY(' +\r\n (virtualizer.getVirtualItems()[0]\r\n ? virtualizer.getVirtualItems()[0].start\r\n : 0) +\r\n 'px)'\r\n \"\r\n role=\"listitem\">\r\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\r\n @let item = items()[vItem.index];\r\n <div #virtualItem [attr.data-index]=\"vItem.index\">\r\n <AggregationTreeItem\r\n [node]=\"item\"\r\n [path]=\"[]\"\r\n [field]=\"aggregation()?.column\"\r\n (onSelect)=\"select()\"\r\n (onOpen)=\"open($event)\"\r\n (onFilter)=\"apply()\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (aggregation()?.$hasMore && this.searchedItems().length === 0) {\r\n <button\r\n variant=\"link\"\r\n class=\"mt-1 flex w-full justify-center\"\r\n [attr.aria-label]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore()\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n</details>\r\n", styles: ["AggregationTreeItem:has(+AggregationTreeItem){margin-bottom:var(--agg-item-gap, 0)}\n"], dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: AggregationTreeItemComponent, selector: "aggregation-tree-item, AggregationTreeItem, aggregationtreeitem", inputs: ["node", "path", "field"], outputs: ["onSelect", "onOpen", "onFilter"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon", inputs: ["class"] }, { kind: "directive", type: ButtonGroup, selector: "button-group, ButtonGroup", inputs: ["class", "orientation"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "component", type: SearchIcon, selector: "SearchIcon", inputs: ["class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
13335
13627
  }
13336
13628
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationTreeComponent, decorators: [{
13337
13629
  type: Component,
@@ -13353,7 +13645,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13353
13645
  ], standalone: true, host: {
13354
13646
  "[class]": 'cn("block h-[inherit] max-h-[inherit] w-[inherit]",class())'
13355
13647
  }, template: "@if (!aggregation()?.isTree) {\r\n <div class=\"p-2 text-sm text-red-500\">\r\n <i class=\"fa-fw fas fa-triangle-exclamation mr-1\"></i>\r\n The aggregationTree component does not support list aggregations. Please use\r\n the &lt;Aggregation /&gt; component instead.\r\n </div>\r\n}\r\n<details\r\n [attr.open]=\"expanded()\"\r\n [attr.name]=\"id()\"\r\n class=\"group space-y-2\"\r\n (toggle)=\"onToggle($event)\">\r\n <summary\r\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\r\n [class.text-muted-foreground]=\"isEmpty()\"\r\n class=\"m-0 mt-1 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\r\n (click)=\"onHeaderClick($event)\">\r\n <ng-content select=\"label\">\r\n @if (aggregation()?.icon) {\r\n <i class=\"fa-fw {{ aggregation()?.icon }} mr-1\" aria-hidden=\"true\"></i>\r\n }\r\n <span class=\"grow truncate\">{{\r\n aggregation()?.display | syslang | transloco\r\n }}</span>\r\n </ng-content>\r\n\r\n @if (showFiltersCount() && filtersCount() > 0) {\r\n <!-- count -->\r\n <Badge size=\"xs\" class=\"ml-1 pb-0.5\">\r\n {{ filtersCount() }}\r\n </Badge>\r\n }\r\n <!-- apply filter block -->\r\n @if (!isCollapsed()) {\r\n <ButtonGroup>\r\n @if (hasFilters()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.clearFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); clear()\">\r\n <i class=\"fa-fw far fa-filter-circle-xmark\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.clearFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n @if (selection()) {\r\n <button\r\n variant=\"primary\"\r\n size=\"xs\"\r\n [attr.title]=\"'filters.applyFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.applyFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); apply()\"\r\n class=\"h-4 px-1\">\r\n <FilterIcon class=\"size-4\" />\r\n <span class=\"sr-only\">{{ \"filters.apply\" | transloco }}</span>\r\n </button>\r\n }\r\n\r\n <!-- select / unselect all -->\r\n @if (isAllSelected()) {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.unselectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.unselectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); unselectAll()\">\r\n <i class=\"fa-fw far fa-check-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.unselectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n } @else {\r\n <button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n class=\"size-6\"\r\n [attr.title]=\"'filters.selectAllFilters' | transloco\"\r\n [attr.aria-label]=\"'filters.selectAllFilters' | transloco\"\r\n (click)=\"$event.stopPropagation(); selectAll()\">\r\n <i class=\"fa-fw far fa-square\"></i>\r\n <span class=\"sr-only\">{{\r\n \"filters.selectAllFilters\" | transloco\r\n }}</span>\r\n </button>\r\n }\r\n </ButtonGroup>\r\n }\r\n\r\n @if (collapsible()) {\r\n <button\r\n variant=\"none\"\r\n title=\"Open/Close\"\r\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\r\n <chevronright />\r\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\r\n </button>\r\n }\r\n </summary>\r\n\r\n <!-- content wrapper -->\r\n @if (aggregation()?.searchable && items().length) {\r\n <InputGroup class=\"group/item mt-1\">\r\n <input\r\n #searchInput\r\n input-group\r\n id=\"aggregation-input-{{ column() }}\"\r\n type=\"text\"\r\n [attr.placeholder]=\"'search' | transloco\"\r\n [(ngModel)]=\"searchText\"\r\n class=\"mt-1\" />\r\n <InputGroupAddon>\r\n <SearchIcon\r\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\r\n </InputGroupAddon>\r\n </InputGroup>\r\n }\r\n\r\n <div\r\n #scrollElement\r\n class=\"scrollbar-thin max-h-[calc(var(--height,100%)-100px)] w-full overflow-auto\">\r\n <div\r\n class=\"relative w-full\"\r\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\r\n role=\"list\"\r\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\r\n <div\r\n class=\"absolute top-0 left-0 w-full\"\r\n [style.transform]=\"\r\n 'translateY(' +\r\n (virtualizer.getVirtualItems()[0]\r\n ? virtualizer.getVirtualItems()[0].start\r\n : 0) +\r\n 'px)'\r\n \"\r\n role=\"listitem\">\r\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\r\n @let item = items()[vItem.index];\r\n <div #virtualItem [attr.data-index]=\"vItem.index\">\r\n <AggregationTreeItem\r\n [node]=\"item\"\r\n [path]=\"[]\"\r\n [field]=\"aggregation()?.column\"\r\n (onSelect)=\"select()\"\r\n (onOpen)=\"open($event)\"\r\n (onFilter)=\"apply()\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n @if (aggregation()?.$hasMore && this.searchedItems().length === 0) {\r\n <button\r\n variant=\"link\"\r\n class=\"mt-1 flex w-full justify-center\"\r\n [attr.aria-label]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore()\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n</details>\r\n", styles: ["AggregationTreeItem:has(+AggregationTreeItem){margin-bottom:var(--agg-item-gap, 0)}\n"] }]
13356
- }], ctorParameters: () => [], propDecorators: { virtualItems: [{ type: i0.ViewChildren, args: ['virtualItem', { isSignal: true }] }], scrollElement: [{ type: i0.ViewChild, args: ["scrollElement", { isSignal: true }] }], searchInput: [{ type: i0.ViewChild, args: ["searchInput", { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], expandedLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedLevel", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }] } });
13648
+ }], ctorParameters: () => [], propDecorators: { virtualItems: [{ type: i0.ViewChildren, args: ['virtualItem', { isSignal: true }] }], scrollElement: [{ type: i0.ViewChild, args: ["scrollElement", { isSignal: true }] }], searchInput: [{ type: i0.ViewChild, args: ["searchInput", { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], expandedLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedLevel", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], onApply: [{ type: i0.Output, args: ["onApply"] }], onClear: [{ type: i0.Output, args: ["onClear"] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }] } });
13357
13649
 
13358
13650
  /**
13359
13651
  * The `AggregationComponent` is responsible for rendering the appropriate aggregation component based on the type of aggregation (date, tree, or list). It uses the `AggregationsService` to retrieve the aggregation data and determines which component to display based on the column type and whether it is a tree structure. The component also provides inputs for configuring its behavior, such as collapsibility, searchability, and showing filter counts.
@@ -13426,6 +13718,8 @@ class AggregationComponent {
13426
13718
  * An output event that emits an array of selected `AggregationItem` objects when the user selects items in the aggregation component. This allows parent components to listen for selection changes and react accordingly, such as applying filters or updating the UI based on the selected items.
13427
13719
  */
13428
13720
  onSelect = output();
13721
+ onApply = output();
13722
+ onClear = output();
13429
13723
  /**
13430
13724
  * A computed property that retrieves the items to be displayed in the aggregation component. It checks for the presence of date, tree, or list aggregation components and returns their respective items. If none of these components are present, it returns an empty array. This allows the component to dynamically display the appropriate items based on the type of aggregation being rendered.
13431
13725
  *
@@ -13465,7 +13759,7 @@ class AggregationComponent {
13465
13759
  return this.appStore.isDateColumn(column);
13466
13760
  }
13467
13761
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13468
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationComponent, isStandalone: true, selector: "Aggregation, aggregation", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { properties: { "class": "cn(\"block h-[inherit] max-h-[inherit]\",class())" } }, viewQueries: [{ propertyName: "aggregationDate", first: true, predicate: AggregationDateComponent, descendants: true, isSignal: true }, { propertyName: "aggregationTree", first: true, predicate: AggregationTreeComponent, descendants: true, isSignal: true }, { propertyName: "aggregationList", first: true, predicate: AggregationListComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
13762
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AggregationComponent, isStandalone: true, selector: "Aggregation, aggregation", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", onApply: "onApply", onClear: "onClear" }, host: { properties: { "class": "cn(\"block h-[inherit] max-h-[inherit]\",class())" } }, viewQueries: [{ propertyName: "aggregationDate", first: true, predicate: AggregationDateComponent, descendants: true, isSignal: true }, { propertyName: "aggregationTree", first: true, predicate: AggregationTreeComponent, descendants: true, isSignal: true }, { propertyName: "aggregationList", first: true, predicate: AggregationListComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
13469
13763
  @if (isDate(aggregation()?.column)) {
13470
13764
  <AggregationDate
13471
13765
  class="max-w-80"
@@ -13477,6 +13771,8 @@ class AggregationComponent {
13477
13771
  [showFiltersCount]="showFiltersCount()"
13478
13772
  [searchable]="searchable()"
13479
13773
  [title]="{ label: 'Date', icon: 'far fa-calendar-day' }"
13774
+ (onApply)="onApply.emit($event)"
13775
+ (onClear)="onClear.emit($event)"
13480
13776
  />
13481
13777
  } @else if (aggregation()?.isTree) {
13482
13778
  <AggregationTree
@@ -13490,6 +13786,8 @@ class AggregationComponent {
13490
13786
  [searchable]="searchable()"
13491
13787
  [expandedLevel]="expandedLevel()"
13492
13788
  (onSelect)="onSelect.emit($event)"
13789
+ (onApply)="onApply.emit($event)"
13790
+ (onClear)="onClear.emit($event)"
13493
13791
  />
13494
13792
  }
13495
13793
  @else {
@@ -13503,9 +13801,11 @@ class AggregationComponent {
13503
13801
  [showFiltersCount]="showFiltersCount()"
13504
13802
  [searchable]="searchable()"
13505
13803
  (onSelect)="onSelect.emit($event)"
13804
+ (onApply)="onApply.emit($event)"
13805
+ (onClear)="onClear.emit($event)"
13506
13806
  />
13507
13807
  }
13508
- `, isInline: true, dependencies: [{ kind: "component", type: AggregationListComponent, selector: "AggregationList, aggregation-list, aggregationlist", inputs: ["class", "id", "name", "column", "collapsible", "collapsed", "searchable", "showFiltersCount", "searchText"], outputs: ["onSelect", "searchTextChange"] }, { kind: "component", type: AggregationTreeComponent, selector: "AggregationTree, aggregation-tree, aggregationtree", inputs: ["class", "id", "name", "column", "expandedLevel", "collapsible", "collapsed", "searchable", "showFiltersCount", "searchText"], outputs: ["onSelect", "searchTextChange"] }, { kind: "component", type: AggregationDateComponent, selector: "aggregation-date, AggregationDate, aggregationdate", inputs: ["title", "displayEmptyDistributionIntervals"] }] });
13808
+ `, isInline: true, dependencies: [{ kind: "component", type: AggregationListComponent, selector: "AggregationList, aggregation-list, aggregationlist", inputs: ["class", "id", "name", "column", "collapsible", "collapsed", "searchable", "showFiltersCount", "searchText"], outputs: ["onSelect", "onApply", "onClear", "searchTextChange"] }, { kind: "component", type: AggregationTreeComponent, selector: "AggregationTree, aggregation-tree, aggregationtree", inputs: ["class", "id", "name", "column", "expandedLevel", "collapsible", "collapsed", "searchable", "showFiltersCount", "searchText"], outputs: ["onSelect", "onApply", "onClear", "searchTextChange"] }, { kind: "component", type: AggregationDateComponent, selector: "aggregation-date, AggregationDate, aggregationdate", inputs: ["title", "displayEmptyDistributionIntervals"] }] });
13509
13809
  }
13510
13810
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AggregationComponent, decorators: [{
13511
13811
  type: Component,
@@ -13524,6 +13824,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13524
13824
  [showFiltersCount]="showFiltersCount()"
13525
13825
  [searchable]="searchable()"
13526
13826
  [title]="{ label: 'Date', icon: 'far fa-calendar-day' }"
13827
+ (onApply)="onApply.emit($event)"
13828
+ (onClear)="onClear.emit($event)"
13527
13829
  />
13528
13830
  } @else if (aggregation()?.isTree) {
13529
13831
  <AggregationTree
@@ -13537,6 +13839,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13537
13839
  [searchable]="searchable()"
13538
13840
  [expandedLevel]="expandedLevel()"
13539
13841
  (onSelect)="onSelect.emit($event)"
13842
+ (onApply)="onApply.emit($event)"
13843
+ (onClear)="onClear.emit($event)"
13540
13844
  />
13541
13845
  }
13542
13846
  @else {
@@ -13550,6 +13854,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13550
13854
  [showFiltersCount]="showFiltersCount()"
13551
13855
  [searchable]="searchable()"
13552
13856
  (onSelect)="onSelect.emit($event)"
13857
+ (onApply)="onApply.emit($event)"
13858
+ (onClear)="onClear.emit($event)"
13553
13859
  />
13554
13860
  }
13555
13861
  `,
@@ -13557,7 +13863,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13557
13863
  "[class]": 'cn("block h-[inherit] max-h-[inherit]",class())'
13558
13864
  }
13559
13865
  }]
13560
- }], propDecorators: { aggregationDate: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationDateComponent), { isSignal: true }] }], aggregationTree: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationTreeComponent), { isSignal: true }] }], aggregationList: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationListComponent), { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], expandedLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedLevel", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
13866
+ }], propDecorators: { aggregationDate: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationDateComponent), { isSignal: true }] }], aggregationTree: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationTreeComponent), { isSignal: true }] }], aggregationList: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationListComponent), { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], expandedLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedLevel", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], onApply: [{ type: i0.Output, args: ["onApply"] }], onClear: [{ type: i0.Output, args: ["onClear"] }] } });
13561
13867
 
13562
13868
  class AsideFiltersComponent {
13563
13869
  cn = cn;
@@ -13584,7 +13890,7 @@ class AsideFiltersComponent {
13584
13890
  <Aggregation id="aside-filters" [name]="agg.name" [column]="agg.column" showFiltersCount />
13585
13891
  }
13586
13892
  </div>
13587
- `, isInline: true, dependencies: [{ kind: "component", type: AggregationComponent, selector: "Aggregation, aggregation", inputs: ["class", "id", "name", "column", "showFiltersCount", "collapsible", "collapsed", "searchable", "expandedLevel"], outputs: ["onSelect"] }] });
13893
+ `, isInline: true, dependencies: [{ kind: "component", type: AggregationComponent, selector: "Aggregation, aggregation", inputs: ["class", "id", "name", "column", "showFiltersCount", "collapsible", "collapsed", "searchable", "expandedLevel"], outputs: ["onSelect", "onApply", "onClear"] }] });
13588
13894
  }
13589
13895
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AsideFiltersComponent, decorators: [{
13590
13896
  type: Component,
@@ -13709,11 +14015,13 @@ class FilterButtonComponent {
13709
14015
  [name]="filter().name"
13710
14016
  [column]="filter().column"
13711
14017
  [expandedLevel]="expandedLevel()"
14018
+ (onApply)="popoverRef()?.close()"
14019
+ (onClear)="popoverRef()?.close()"
13712
14020
  />
13713
14021
  }
13714
14022
  </PopoverContent>
13715
14023
  </Popover>
13716
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: PopoverComponent, selector: "popover, Popover", inputs: ["disabled", "closeOnScroll"], outputs: ["closed"] }, { kind: "directive", type: PopoverContentComponent, selector: "popover-content, PopoverContent, popovercontent", inputs: ["class", "position", "keepOpen", "offset", "strategy"], exportAs: ["popoverContent"] }, { kind: "component", type: AggregationComponent, selector: "Aggregation, aggregation", inputs: ["class", "id", "name", "column", "showFiltersCount", "collapsible", "collapsed", "searchable", "expandedLevel"], outputs: ["onSelect"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: OperatorPipe, name: "operator" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
14024
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: PopoverComponent, selector: "popover, Popover", inputs: ["disabled", "closeOnScroll"], outputs: ["closed"] }, { kind: "directive", type: PopoverContentComponent, selector: "popover-content, PopoverContent, popovercontent", inputs: ["class", "position", "keepOpen", "offset", "strategy"], exportAs: ["popoverContent"] }, { kind: "component", type: AggregationComponent, selector: "Aggregation, aggregation", inputs: ["class", "id", "name", "column", "showFiltersCount", "collapsible", "collapsed", "searchable", "expandedLevel"], outputs: ["onSelect", "onApply", "onClear"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: OperatorPipe, name: "operator" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
13717
14025
  }
13718
14026
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FilterButtonComponent, decorators: [{
13719
14027
  type: Component,
@@ -13774,6 +14082,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
13774
14082
  [name]="filter().name"
13775
14083
  [column]="filter().column"
13776
14084
  [expandedLevel]="expandedLevel()"
14085
+ (onApply)="popoverRef()?.close()"
14086
+ (onClear)="popoverRef()?.close()"
13777
14087
  />
13778
14088
  }
13779
14089
  </PopoverContent>
@@ -13884,7 +14194,7 @@ class MoreComponent {
13884
14194
  [name]="filter.name"
13885
14195
  [column]="filter.column" />
13886
14196
  }
13887
- `, isInline: true, styles: [":host{scrollbar-width:none}\n"], dependencies: [{ kind: "component", type: AggregationComponent, selector: "Aggregation, aggregation", inputs: ["class", "id", "name", "column", "showFiltersCount", "collapsible", "collapsed", "searchable", "expandedLevel"], outputs: ["onSelect"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14197
+ `, isInline: true, styles: [":host{scrollbar-width:none}\n"], dependencies: [{ kind: "component", type: AggregationComponent, selector: "Aggregation, aggregation", inputs: ["class", "id", "name", "column", "showFiltersCount", "collapsible", "collapsed", "searchable", "expandedLevel"], outputs: ["onSelect", "onApply", "onClear"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
13888
14198
  }
13889
14199
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MoreComponent, decorators: [{
13890
14200
  type: Component,
@@ -13950,7 +14260,7 @@ class MoreButtonComponent {
13950
14260
  }
13951
14261
  </PopoverContent>
13952
14262
  </Popover>
13953
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: PopoverComponent, selector: "popover, Popover", inputs: ["disabled", "closeOnScroll"], outputs: ["closed"] }, { kind: "directive", type: PopoverContentComponent, selector: "popover-content, PopoverContent, popovercontent", inputs: ["class", "position", "keepOpen", "offset", "strategy"], exportAs: ["popoverContent"] }, { kind: "component", type: MoreComponent, selector: "more, More", inputs: ["count", "includedFilters", "excludedFilters", "aggregations"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14263
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: PopoverComponent, selector: "popover, Popover", inputs: ["disabled", "closeOnScroll"], outputs: ["closed"] }, { kind: "directive", type: PopoverContentComponent, selector: "popover-content, PopoverContent, popovercontent", inputs: ["class", "position", "keepOpen", "offset", "strategy"], exportAs: ["popoverContent"] }, { kind: "component", type: MoreComponent, selector: "more, More", inputs: ["count", "includedFilters", "excludedFilters", "aggregations"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
13954
14264
  }
13955
14265
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MoreButtonComponent, decorators: [{
13956
14266
  type: Component,
@@ -14162,12 +14472,12 @@ class FiltersBarComponent {
14162
14472
  }
14163
14473
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FiltersBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14164
14474
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: FiltersBarComponent, isStandalone: true, selector: "filters-bar, FiltersBar, filtersbar", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, morePosition: { classPropertyName: "morePosition", publicName: "morePosition", isSignal: true, isRequired: false, transformFunction: null }, aggregations: { classPropertyName: "aggregations", publicName: "aggregations", isSignal: true, isRequired: false, transformFunction: null }, includeFilters: { classPropertyName: "includeFilters", publicName: "includeFilters", isSignal: true, isRequired: false, transformFunction: null }, excludeFilters: { classPropertyName: "excludeFilters", publicName: "excludeFilters", isSignal: true, isRequired: false, transformFunction: null }, filtersCount: { classPropertyName: "filtersCount", publicName: "filtersCount", isSignal: true, isRequired: false, transformFunction: null }, showMoreFiltersButton: { classPropertyName: "showMoreFiltersButton", publicName: "showMoreFiltersButton", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClearFilters: "onClearFilters", onClearBasket: "onClearBasket" }, host: { listeners: { "click": "handleClick($event)" }, properties: { "class": "cn('block relative', class())" } }, providers: [provideTranslocoScope("filters")], viewQueries: [{ propertyName: "moreButtonRef", first: true, predicate: MoreButtonComponent, descendants: true, isSignal: true }, { propertyName: "filterButtonRefs", predicate: FilterButtonComponent, descendants: true, isSignal: true }, { propertyName: "overflowManagerRef", first: true, predicate: OverflowManagerDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
14165
- <ng-container overflowManager [direction]="direction()" [target]="el.nativeElement" (count)="adjustFiltersCount($event)">
14475
+ <div overflowManager [direction]="direction()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
14166
14476
  @if (hasFilters()) {
14167
14477
  <button
14168
14478
  variant="destructive"
14169
14479
  size="icon"
14170
- class="shrink-0"
14480
+ class="shrink-0 size-9"
14171
14481
  role="listitem"
14172
14482
  [title]="'filters.clearAllFilters' | transloco"
14173
14483
  (click)="clearFilters()"
@@ -14179,7 +14489,7 @@ class FiltersBarComponent {
14179
14489
  @if (currentBasket()) {
14180
14490
  <button
14181
14491
  variant="destructive"
14182
- class="max-w-40"
14492
+ class="max-w-40 size-9"
14183
14493
  role="listitem"
14184
14494
  [title]="'filters.clearBasket' | transloco"
14185
14495
  (click)="clearBasket()"
@@ -14191,29 +14501,29 @@ class FiltersBarComponent {
14191
14501
 
14192
14502
  @if (hasAggregations()) {
14193
14503
  <div
14194
- [class]="cn('flex gap-1 h-9 z-filter', BreakpointObserverService.isMobile() && 'flex-wrap', direction() === 'vertical' ? 'flex-col items-start' : 'flex-row')"
14504
+ [class]="cn('flex gap-1 h-9 z-filter flex-1 min-w-0', direction() === 'vertical' ? 'flex-col items-start' : 'flex-row')"
14195
14505
  role="list"
14196
14506
  aria-label="Filters list">
14197
14507
  @for (filter of authorizedFilters(); track filter.name) {
14198
14508
  <FilterButton class="max-w-60" overflowItem [name]="filter.name" [column]="filter.column" [position]="position()" [offset]="offset()" [expandedLevel]="expandedLevel()" />
14199
14509
  }
14200
-
14201
- <!-- More button to show more filters if there are any, it's hidden by default -->
14202
- @if (showMoreFiltersButton()) {
14203
- <MoreButton
14204
- overflowStop
14205
- [class]="cn('invisible absolute', direction() === 'horizontal' ? 'right-0' : 'bottom-0', hasMoreFilters().length > 0 && 'visible')"
14206
- role="listitem"
14207
- [count]="visibleFiltersCount()"
14208
- [position]="morePosition()"
14209
- [includedFilters]="includeFilters()"
14210
- [excludedFilters]="excludeFilters()"
14211
- [aggregations]="aggregations()" />
14212
- }
14213
14510
  </div>
14511
+
14512
+ <!-- Always mounted so the stop position is stable; hidden when all filters fit -->
14513
+ @if (showMoreFiltersButton()) {
14514
+ <MoreButton
14515
+ overflowStop
14516
+ [class]="cn('shrink-0', hasMoreFilters().length === 0 && 'invisible pointer-events-none')"
14517
+ role="listitem"
14518
+ [count]="visibleFiltersCount()"
14519
+ [position]="morePosition()"
14520
+ [includedFilters]="includeFilters()"
14521
+ [excludedFilters]="excludeFilters()"
14522
+ [aggregations]="aggregations()" />
14214
14523
  }
14215
- </ng-container>
14216
- `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: MoreButtonComponent, selector: "more-button, MoreButton", inputs: ["count", "position", "includedFilters", "excludedFilters", "aggregations"] }, { kind: "component", type: FilterButtonComponent, selector: "filter-button, FilterButton", inputs: ["name", "column", "position", "offset", "expandedLevel"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14524
+ }
14525
+ </div>
14526
+ `, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MoreButtonComponent, selector: "more-button, MoreButton", inputs: ["count", "position", "includedFilters", "excludedFilters", "aggregations"] }, { kind: "component", type: FilterButtonComponent, selector: "filter-button, FilterButton", inputs: ["name", "column", "position", "offset", "expandedLevel"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14217
14527
  }
14218
14528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FiltersBarComponent, decorators: [{
14219
14529
  type: Component,
@@ -14231,12 +14541,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
14231
14541
  ],
14232
14542
  providers: [provideTranslocoScope("filters")],
14233
14543
  template: `
14234
- <ng-container overflowManager [direction]="direction()" [target]="el.nativeElement" (count)="adjustFiltersCount($event)">
14544
+ <div overflowManager [direction]="direction()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
14235
14545
  @if (hasFilters()) {
14236
14546
  <button
14237
14547
  variant="destructive"
14238
14548
  size="icon"
14239
- class="shrink-0"
14549
+ class="shrink-0 size-9"
14240
14550
  role="listitem"
14241
14551
  [title]="'filters.clearAllFilters' | transloco"
14242
14552
  (click)="clearFilters()"
@@ -14248,7 +14558,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
14248
14558
  @if (currentBasket()) {
14249
14559
  <button
14250
14560
  variant="destructive"
14251
- class="max-w-40"
14561
+ class="max-w-40 size-9"
14252
14562
  role="listitem"
14253
14563
  [title]="'filters.clearBasket' | transloco"
14254
14564
  (click)="clearBasket()"
@@ -14260,28 +14570,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
14260
14570
 
14261
14571
  @if (hasAggregations()) {
14262
14572
  <div
14263
- [class]="cn('flex gap-1 h-9 z-filter', BreakpointObserverService.isMobile() && 'flex-wrap', direction() === 'vertical' ? 'flex-col items-start' : 'flex-row')"
14573
+ [class]="cn('flex gap-1 h-9 z-filter flex-1 min-w-0', direction() === 'vertical' ? 'flex-col items-start' : 'flex-row')"
14264
14574
  role="list"
14265
14575
  aria-label="Filters list">
14266
14576
  @for (filter of authorizedFilters(); track filter.name) {
14267
14577
  <FilterButton class="max-w-60" overflowItem [name]="filter.name" [column]="filter.column" [position]="position()" [offset]="offset()" [expandedLevel]="expandedLevel()" />
14268
14578
  }
14269
-
14270
- <!-- More button to show more filters if there are any, it's hidden by default -->
14271
- @if (showMoreFiltersButton()) {
14272
- <MoreButton
14273
- overflowStop
14274
- [class]="cn('invisible absolute', direction() === 'horizontal' ? 'right-0' : 'bottom-0', hasMoreFilters().length > 0 && 'visible')"
14275
- role="listitem"
14276
- [count]="visibleFiltersCount()"
14277
- [position]="morePosition()"
14278
- [includedFilters]="includeFilters()"
14279
- [excludedFilters]="excludeFilters()"
14280
- [aggregations]="aggregations()" />
14281
- }
14282
14579
  </div>
14580
+
14581
+ <!-- Always mounted so the stop position is stable; hidden when all filters fit -->
14582
+ @if (showMoreFiltersButton()) {
14583
+ <MoreButton
14584
+ overflowStop
14585
+ [class]="cn('shrink-0', hasMoreFilters().length === 0 && 'invisible pointer-events-none')"
14586
+ role="listitem"
14587
+ [count]="visibleFiltersCount()"
14588
+ [position]="morePosition()"
14589
+ [includedFilters]="includeFilters()"
14590
+ [excludedFilters]="excludeFilters()"
14591
+ [aggregations]="aggregations()" />
14592
+ }
14283
14593
  }
14284
- </ng-container>
14594
+ </div>
14285
14595
  `,
14286
14596
  host: {
14287
14597
  "[class]": "cn('block relative', class())",
@@ -14711,7 +15021,7 @@ class LabelsEditDialog {
14711
15021
  </DialogFooter>
14712
15022
  </DialogContent>
14713
15023
  </dialog>
14714
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "component", type: MultiSelectLabelsComponent, selector: "multiselect-labels, multiselectlabels, MultiSelectLabels", inputs: ["article", "isPublic", "allowModification", "labelsField", "labelInput"], outputs: ["articleChange", "labelInputChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15024
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "component", type: MultiSelectLabelsComponent, selector: "multiselect-labels, multiselectlabels, MultiSelectLabels", inputs: ["article", "isPublic", "allowModification", "labelsField", "labelInput"], outputs: ["articleChange", "labelInputChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14715
15025
  }
14716
15026
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: LabelsEditDialog, decorators: [{
14717
15027
  type: Component,
@@ -14773,14 +15083,14 @@ class SearchFooterComponent {
14773
15083
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SearchFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14774
15084
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SearchFooterComponent, isStandalone: true, selector: "search-footer, searchfooter, SearchFooter", inputs: { hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { loadMore: "loadMore" }, ngImport: i0, template: ` <div class="flex flex-col px-2">
14775
15085
  @if (hasMore() && config().showLoadMore) {
14776
- <button decoration="outline" class="w-full" tabindex="0" [attr.title]="'loadMore' | transloco" (click)="onLoadMore($event)">
15086
+ <button variant="outline" class="w-full" tabindex="0" [attr.title]="'loadMore' | transloco" (click)="onLoadMore($event)">
14777
15087
  {{ 'loadMore' | transloco }}
14778
15088
  </button>
14779
15089
  }
14780
- <button decoration="underline" class="ml-auto" [attr.title]="'seeMore' | transloco" [routerLink]="[config().routerLink]">
15090
+ <button variant="link" class="ml-auto" [attr.title]="'seeMore' | transloco" [routerLink]="[config().routerLink]">
14781
15091
  {{ 'seeMore' | transloco }}
14782
15092
  </button>
14783
- </div>`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15093
+ </div>`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14784
15094
  }
14785
15095
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SearchFooterComponent, decorators: [{
14786
15096
  type: Component,
@@ -14789,11 +15099,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
14789
15099
  imports: [TranslocoPipe, RouterLink, ButtonComponent],
14790
15100
  template: ` <div class="flex flex-col px-2">
14791
15101
  @if (hasMore() && config().showLoadMore) {
14792
- <button decoration="outline" class="w-full" tabindex="0" [attr.title]="'loadMore' | transloco" (click)="onLoadMore($event)">
15102
+ <button variant="outline" class="w-full" tabindex="0" [attr.title]="'loadMore' | transloco" (click)="onLoadMore($event)">
14793
15103
  {{ 'loadMore' | transloco }}
14794
15104
  </button>
14795
15105
  }
14796
- <button decoration="underline" class="ml-auto" [attr.title]="'seeMore' | transloco" [routerLink]="[config().routerLink]">
15106
+ <button variant="link" class="ml-auto" [attr.title]="'seeMore' | transloco" [routerLink]="[config().routerLink]">
14797
15107
  {{ 'seeMore' | transloco }}
14798
15108
  </button>
14799
15109
  </div>`
@@ -14896,7 +15206,7 @@ class SearchListComponent {
14896
15206
  <ng-content />
14897
15207
  </li>
14898
15208
  }
14899
- `, isInline: true, dependencies: [{ kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15209
+ `, isInline: true, dependencies: [{ kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14900
15210
  }
14901
15211
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SearchListComponent, decorators: [{
14902
15212
  type: Component,
@@ -15077,7 +15387,7 @@ class SavedSearchDialog {
15077
15387
  (ngModelChange)="saveName.set($event)" />
15078
15388
 
15079
15389
  <DialogFooter>
15080
- <button decoration="outline" (click)="dialog.close()">
15390
+ <button variant="outline" (click)="dialog.close()">
15081
15391
  {{ 'cancel' | transloco }}
15082
15392
  </button>
15083
15393
  <button (click)="confirm()" [disabled]="!saveName()">
@@ -15086,7 +15396,7 @@ class SavedSearchDialog {
15086
15396
  </DialogFooter>
15087
15397
  </DialogContent>
15088
15398
  </dialog>
15089
- `, isInline: true, dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15399
+ `, isInline: true, dependencies: [{ 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: DialogComponent, selector: "dialog, [dialog]", outputs: ["closed"], exportAs: ["dialog"] }, { kind: "component", type: DialogHeaderComponent, selector: "DialogHeader" }, { kind: "directive", type: DialogTitleComponent, selector: "DialogTitle", inputs: ["class"] }, { kind: "directive", type: DialogContentComponent, selector: "DialogContent", inputs: ["class"] }, { kind: "directive", type: DialogFooterComponent, selector: "DialogFooter", inputs: ["class"] }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15090
15400
  }
15091
15401
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SavedSearchDialog, decorators: [{
15092
15402
  type: Component,
@@ -15122,7 +15432,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15122
15432
  (ngModelChange)="saveName.set($event)" />
15123
15433
 
15124
15434
  <DialogFooter>
15125
- <button decoration="outline" (click)="dialog.close()">
15435
+ <button variant="outline" (click)="dialog.close()">
15126
15436
  {{ 'cancel' | transloco }}
15127
15437
  </button>
15128
15438
  <button (click)="confirm()" [disabled]="!saveName()">
@@ -15216,15 +15526,7 @@ class UserProfileFormComponent {
15216
15526
  }, ...(ngDevMode ? [{ debugName: "keys" }] : []));
15217
15527
  formKeys = computed(() => this.keys().filter(k => k !== "profilePhoto"), ...(ngDevMode ? [{ debugName: "formKeys" }] : []));
15218
15528
  allowProfilePhoto = computed(() => this.keys().some(k => k === "profilePhoto"), ...(ngDevMode ? [{ debugName: "allowProfilePhoto" }] : []));
15219
- initials = computed(() => {
15220
- const fullName = this.userProfile()?.data?.fullName;
15221
- if (!fullName)
15222
- return undefined;
15223
- return fullName
15224
- .split(" ")
15225
- .map((word) => word[0].toUpperCase())
15226
- .join("");
15227
- }, ...(ngDevMode ? [{ debugName: "initials" }] : []));
15529
+ initials = computed(() => this.principalStore.initials(), ...(ngDevMode ? [{ debugName: "initials" }] : []));
15228
15530
  username = computed(() => this.principalStore.name() || this.principalStore.email() || null, ...(ngDevMode ? [{ debugName: "username" }] : []));
15229
15531
  propertyToEdit = signal(undefined, ...(ngDevMode ? [{ debugName: "propertyToEdit" }] : []));
15230
15532
  value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
@@ -15234,17 +15536,13 @@ class UserProfileFormComponent {
15234
15536
  { code: "fr", label: "Français", icon: FlagFrenchIconComponent }
15235
15537
  ];
15236
15538
  changingPassword = signal(false, ...(ngDevMode ? [{ debugName: "changingPassword" }] : []));
15237
- principal = computed(() => this.principalStore.principal?.(), ...(ngDevMode ? [{ debugName: "principal" }] : []));
15238
- customData = computed(() => {
15239
- const customData = this.appStore.general()?.features?.userProfile?.customData;
15240
- const profileKeys = this.userProfile()?.customData;
15241
- return (customData?.length ? customData : (profileKeys ? Object.keys(profileKeys) : []))
15242
- .filter(key => !this.keys().some(k => k.toLowerCase() === key.toLowerCase())); // hide any duplicates in customData keys from data's
15243
- }, ...(ngDevMode ? [{ debugName: "customData" }] : []));
15539
+ customData = computed(() => (this.appStore.general()?.features?.userProfile?.customData || [])
15540
+ .filter(key => !this.keys().some(k => k.toLowerCase() === key.toLowerCase())), ...(ngDevMode ? [{ debugName: "customData" }] : []));
15244
15541
  allowChangePassword = computed(() => {
15245
15542
  const { useCredentials } = globalConfig;
15246
15543
  const { allowChangePassword = false } = this.appStore.general()?.features || {};
15247
- return allowChangePassword && useCredentials && this.principal().editablePartition;
15544
+ const editablePartition = this.principalStore.editablePartition?.() || false;
15545
+ return allowChangePassword && useCredentials && editablePartition;
15248
15546
  }, ...(ngDevMode ? [{ debugName: "allowChangePassword" }] : []));
15249
15547
  constructor() {
15250
15548
  this.currentLanguage.set(this.transloco.getActiveLang());
@@ -15255,26 +15553,31 @@ class UserProfileFormComponent {
15255
15553
  }
15256
15554
  });
15257
15555
  }
15258
- userProfileResource = this.userProfileService.getUserProfile(this.principal);
15556
+ userProfileResource = this.userProfileService.getUserProfile(this.principalStore.userId);
15259
15557
  userProfile = linkedSignal(() => {
15260
15558
  if (this.userProfileResource.hasValue()) {
15261
15559
  return this.userProfileResource.value();
15262
15560
  }
15263
- const { userId: id, email: mail, fullName } = this.principal() || {};
15561
+ const { userId: id, email: mail, fullName } = getState(this.principalStore);
15264
15562
  if (!id || !mail || !fullName) {
15265
15563
  return undefined;
15266
15564
  }
15267
15565
  return { data: { id, mail, fullName } };
15268
15566
  }, ...(ngDevMode ? [{ debugName: "userProfile" }] : []));
15269
15567
  async createUserProfile() {
15270
- const { userId: id, email: mail, fullName } = this.principal() || {};
15568
+ const { userId: id, email: mail, fullName } = getState(this.principalStore);
15271
15569
  if (!id) {
15272
15570
  return;
15273
15571
  }
15274
- const response = await createUserProfile({ data: { id, mail, fullName } });
15275
- if (response) {
15276
- info("Created user profile", response);
15277
- this.userProfileResource.set(response);
15572
+ try {
15573
+ const response = await createUserProfile({ data: { id, mail, fullName } });
15574
+ if (response) {
15575
+ info("Created user profile", response);
15576
+ this.userProfileResource.set(response);
15577
+ }
15578
+ }
15579
+ catch (err) {
15580
+ notify.error(err.message);
15278
15581
  }
15279
15582
  }
15280
15583
  /**
@@ -15286,7 +15589,7 @@ class UserProfileFormComponent {
15286
15589
  onEdit(category, propertyName) {
15287
15590
  const data = this.userProfile()?.[category];
15288
15591
  const value = data?.[propertyName];
15289
- this.value.set(value || "");
15592
+ this.value.set(value?.trim() || "");
15290
15593
  this.propertyToEdit.set(`${category}.${propertyName}`);
15291
15594
  }
15292
15595
  /**
@@ -15296,15 +15599,20 @@ class UserProfileFormComponent {
15296
15599
  * @param propertyName property name
15297
15600
  */
15298
15601
  async onDeleteData(category, propertyName) {
15299
- const response = await deleteUserProfileProperty(this.userProfile(), category, propertyName);
15300
- if (response) {
15301
- info("Deleted user profile property", response);
15302
- const userProfile = JSON.parse(JSON.stringify(this.userProfile()));
15303
- userProfile[category][propertyName] = undefined;
15304
- this.userProfileResource.set(userProfile);
15602
+ try {
15603
+ const response = await deleteUserProfileProperty(this.userProfile(), category, propertyName);
15604
+ if (response) {
15605
+ info("Deleted user profile property", response);
15606
+ const userProfile = JSON.parse(JSON.stringify(this.userProfile()));
15607
+ userProfile[category][propertyName] = undefined;
15608
+ this.userProfileResource.set(userProfile);
15609
+ }
15610
+ else {
15611
+ info("Could not delete user profile property", response);
15612
+ }
15305
15613
  }
15306
- else {
15307
- info("Could not delete user profile property", response);
15614
+ catch (err) {
15615
+ notify.error(err.message);
15308
15616
  }
15309
15617
  }
15310
15618
  /**
@@ -15318,19 +15626,24 @@ class UserProfileFormComponent {
15318
15626
  const userProfile = JSON.parse(JSON.stringify(this.userProfile()));
15319
15627
  if (!userProfile[category])
15320
15628
  userProfile[category] = {};
15321
- userProfile[category][propertyName] = this.value();
15322
- const response = await patchUserProfile(userProfile, category, propertyName);
15323
- if (response) {
15324
- const newUserProfile = this.userProfile();
15325
- this.userProfileResource.set({
15326
- ...newUserProfile,
15327
- ...response,
15328
- data: { ...(newUserProfile?.data || {}), ...(response.data || {}) },
15329
- customData: { ...(newUserProfile?.customData || {}), ...(response.customData || {}) }
15330
- });
15629
+ userProfile[category][propertyName] = this.value()?.trim() || "";
15630
+ try {
15631
+ const response = await patchUserProfile(userProfile, category, propertyName);
15632
+ if (response) {
15633
+ const newUserProfile = this.userProfile();
15634
+ this.userProfileResource.set({
15635
+ ...newUserProfile,
15636
+ ...response,
15637
+ data: { ...(newUserProfile?.data || {}), ...(response.data || {}) },
15638
+ customData: { ...(newUserProfile?.customData || {}), ...(response.customData || {}) }
15639
+ });
15640
+ }
15641
+ this.value.set(undefined);
15642
+ this.propertyToEdit.set(undefined);
15643
+ }
15644
+ catch (err) {
15645
+ notify.error(err.message);
15331
15646
  }
15332
- this.value.set(undefined);
15333
- this.propertyToEdit.set(undefined);
15334
15647
  }
15335
15648
  /**
15336
15649
  * Get the value of a data key
@@ -15374,7 +15687,7 @@ class UserProfileFormComponent {
15374
15687
  }
15375
15688
  }
15376
15689
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UserProfileFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15377
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: UserProfileFormComponent, isStandalone: true, selector: "user-profile-form, UserProfileForm, userprofileform", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, currentLanguage: { classPropertyName: "currentLanguage", publicName: "currentLanguage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", currentLanguage: "currentLanguageChange" }, providers: [provideTranslocoScope("user-profile", "login")], viewQueries: [{ propertyName: "createInputElement", first: true, predicate: ["avatarInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: EditIcon, selector: "edit-icon, EditIcon, editicon", inputs: ["class"] }, { kind: "component", type: UndoIcon, selector: "UndoIcon, undoicon, undo-icon", inputs: ["class"] }, { kind: "component", type: AvatarComponent, selector: "avatar, Avatar", inputs: ["class"] }, { kind: "component", type: AvatarFallbackComponent, selector: "avatar-fallback, avatarfallback, AvatarFallback", inputs: ["class"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: AvatarImageComponent, selector: "avatar-image, AvatarImage, avatarimage", inputs: ["class", "src", "alt", "width", "height", "referrerPolicy", "crossOrigin"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: ChangePasswordComponent, selector: "change-password, ChangePassword, changepassword", inputs: ["username", "alert", "redirectAfterSuccess", "redirectAfterCancel", "currentPassword", "newPassword", "confirmPassword"], outputs: ["success", "cancel", "currentPasswordChange", "newPasswordChange", "confirmPasswordChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15690
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: UserProfileFormComponent, isStandalone: true, selector: "user-profile-form, UserProfileForm, userprofileform", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, currentLanguage: { classPropertyName: "currentLanguage", publicName: "currentLanguage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", currentLanguage: "currentLanguageChange" }, providers: [provideTranslocoScope("user-profile", "login")], viewQueries: [{ propertyName: "createInputElement", first: true, predicate: ["avatarInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive cursor-pointer\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: RouterModule }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: EditIcon, selector: "edit-icon, EditIcon, editicon", inputs: ["class"] }, { kind: "component", type: UndoIcon, selector: "UndoIcon, undoicon, undo-icon", inputs: ["class"] }, { kind: "component", type: AvatarComponent, selector: "avatar, Avatar", inputs: ["class"] }, { kind: "component", type: AvatarFallbackComponent, selector: "avatar-fallback, avatarfallback, AvatarFallback", inputs: ["class"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: AvatarImageComponent, selector: "avatar-image, AvatarImage, avatarimage", inputs: ["class", "src", "alt", "width", "height", "referrerPolicy", "crossOrigin"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: ChangePasswordComponent, selector: "change-password, ChangePassword, changepassword", inputs: ["username", "alert", "redirectAfterSuccess", "redirectAfterCancel", "currentPassword", "newPassword", "confirmPassword"], outputs: ["success", "cancel", "currentPasswordChange", "newPasswordChange", "confirmPasswordChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
15378
15691
  }
15379
15692
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UserProfileFormComponent, decorators: [{
15380
15693
  type: Component,
@@ -15382,7 +15695,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15382
15695
  FormsModule,
15383
15696
  RouterModule,
15384
15697
  TranslocoPipe,
15385
- InputComponent,
15386
15698
  TrashIcon,
15387
15699
  EditIcon,
15388
15700
  UndoIcon,
@@ -15392,7 +15704,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15392
15704
  AvatarImageComponent,
15393
15705
  ButtonComponent,
15394
15706
  ChangePasswordComponent
15395
- ], providers: [provideTranslocoScope("user-profile", "login")], template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n" }]
15707
+ ], providers: [provideTranslocoScope("user-profile", "login")], template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive cursor-pointer\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n" }]
15396
15708
  }], ctorParameters: () => [], propDecorators: { createInputElement: [{ type: i0.ViewChild, args: ["avatarInput", { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], currentLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentLanguage", required: false }] }, { type: i0.Output, args: ["currentLanguageChange"] }] } });
15397
15709
 
15398
15710
  class UserProfileDialog {
@@ -15405,7 +15717,7 @@ class UserProfileDialog {
15405
15717
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UserProfileDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
15406
15718
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: UserProfileDialog, isStandalone: true, selector: "user-profile-dialog, userprofiledialog, UserProfileDialog", providers: [provideTranslocoScope("user-profile")], viewQueries: [{ propertyName: "dialog", first: true, predicate: DialogComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
15407
15719
  <div dialog #dialog="dialog">
15408
- <DialogContent class="max-h-11/12 overflow-auto">
15720
+ <DialogContent class="max-h-11/12 overflow-auto z-60">
15409
15721
  <DialogHeader>
15410
15722
  <DialogTitle>{{ 'userProfile.title' | transloco }}</DialogTitle>
15411
15723
  </DialogHeader>
@@ -15433,7 +15745,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
15433
15745
  providers: [provideTranslocoScope("user-profile")],
15434
15746
  template: `
15435
15747
  <div dialog #dialog="dialog">
15436
- <DialogContent class="max-h-11/12 overflow-auto">
15748
+ <DialogContent class="max-h-11/12 overflow-auto z-60">
15437
15749
  <DialogHeader>
15438
15750
  <DialogTitle>{{ 'userProfile.title' | transloco }}</DialogTitle>
15439
15751
  </DialogHeader>
@@ -15645,5 +15957,5 @@ const queryNameResolver = () => {
15645
15957
  * Generated bundle index. Do not edit.
15646
15958
  */
15647
15959
 
15648
- export { AGGREGATIONS_NAMES, AGGREGATIONS_NAMES_PRESET_DEFAULT, APP_FEATURES, AdvancedFiltersComponent, AdvancedSearch, AdvancedSearchComponent, AggregationComponent, AggregationDateComponent, AggregationListComponent, AggregationTreeComponent, AggregationsService, AggregationsStore, Alert, AlertDialog, AlertsComponent, AppService, AppStore, ApplicationService, ApplicationStore, ArticleEntities, ArticleExtracts, ArticleLabels, ArticleSimilarDocuments, AsideFiltersComponent, AuditFeedbackType, AuditService, AuthGuard, AuthPageComponent, AutocompleteService, BOOKMARKS_CONFIG, BOOKMARKS_OPTIONS, BackdropComponent, BackdropService, BookmarkButtonComponent, BookmarksComponent, COLLECTIONS_CONFIG, COLLECTIONS_OPTIONS, COMPONENTS_FOR_DOCUMENT_TYPE, ChangePasswordComponent, ChildMarkerDirective, CollectionsComponent, CollectionsDialog, DRAWER_COMPONENT, DRAWER_STACK_MAX_COUNT, DateComponent, DeleteCollectionDialog, DidYouMeanComponent, DocumentLocatorComponent, DrawerAdvancedFiltersComponent, DrawerComponent, DrawerNavbarComponent, DrawerPreviewComponent, DrawerService, DrawerStackComponent, DrawerStackService, DropdownInputComponent, DropdownListComponent, ErrorComponent, ExportDialog, ExportService, FILTERS_BREAKPOINT, FILTER_DATE_ALLOW_CUSTOM_RANGE, FeedbackDialogComponent, FileSizePipe, FilterButtonComponent, FiltersBarComponent, HIGHLIGHTS, HighlightWordPipe, InfinityScrollDirective, InlineWorker, JsonMethodPluginService, KeyboardNavigatorDirective, LabelService, LabelsEditDialog, LoadingComponent, MetadataComponent, MissingTermsComponent, MoreButtonComponent, MoreComponent, MultiSelectLabelsComponent, MultiSelectionToolbarComponent, NON_SEARCHABLE_COLUMNS, NON_SEARCHABLE_DEFAULTS, NavbarTabsComponent, NavigationService, NoResultComponent, OpenArticleOnCtrlEnterDirective, OperatorPipe, OverflowItemDirective, OverflowManagerDirective, OverflowStopDirective, OverrideUserDialogComponent, PREVIEW_CONFIG, PagerComponent, PreviewNavigator, PreviewService, PrincipalService, PrincipalStore, QueryParamsStore, QueryService, RECENT_SEARCHES_CONFIG, RECENT_SEARCHES_OPTIONS, ROUTE_COMPONENTS, RecentSearchesComponent, ResetUserSettingsDialogComponent, SAVED_SEARCHES_CONFIG, SAVED_SEARCHES_OPTIONS, SavedSearchDialog, SavedSearchesComponent, SavedSearchesService, SearchFeedbackComponent, SearchInputFooter, SearchService, SelectArticleDirective, SelectArticleOnClickDirective, SelectionHistoryService, SelectionService, SelectionStore, ShowBookmarkDirective, SignInComponent, SortSelectorComponent, SourceComponent, SourceIconPipe, SponsoredResultsComponent, SyslangPipe, THEMES, TextChunkService, ThemeProviderDirective, ThemeSelectorComponent, ThemeStore, ThemeToggleComponent, TranslocoDateImpurePipe, UserProfileDialog, UserProfileFormComponent, UserProfileService, UserSettingsStore, applyThemeToNativeElement, auditInterceptorFn, authInterceptorFn, bodyInterceptorFn, buildQuery, debouncedSignal, errorInterceptorFn, getCurrentPath, getCurrentQueryName, getQueryNameFromRoute, processCssVars, queryNameResolver, signIn, themeColorNameToCssVariable, themeColorsToCssVariables, toastInterceptorFn, withAggregationsFeatures, withAlertsFeatures, withAppFeatures, withApplicationFeatures, withAssistantFeatures, withBasketsFeatures, withBookmarkFeatures, withBootstrapApp, withExtractsFeatures, withFetch, withMultiSelectionFeatures, withPrincipalFeatures, withQueryParamsFeatures, withRecentSearchesFeatures, withSavedSearchesFeatures, withSelectionFeatures, withThemeBodyHook, withThemes, withThemesFeatures, withUserSettingsFeatures };
15960
+ export { AGGREGATIONS_NAMES, AGGREGATIONS_NAMES_PRESET_DEFAULT, APP_FEATURES, AdvancedFiltersComponent, AdvancedSearch, AdvancedSearchComponent, AggregationComponent, AggregationDateComponent, AggregationDateRangeDialogComponent, AggregationListComponent, AggregationTreeComponent, AggregationsService, AggregationsStore, Alert, AlertDialog, AlertsComponent, AppService, AppStore, ApplicationService, ApplicationStore, ArticleEntities, ArticleExtracts, ArticleLabels, ArticleSimilarDocuments, AsideFiltersComponent, AuditFeedbackType, AuditService, AuthGuard, AuthPageComponent, AutocompleteService, BOOKMARKS_CONFIG, BOOKMARKS_OPTIONS, BackdropComponent, BackdropService, BookmarkButtonComponent, BookmarksComponent, COLLECTIONS_CONFIG, COLLECTIONS_OPTIONS, COMPONENTS_FOR_DOCUMENT_TYPE, ChangePasswordComponent, ChildMarkerDirective, CollectionsComponent, CollectionsDialog, DRAWER_COMPONENT, DRAWER_STACK_MAX_COUNT, DateComponent, DeleteCollectionDialog, DidYouMeanComponent, DocumentLocatorComponent, DrawerAdvancedFiltersComponent, DrawerComponent, DrawerNavbarComponent, DrawerPreviewComponent, DrawerService, DrawerStackComponent, DrawerStackService, DropdownInputComponent, DropdownListComponent, ErrorComponent, ExportDialog, ExportService, FILTERS_BREAKPOINT, FILTER_DATE_ALLOW_CUSTOM_RANGE, FeedbackDialogComponent, FileSizePipe, FilterButtonComponent, FiltersBarComponent, HIGHLIGHTS, HighlightWordPipe, InfinityScrollDirective, InlineWorker, JsonMethodPluginService, KeyboardNavigatorDirective, LabelService, LabelsEditDialog, LoadingComponent, MetadataComponent, MissingTermsComponent, MoreButtonComponent, MoreComponent, MultiSelectLabelsComponent, MultiSelectionToolbarComponent, NON_SEARCHABLE_COLUMNS, NON_SEARCHABLE_DEFAULTS, NavbarTabsComponent, NavigationService, NoResultComponent, OpenArticleOnCtrlEnterDirective, OperatorPipe, OverflowItemDirective, OverflowManagerDirective, OverflowStopDirective, OverrideUserDialogComponent, PREVIEW_CONFIG, PagerComponent, PreviewNavigator, PreviewService, PrincipalService, PrincipalStore, QueryParamsStore, QueryService, RECENT_SEARCHES_CONFIG, RECENT_SEARCHES_OPTIONS, ROUTE_COMPONENTS, RecentSearchesComponent, ResetUserSettingsDialogComponent, SAVED_SEARCHES_CONFIG, SAVED_SEARCHES_OPTIONS, SavedSearchDialog, SavedSearchesComponent, SavedSearchesService, SearchFeedbackComponent, SearchInputFooter, SearchService, SelectArticleDirective, SelectArticleOnClickDirective, SelectionHistoryService, SelectionService, SelectionStore, ShowBookmarkDirective, SignInComponent, SortSelectorComponent, SourceComponent, SourceIconPipe, SponsoredResultsComponent, SyslangPipe, THEMES, TextChunkService, ThemeProviderDirective, ThemeSelectorComponent, ThemeStore, ThemeToggleComponent, TranslocoDateImpurePipe, UserProfileDialog, UserProfileFormComponent, UserProfileService, UserSettingsStore, applyThemeToNativeElement, auditInterceptorFn, authInterceptorFn, bodyInterceptorFn, buildQuery, debouncedSignal, errorInterceptorFn, getCurrentPath, getCurrentQueryName, getQueryNameFromRoute, processCssVars, queryNameResolver, signIn, themeColorNameToCssVariable, themeColorsToCssVariables, toastInterceptorFn, withAggregationsFeatures, withAlertsFeatures, withAppFeatures, withApplicationFeatures, withAssistantFeatures, withBasketsFeatures, withBookmarkFeatures, withBootstrapApp, withExtractsFeatures, withFetch, withMultiSelectionFeatures, withPrincipalFeatures, withQueryParamsFeatures, withRecentSearchesFeatures, withSavedSearchesFeatures, withSelectionFeatures, withThemeBodyHook, withThemes, withThemesFeatures, withUserSettingsFeatures };
15649
15961
  //# sourceMappingURL=sinequa-atomic-angular.mjs.map