@sinequa/atomic-angular 1.14.1 → 1.15.0

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.
@@ -3224,7 +3224,9 @@ class QueryService {
3224
3224
  if (allowEmptySearch === false && query?.text === "") {
3225
3225
  warn("QueryService.search: Empty search query is not allowed. Returning empty result.");
3226
3226
  notify.warning(this.transloco.translate("searches.emptySearch"));
3227
- return of({ records: [] });
3227
+ const emptyResult = { records: [] };
3228
+ this.result.set(emptyResult);
3229
+ return of(emptyResult);
3228
3230
  }
3229
3231
  }
3230
3232
  const body = {
@@ -3232,7 +3234,7 @@ class QueryService {
3232
3234
  query,
3233
3235
  $auditRecord
3234
3236
  };
3235
- return this.http.post(`${this.API_URL}/query`, body).pipe(catchError((err) => {
3237
+ return this.http.post(`${this.API_URL}/query`, body).pipe(catchError(err => {
3236
3238
  error("queryService.getResults failure - error: ", err);
3237
3239
  return of({});
3238
3240
  }), map((result) => {
@@ -3251,19 +3253,17 @@ class QueryService {
3251
3253
  }
3252
3254
  });
3253
3255
  return result;
3254
- }), map((result) => {
3256
+ }), map(result => {
3255
3257
  result.records?.map((article) => Object.assign(article, { value: article.title, type: "default" }));
3256
3258
  return result;
3257
- }), map((result) => {
3259
+ }), map(result => {
3258
3260
  const r = {
3259
3261
  ...result,
3260
- nextPage: result.page !== undefined && result.page < Math.ceil(result.rowCount / result.pageSize)
3261
- ? result.page + 1
3262
- : undefined,
3262
+ nextPage: result.page !== undefined && result.page < Math.ceil(result.rowCount / result.pageSize) ? result.page + 1 : undefined,
3263
3263
  previousPage: result.page !== undefined && result.page > 1 ? result.page - 1 : undefined
3264
3264
  };
3265
3265
  return r;
3266
- }), tap((response) => {
3266
+ }), tap(response => {
3267
3267
  this.result.set(response);
3268
3268
  info("queryService.getResults success - data: ", response);
3269
3269
  }));
@@ -3289,10 +3289,10 @@ class QueryService {
3289
3289
  query
3290
3290
  });
3291
3291
  }
3292
- return this.http.post(`${this.API_URL}/multi`, body).pipe(catchError((err) => {
3292
+ return this.http.post(`${this.API_URL}/multi`, body).pipe(catchError(err => {
3293
3293
  error("queryService.bulkSearch failure - error: ", err);
3294
3294
  return EMPTY;
3295
- }), map((response) => {
3295
+ }), map(response => {
3296
3296
  // update $hasMore flag
3297
3297
  response.results.forEach((result) => {
3298
3298
  result.aggregations.forEach((agg) => {
@@ -3310,13 +3310,13 @@ class QueryService {
3310
3310
  });
3311
3311
  });
3312
3312
  return response.results;
3313
- }), map((results) => {
3314
- results.forEach((result) => {
3313
+ }), map(results => {
3314
+ results.forEach(result => {
3315
3315
  result.records?.map((article) => Object.assign(article, { value: article.title, type: "default" }));
3316
3316
  });
3317
3317
  return results;
3318
- }), map((results) => {
3319
- return results.map((result) => {
3318
+ }), map(results => {
3319
+ return results.map(result => {
3320
3320
  const r = {
3321
3321
  ...result,
3322
3322
  nextPage: result.page < Math.ceil(result.rowCount / result.pageSize) ? result.page + 1 : undefined,
@@ -3326,7 +3326,7 @@ class QueryService {
3326
3326
  });
3327
3327
  }),
3328
3328
  // map(response => ResultsSchema.parse(response) as T),
3329
- tap((response) => {
3329
+ tap(response => {
3330
3330
  info("queryService.bulkSearch success - data: ", response);
3331
3331
  }));
3332
3332
  }
@@ -3346,30 +3346,30 @@ class QueryService {
3346
3346
  this.queryParamsStore.patch({ page }, audit);
3347
3347
  }
3348
3348
  /**
3349
- * Get the pages associated to some text locations.
3350
- *
3351
- * @param docs - all documents offsets we want to get the pages from.
3352
- * @returns An Observable that emits the found pages.
3353
- */
3349
+ * Get the pages associated to some text locations.
3350
+ *
3351
+ * @param docs - all documents offsets we want to get the pages from.
3352
+ * @returns An Observable that emits the found pages.
3353
+ */
3354
3354
  getDocPages(docs) {
3355
3355
  const queryName = this.appStore.getDefaultQuery()?.name || "_default";
3356
3356
  const appName = globalConfig.app;
3357
3357
  return this.http.post(`${this.API_V2_URL}/app/${appName}/query/${queryName}/doc-pages`, { docs }).pipe(map(({ items }) => items), catchError(err => {
3358
- error('queryService.getDocPages failure - error: ', err);
3358
+ error("queryService.getDocPages failure - error: ", err);
3359
3359
  return [];
3360
3360
  }));
3361
3361
  }
3362
3362
  /**
3363
- * Get the page associated to a single text location.
3364
- *
3365
- * @param id - the document id.
3366
- * @param offset - offset from the passage location.
3367
- * @param length - length from the passage location.
3368
- * @returns An Observable that emits the found page.
3369
- */
3363
+ * Get the page associated to a single text location.
3364
+ *
3365
+ * @param id - the document id.
3366
+ * @param offset - offset from the passage location.
3367
+ * @param length - length from the passage location.
3368
+ * @returns An Observable that emits the found page.
3369
+ */
3370
3370
  getDocPage(id, offset, length) {
3371
3371
  return this.getDocPages([{ id, textLocations: [{ offset, length }] }]).pipe(map((response) => response[0].pages[0].pageNumber), catchError(err => {
3372
- error('queryService.getDocPage failure - error: ', err);
3372
+ error("queryService.getDocPage failure - error: ", err);
3373
3373
  return [];
3374
3374
  }));
3375
3375
  }
@@ -7872,7 +7872,7 @@ class NavbarTabsComponent {
7872
7872
  // the filter params (f/sort/id/page) already in the URL are kept.
7873
7873
  // - default: 'replace' so everything is rewritten from scratch.
7874
7874
  getQueryParamsHandling() {
7875
- return this.persistFiltersAcrossTabs() ? 'merge' : 'replace';
7875
+ return this.persistFiltersAcrossTabs() ? "merge" : "replace";
7876
7876
  }
7877
7877
  // Get query params conditionally
7878
7878
  getQueryParams(tab) {
@@ -7915,7 +7915,7 @@ class NavbarTabsComponent {
7915
7915
  }
7916
7916
  changeTab() { }
7917
7917
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: NavbarTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7918
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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())" } }, providers: [provideTranslocoScope('navbar-tabs')], ngImport: i0, template: `
7918
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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())" } }, providers: [provideTranslocoScope("navbar-tabs")], ngImport: i0, template: `
7919
7919
  <!-- do not display the tabs if there are no tabs -->
7920
7920
  @if (nav.tabs().length > 0) {
7921
7921
  <div overflowManager (count)="visibleTabCount.set($event)" class="flex items-end rounded-[inherit] bg-inherit">
@@ -7923,8 +7923,7 @@ class NavbarTabsComponent {
7923
7923
  <TabsList class="w-full">
7924
7924
  @for (tab of nav.tabs(); track $index) {
7925
7925
  <Tab
7926
- [class]="cn('group', !noTruncate() && 'basis-[12.5rem]')"
7927
- title="{{ tab.display | syslang | transloco }}"
7926
+ [class]="cn('group', !noTruncate() && 'basis-50')"
7928
7927
  value="{{ tab.display }}"
7929
7928
  overflowItem
7930
7929
  [noTruncate]="noTruncate()"
@@ -8021,7 +8020,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
8021
8020
  EllipsisIcon,
8022
8021
  FaIconComponent
8023
8022
  ],
8024
- providers: [provideTranslocoScope('navbar-tabs')],
8023
+ providers: [provideTranslocoScope("navbar-tabs")],
8025
8024
  template: `
8026
8025
  <!-- do not display the tabs if there are no tabs -->
8027
8026
  @if (nav.tabs().length > 0) {
@@ -8030,8 +8029,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
8030
8029
  <TabsList class="w-full">
8031
8030
  @for (tab of nav.tabs(); track $index) {
8032
8031
  <Tab
8033
- [class]="cn('group', !noTruncate() && 'basis-[12.5rem]')"
8034
- title="{{ tab.display | syslang | transloco }}"
8032
+ [class]="cn('group', !noTruncate() && 'basis-50')"
8035
8033
  value="{{ tab.display }}"
8036
8034
  overflowItem
8037
8035
  [noTruncate]="noTruncate()"
@@ -10136,7 +10134,7 @@ class AggregationDateComponent {
10136
10134
  throw new Error("filters.filterInvalid");
10137
10135
  }
10138
10136
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10139
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: AggregationDateComponent, isStandalone: true, selector: "aggregation-date, AggregationDate, aggregationdate", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", 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 }, syncUrl: { classPropertyName: "syncUrl", publicName: "syncUrl", isSignal: true, isRequired: false, transformFunction: null }, controlledQuery: { classPropertyName: "controlledQuery", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, controlledAggregation: { classPropertyName: "controlledAggregation", publicName: "aggregation", isSignal: true, isRequired: false, transformFunction: null }, controlledSelection: { classPropertyName: "controlledSelection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, emitOn: { classPropertyName: "emitOn", publicName: "emitOn", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, displayEmptyDistributionIntervals: { classPropertyName: "displayEmptyDistributionIntervals", publicName: "displayEmptyDistributionIntervals", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", onApply: "onApply", onClear: "onClear", selectionChange: "selectionChange", filtersChange: "filtersChange", searchText: "searchTextChange" }, host: { properties: { "class": "cn(\"@container block\", isEmpty() && \"hidden\")" } }, providers: [provideTranslocoScope("filters")], viewQueries: [{ propertyName: "dateRangeDialog", first: true, predicate: AggregationDateRangeDialogComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div\n class=\"@container flex grow justify-end gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{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: 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, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "component", type: AggregationDateRangeDialogComponent, selector: "aggregation-date-range-dialog", inputs: ["min", "max", "lang", "useDateRange"], outputs: ["rangeSelected"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size", "solid"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "component", type: FilterXIcon, selector: "filter-x-icon, FilterXIcon", inputs: ["class"] }, { kind: "directive", type: IconButtonComponent, selector: "button[icon-button], icon-button, IconButton", inputs: ["class", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
10137
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: AggregationDateComponent, isStandalone: true, selector: "aggregation-date, AggregationDate, aggregationdate", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", 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 }, syncUrl: { classPropertyName: "syncUrl", publicName: "syncUrl", isSignal: true, isRequired: false, transformFunction: null }, controlledQuery: { classPropertyName: "controlledQuery", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, controlledAggregation: { classPropertyName: "controlledAggregation", publicName: "aggregation", isSignal: true, isRequired: false, transformFunction: null }, controlledSelection: { classPropertyName: "controlledSelection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, emitOn: { classPropertyName: "emitOn", publicName: "emitOn", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, displayEmptyDistributionIntervals: { classPropertyName: "displayEmptyDistributionIntervals", publicName: "displayEmptyDistributionIntervals", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect", onApply: "onApply", onClear: "onClear", selectionChange: "selectionChange", filtersChange: "filtersChange", searchText: "searchTextChange" }, host: { properties: { "class": "cn(\"@container block\", isEmpty() && \"hidden\")" } }, providers: [provideTranslocoScope("filters")], viewQueries: [{ propertyName: "dateRangeDialog", first: true, predicate: AggregationDateRangeDialogComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{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: 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, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "component", type: AggregationDateRangeDialogComponent, selector: "aggregation-date-range-dialog", inputs: ["min", "max", "lang", "useDateRange"], outputs: ["rangeSelected"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size", "solid"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "component", type: FilterXIcon, selector: "filter-x-icon, FilterXIcon", inputs: ["class"] }, { kind: "directive", type: IconButtonComponent, selector: "button[icon-button], icon-button, IconButton", inputs: ["class", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
10140
10138
  }
10141
10139
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationDateComponent, decorators: [{
10142
10140
  type: Component,
@@ -10161,7 +10159,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
10161
10159
  // layout — a date facet has no "empty but resolved" state to gate behind
10162
10160
  // `hideWhenEmpty` (see `isEmpty`), unlike list/tree.
10163
10161
  "[class]": 'cn("@container block", isEmpty() && "hidden")'
10164
- }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div\n class=\"@container flex grow justify-end gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
10162
+ }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
10165
10163
  }], ctorParameters: () => [], propDecorators: { dateRangeDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AggregationDateRangeDialogComponent), { isSignal: true }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", 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 }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], syncUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "syncUrl", required: false }] }], controlledQuery: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }], controlledAggregation: [{ type: i0.Input, args: [{ isSignal: true, alias: "aggregation", required: false }] }], controlledSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], emitOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitOn", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], displayEmptyDistributionIntervals: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayEmptyDistributionIntervals", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], onApply: [{ type: i0.Output, args: ["onApply"] }], onClear: [{ type: i0.Output, args: ["onClear"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], filtersChange: [{ type: i0.Output, args: ["filtersChange"] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }] } });
10166
10164
 
10167
10165
  /**
@@ -10171,7 +10169,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
10171
10169
  */
10172
10170
  class DateComponent extends AggregationDateComponent {
10173
10171
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: DateComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10174
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div\n class=\"@container flex grow justify-end gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: IconButtonComponent, selector: "button[icon-button], icon-button, IconButton", inputs: ["class", "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, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "component", type: AggregationDateRangeDialogComponent, selector: "aggregation-date-range-dialog", inputs: ["min", "max", "lang", "useDateRange"], outputs: ["rangeSelected"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "component", type: FilterXIcon, selector: "filter-x-icon, FilterXIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
10172
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: IconButtonComponent, selector: "button[icon-button], icon-button, IconButton", inputs: ["class", "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, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "component", type: AggregationDateRangeDialogComponent, selector: "aggregation-date-range-dialog", inputs: ["min", "max", "lang", "useDateRange"], outputs: ["rangeSelected"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "component", type: FilterXIcon, selector: "filter-x-icon, FilterXIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
10175
10173
  }
10176
10174
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: DateComponent, decorators: [{
10177
10175
  type: Component,
@@ -10188,7 +10186,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
10188
10186
  FilterXIcon
10189
10187
  ], host: {
10190
10188
  class: "@container"
10191
- }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div\n class=\"@container flex grow justify-end gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
10189
+ }, template: "<details [attr.open]=\"expanded()\" [attr.name]=\"id()\" class=\"group space-y-2\">\n <summary\n [class.cursor-pointer]=\"collapsible()\"\n class=\"m-0 flex h-8 w-full items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (hasFilters()) {\n @let clearLabel = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon />\n </button>\n }\n\n @if (\n (!isControlled() || emitOn() === \"apply\") &&\n selection() &&\n validSelection()\n ) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n @if (collapsible()) {\n <icon-button\n title=\"Open/Close\"\n class=\"cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevronright />\n </icon-button>\n }\n </summary>\n\n <!-- content wrapper -->\n <form [formGroup]=\"form\">\n <ul\n class=\"flex max-h-[var(--scroll-height,20rem)] snap-y snap-start scrollbar-thin flex-col gap-1 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track $index) {\n <li\n role=\"listitem\"\n tabindex=\"0\"\n (click)=\"radio.click()\"\n [attr.aria-label]=\"option.display | syslang | transloco\"\n [class]=\"\n cn(\n 'flex p-0 px-2 leading-7',\n form.get('option')?.value === option.display && 'bg-accent',\n option.hidden && 'hidden',\n option.disabled && 'disabled pointer-events-none text-neutral-300'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <input\n #radio\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-{{ option.display }}\"\n [attr.disabled]=\"option.disabled ? true : null\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"select()\"\n value=\"{{ option.display }}\" />\n\n <label\n for=\"date-filter-{{ option.display }}\"\n class=\"grow cursor-pointer p-1\">\n {{ option.display | syslang | transloco }}\n </label>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n class=\"flex px-2 leading-7\"\n [class.select]=\"form.get('option')?.value === 'custom-range'\">\n <input\n type=\"radio\"\n formControlName=\"option\"\n id=\"date-filter-range-dialog\"\n value=\"custom-range\"\n (click)=\"select()\" />\n <div class=\"@container flex grow gap-1 p-1 @max-[340px]:flex-wrap\">\n <div class=\"flex gap-1\">\n <label for=\"datepicker-range-start\" class=\"min-w-10 truncate\">{{\n \"filters.from\" | transloco\n }}</label>\n <input\n id=\"datepicker-range-start\"\n name=\"start\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n <div class=\"flex gap-1\">\n <label\n for=\"datepicker-range-end\"\n class=\"min-w-10 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input\n id=\"datepicker-range-end\"\n name=\"end\"\n type=\"text\"\n readonly\n class=\"h-8 max-w-[13ch] min-w-[13ch]\"\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\" />\n </div>\n </div>\n </li>\n }\n </ul>\n </form>\n</details>\n\n<aggregation-date-range-dialog\n [lang]=\"lang()\"\n [useDateRange]=\"false\"\n [min]=\"form.get('customRange.from')?.value || undefined\"\n [max]=\"form.get('customRange.to')?.value || undefined\"\n (rangeSelected)=\"onRangeSelected($event)\" />\n", styles: [":host{display:block;min-width:200px}ul[role=list]{scrollbar-width:thin}\n"] }]
10192
10190
  }] });
10193
10191
 
10194
10192
  class ArticleEntities {
@@ -12395,6 +12393,7 @@ const COLLECTIONS_CONFIG = new InjectionToken("Collections options", {
12395
12393
  class CollectionsComponent {
12396
12394
  floating = inject(PopoverComponent, { skipSelf: true, optional: true });
12397
12395
  userSettingsStore = inject(UserSettingsStore);
12396
+ queryParamsStore = inject(QueryParamsStore);
12398
12397
  drawerStack = inject(DrawerStackService);
12399
12398
  router = inject(Router);
12400
12399
  options = input(...(ngDevMode ? [undefined, { debugName: "options" }] : []));
@@ -12414,6 +12413,9 @@ class CollectionsComponent {
12414
12413
  }
12415
12414
  onClick(collection) {
12416
12415
  this.drawerStack.closeAll();
12416
+ // Sync the store before navigating: patchState is synchronous while router.navigate is not,
12417
+ // so the destination /search page must already see the basket when it fires its first query.
12418
+ this.queryParamsStore.patch({ basket: collection.name }, undefined, { syncUrl: false });
12417
12419
  this.router.navigate(["/search"], { queryParams: { b: collection.name } });
12418
12420
  }
12419
12421
  onDelete(collection, index, e) {
@@ -12429,16 +12431,7 @@ class CollectionsComponent {
12429
12431
  }
12430
12432
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: CollectionsComponent, decorators: [{
12431
12433
  type: Component,
12432
- args: [{ selector: "app-collections, collections", standalone: true, imports: [
12433
- TranslocoPipe,
12434
- RouterLink,
12435
- DeleteCollectionDialog,
12436
- ButtonComponent,
12437
- ListItemComponent,
12438
- Separator,
12439
- TrashIcon,
12440
- InboxIcon
12441
- ], 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 <inbox-icon />\r\n\r\n <p class=\"line-clamp-1\">{{ collection.name }}</p>\r\n\r\n <button\r\n variant=\"ghost\"\r\n [iconOnly]=\"true\"\r\n class=\"text-destructive\"\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 <span class=\"py-4 text-center text-neutral-500\">\r\n {{ \"collections.noCollections\" | transloco }}\r\n </span>\r\n }\r\n</ul>\r\n\r\n@if (paginatedCollections().length > 0) {\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=\"primary\"\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}\r\n" }]
12434
+ args: [{ selector: "app-collections, collections", standalone: true, imports: [TranslocoPipe, RouterLink, DeleteCollectionDialog, ButtonComponent, ListItemComponent, Separator, TrashIcon, InboxIcon], 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 <inbox-icon />\r\n\r\n <p class=\"line-clamp-1\">{{ collection.name }}</p>\r\n\r\n <button\r\n variant=\"ghost\"\r\n [iconOnly]=\"true\"\r\n class=\"text-destructive\"\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 <span class=\"py-4 text-center text-neutral-500\">\r\n {{ \"collections.noCollections\" | transloco }}\r\n </span>\r\n }\r\n</ul>\r\n\r\n@if (paginatedCollections().length > 0) {\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=\"primary\"\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}\r\n" }]
12442
12435
  }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], deleteCollectionDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DeleteCollectionDialog), { isSignal: true }] }] } });
12443
12436
 
12444
12437
  /** Static catalog of the known boolean feature flags, with human-readable metadata. */
@@ -13265,25 +13258,23 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13265
13258
  aggregations = signal([], ...(ngDevMode ? [{ debugName: "aggregations" }] : []));
13266
13259
  inputVariant = signal("default", ...(ngDevMode ? [{ debugName: "inputVariant" }] : []));
13267
13260
  tabs = computed(() => {
13268
- const routeData = this.router.config.find((c) => c.path === searchRoute);
13261
+ const routeData = this.router.config.find(c => c.path === searchRoute);
13269
13262
  return !routeData
13270
13263
  ? []
13271
- : [{ path: "all", display: "All" }].concat(routeData
13272
- .children.filter((c) => !!c.path && c.path !== "all" && c.path !== "**")
13273
- .map((c) => ({ path: c.path, display: c.data?.["display"] })));
13264
+ : [{ path: "all", display: "All" }].concat(routeData.children.filter(c => !!c.path && c.path !== "all" && c.path !== "**").map(c => ({ path: c.path, display: c.data?.["display"] })));
13274
13265
  }, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
13275
13266
  filters = computed(() => {
13276
13267
  const cjsonFilters = this.appStore
13277
13268
  .customizationJson()
13278
- .filters?.filter((f) => f.column !== "#date")
13279
- .map((f) => ({
13269
+ .filters?.filter(f => f.column !== "#date")
13270
+ .map(f => ({
13280
13271
  column: f.column,
13281
13272
  alias: this.appStore.getColumnAlias(f.column),
13282
13273
  display: f.display,
13283
- items: this.aggregations()?.find((a) => a.column === f.column)?.items
13274
+ items: this.aggregations()?.find(a => a.column === f.column)?.items
13284
13275
  })) || [];
13285
13276
  const agg = this.aggregations()
13286
- .filter((f) => !cjsonFilters.some((cf) => cf.column === f.column))
13277
+ .filter(f => !cjsonFilters.some(cf => cf.column === f.column))
13287
13278
  .map((f) => ({
13288
13279
  column: f.column,
13289
13280
  alias: this.appStore.getColumnAlias(f.column),
@@ -13352,7 +13343,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13352
13343
  }
13353
13344
  this.queryParamsStore.patch({ text });
13354
13345
  const filters = [];
13355
- this.appliedFilters().forEach((filter) => {
13346
+ this.appliedFilters().forEach(filter => {
13356
13347
  if (filter.values.length) {
13357
13348
  // todo should handle dates? how?
13358
13349
  /* if (filter.column.startsWith('modified') || filter.column.startsWith('date')) {
@@ -13370,7 +13361,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13370
13361
  });
13371
13362
  this.queryParamsStore.clearFilters();
13372
13363
  if (filters.length) {
13373
- filters.forEach((filter) => {
13364
+ filters.forEach(filter => {
13374
13365
  this.queryParamsStore.updateFilter(filter);
13375
13366
  });
13376
13367
  }
@@ -13388,10 +13379,10 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13388
13379
  const display = values[0].display;
13389
13380
  if (this.appStore.isDateColumn(field)) {
13390
13381
  // dates
13391
- const agg = this.aggregations().find((a) => a.column === field);
13382
+ const agg = this.aggregations().find(a => a.column === field);
13392
13383
  if (agg) {
13393
13384
  const options = translateAggregationToDateOptions(agg, false);
13394
- const option = options.find((o) => !!o.display && value.indexOf(o.display) !== -1);
13385
+ const option = options.find(o => !!o.display && value.indexOf(o.display) !== -1);
13395
13386
  if (option)
13396
13387
  return [
13397
13388
  {
@@ -13409,11 +13400,11 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13409
13400
  return [{ operator: op, value, field: f }];
13410
13401
  }
13411
13402
  else {
13412
- const agg = this.aggregations().find((a) => a.column === field);
13403
+ const agg = this.aggregations().find(a => a.column === field);
13413
13404
  // if AggregationItem
13414
13405
  if (!!value.match(aggItemRegex)?.[1] && !!agg) {
13415
- const items = agg.items.filter((item) => values.some((v) => item.value === v.value));
13416
- const filters = items.map((item) => parseValueAndOperatorFromItem(item, field));
13406
+ const items = agg.items.filter(item => values.some(v => item.value === v.value));
13407
+ const filters = items.map(item => parseValueAndOperatorFromItem(item, field));
13417
13408
  return [
13418
13409
  {
13419
13410
  operator: "or",
@@ -13431,10 +13422,10 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13431
13422
  {
13432
13423
  operator,
13433
13424
  name: agg?.name,
13434
- values: values.map((v) => v.value),
13425
+ values: values.map(v => v.value),
13435
13426
  field,
13436
13427
  display: display || value,
13437
- filters: values.map((v) => ({
13428
+ filters: values.map(v => ({
13438
13429
  operator: "contains",
13439
13430
  name: agg?.name,
13440
13431
  field,
@@ -13463,7 +13454,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13463
13454
  // value can be separated by AND or OR keywords, if it's the case each words must be written field:word1 AND field:word2 etc...
13464
13455
  const words = value.split(/\s+(AND|OR)\s+/);
13465
13456
  return words
13466
- .map((w) => {
13457
+ .map(w => {
13467
13458
  if (w === "AND" || w === "OR")
13468
13459
  return w;
13469
13460
  return `(${fieldStr}${w})`;
@@ -13472,7 +13463,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13472
13463
  }
13473
13464
  case "any": {
13474
13465
  const splitWords = value.split(" ");
13475
- return `(${splitWords.map((w) => `${fieldStr}[${w}]`).join(" OR ")})`;
13466
+ return `(${splitWords.map(w => `${fieldStr}[${w}]`).join(" OR ")})`;
13476
13467
  }
13477
13468
  case "none":
13478
13469
  return `${fieldStr}NOT [${value}]`;
@@ -13481,20 +13472,19 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13481
13472
  }
13482
13473
  }
13483
13474
  getPlaceholder(key) {
13484
- return (this.selectData.find((d) => d.operator === this.form.get(key)?.value)?.placeholder ||
13485
- this.transloco.translate("drawers.searchWords"));
13475
+ return this.selectData.find(d => d.operator === this.form.get(key)?.value)?.placeholder || this.transloco.translate("drawers.searchWords");
13486
13476
  }
13487
13477
  /** Get applied filters for a column */
13488
13478
  getItems(column) {
13489
- return this.appliedFilters().find((f) => f.column === column)?.values || [];
13479
+ return this.appliedFilters().find(f => f.column === column)?.values || [];
13490
13480
  }
13491
13481
  /** add item to current selection */
13492
13482
  addItem(item, filter) {
13493
- const appliedFilter = this.appliedFilters().find((af) => af.column === filter.column);
13483
+ const appliedFilter = this.appliedFilters().find(af => af.column === filter.column);
13494
13484
  if (!appliedFilter) {
13495
13485
  this.appliedFilters.set(this.appliedFilters().concat([{ column: filter.column, values: [item] }]));
13496
13486
  }
13497
- else if (!appliedFilter.values.some((v) => v.value === item.value)) {
13487
+ else if (!appliedFilter.values.some(v => v.value === item.value)) {
13498
13488
  if (this.appStore.isDateColumn(filter.column)) {
13499
13489
  appliedFilter.values = [item]; // only one item for date filters
13500
13490
  }
@@ -13505,9 +13495,9 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13505
13495
  }
13506
13496
  /** remove item from current selection */
13507
13497
  removeItem(item, filter) {
13508
- const appliedFilter = this.appliedFilters().find((af) => af.column === filter.column);
13498
+ const appliedFilter = this.appliedFilters().find(af => af.column === filter.column);
13509
13499
  if (appliedFilter) {
13510
- appliedFilter.values = appliedFilter.values.filter((v) => v.value !== item.value);
13500
+ appliedFilter.values = appliedFilter.values.filter(v => v.value !== item.value);
13511
13501
  }
13512
13502
  }
13513
13503
  /** Update suggestions on input focus */
@@ -13521,23 +13511,22 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13521
13511
  }
13522
13512
  setSuggestions(value) {
13523
13513
  this.suggestions.set([]);
13524
- const filter = this.filters().find((f) => f.column === this.currentFilter());
13514
+ const filter = this.filters().find(f => f.column === this.currentFilter());
13525
13515
  if (!!value && !!filter && filter.items?.length) {
13526
- this.suggestions.set(this.getSuggestionItems(value.toLowerCase(), filter.items).map((i) => ({
13516
+ this.suggestions.set(this.getSuggestionItems(value.toLowerCase(), filter.items).map(i => ({
13527
13517
  display: i.display || String(i.value),
13528
13518
  value: String(filter.column === "treepath" ? `/${i.$path || i.value}/*` : i.value)
13529
13519
  })));
13530
13520
  }
13531
13521
  }
13532
13522
  getSuggestionItems(value, items) {
13533
- const res = items.filter((i) => (!!i.display && i.display.toLowerCase().indexOf(value) !== -1) ||
13534
- String(i.value).toLowerCase().indexOf(value) !== -1);
13523
+ const res = items.filter(i => (!!i.display && i.display.toLowerCase().indexOf(value) !== -1) || String(i.value).toLowerCase().indexOf(value) !== -1);
13535
13524
  // todo handle tree items
13536
13525
  return res;
13537
13526
  }
13538
13527
  getWithSubItems(items) {
13539
13528
  const res = [...items];
13540
- items.forEach((item) => {
13529
+ items.forEach(item => {
13541
13530
  if (item.hasChildren && item.items?.length) {
13542
13531
  res.push(...this.getWithSubItems(item.items));
13543
13532
  }
@@ -13545,7 +13534,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
13545
13534
  return res;
13546
13535
  }
13547
13536
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: DrawerAdvancedFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13548
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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}\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", "solid"] }, { 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" }] });
13537
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: DrawerAdvancedFiltersComponent, isStandalone: true, selector: "advanced-filters", host: { attributes: { "data-legacy": "" }, 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}\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", "solid"] }, { 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" }] });
13549
13538
  }
13550
13539
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: DrawerAdvancedFiltersComponent, decorators: [{
13551
13540
  type: Component,
@@ -13561,7 +13550,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
13561
13550
  TabComponent,
13562
13551
  TabsListComponent
13563
13552
  ], providers: [DrawerService, SyslangPipe, TranslocoPipe, provideTranslocoScope("drawers")], host: {
13564
- class: "fixed bg-background grid h-full top-0 -right-full justify-end"
13553
+ class: "fixed bg-background grid h-full top-0 -right-full justify-end",
13554
+ "data-legacy": ""
13565
13555
  }, 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}\n"] }]
13566
13556
  }], ctorParameters: () => [] });
13567
13557
 
@@ -14053,7 +14043,7 @@ class AdvancedSearchComponent {
14053
14043
  const { queryText } = getState(this.selectionStore);
14054
14044
  return queryText;
14055
14045
  },
14056
- computation: (queryText) => {
14046
+ computation: queryText => {
14057
14047
  const text = queryText || "";
14058
14048
  return text ? text.trim() : "";
14059
14049
  } }] : [{
@@ -14061,7 +14051,7 @@ class AdvancedSearchComponent {
14061
14051
  const { queryText } = getState(this.selectionStore);
14062
14052
  return queryText;
14063
14053
  },
14064
- computation: (queryText) => {
14054
+ computation: queryText => {
14065
14055
  const text = queryText || "";
14066
14056
  return text ? text.trim() : "";
14067
14057
  }
@@ -14074,21 +14064,13 @@ class AdvancedSearchComponent {
14074
14064
  this.queryText.set("");
14075
14065
  }
14076
14066
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AdvancedSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
14077
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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()) {\r\n <div\r\n [class]=\"\r\n cn(\r\n 'scroll-stable flex flex-col overflow-y-auto pr-3 pb-6 pl-6',\r\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\r\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\r\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\r\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\r\n )\r\n \">\r\n <section class=\"mt-6 mb-4 flex w-full flex-col gap-6\">\r\n <header\r\n id=\"panel-control\"\r\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\r\n <div\r\n class=\"bg-muted flex grow items-center gap-2 rounded-s rounded-e-none px-3\">\r\n <input\r\n id=\"advanced-search-input\"\r\n type=\"search\"\r\n class=\"grow focus:outline-none\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\r\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\r\n [ngModel]=\"queryText()\"\r\n (ngModelChange)=\"queryText.set($event)\"\r\n (keydown.enter)=\"executeSearch()\" />\r\n\r\n @if (queryText() !== \"\") {\r\n <button\r\n [iconOnly]=\"true\"\r\n size=\"sm\"\r\n [attr.title]=\"'clear' | transloco\"\r\n [attr.aria-label]=\"'clear' | transloco\"\r\n (click)=\"clearInput()\"\r\n (keydown.enter)=\"clearInput()\">\r\n <xmark-icon />\r\n </button>\r\n }\r\n </div>\r\n\r\n <button\r\n class=\"size-8 rounded-s-none rounded-e-lg\"\r\n [disabled]=\"queryText() === '' || null\"\r\n [attr.title]=\"'search' | transloco\"\r\n [attr.aria-label]=\"'search' | transloco\"\r\n (click)=\"executeSearch()\">\r\n <magnifying-glass-icon />\r\n </button>\r\n </header>\r\n </section>\r\n\r\n <!-- the same name is used everywhere to simulate an accordion -->\r\n <!-- extracts -->\r\n <ExtractsPanel [article]=\"article()\" />\r\n\r\n <!-- labels -->\r\n <LabelsPanel [article]=\"article()\" />\r\n\r\n <!-- entities -->\r\n <EntitiesPanel [article]=\"article()\" />\r\n\r\n <!-- similar documents -->\r\n <SimilarDocumentsPanel\r\n [article]=\"article()\"\r\n [strategy]=\"previewStrategy()\"\r\n (selected)=\"selected.emit($event)\" />\r\n </div>\r\n}\r\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", "solid"] }, { 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: "component", type: XMarkIcon, selector: "XMarkIcon, xmark-icon, x-mark-icon", inputs: ["class"] }, { kind: "component", type: MagnifyingGlassIcon, selector: "magnifying-glass-icon, MagnifyingGlassIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14067
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", 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" }, host: { attributes: { "data-legacy": "" } }, providers: [provideTranslocoScope("drawers")], ngImport: i0, template: "@if (article()) {\r\n <div\r\n [class]=\"\r\n cn(\r\n 'scroll-stable flex flex-col overflow-y-auto pr-3 pb-6 pl-6',\r\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\r\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\r\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\r\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\r\n )\r\n \">\r\n <section class=\"mt-6 mb-4 flex w-full flex-col gap-6\">\r\n <header\r\n id=\"panel-control\"\r\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\r\n <div\r\n class=\"bg-muted flex grow items-center gap-2 rounded-s rounded-e-none px-3\">\r\n <input\r\n id=\"advanced-search-input\"\r\n type=\"search\"\r\n class=\"grow focus:outline-none\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\r\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\r\n [ngModel]=\"queryText()\"\r\n (ngModelChange)=\"queryText.set($event)\"\r\n (keydown.enter)=\"executeSearch()\" />\r\n\r\n @if (queryText() !== \"\") {\r\n <button\r\n [iconOnly]=\"true\"\r\n size=\"sm\"\r\n [attr.title]=\"'clear' | transloco\"\r\n [attr.aria-label]=\"'clear' | transloco\"\r\n (click)=\"clearInput()\"\r\n (keydown.enter)=\"clearInput()\">\r\n <xmark-icon />\r\n </button>\r\n }\r\n </div>\r\n\r\n <button\r\n class=\"size-8 rounded-s-none rounded-e-lg\"\r\n [disabled]=\"queryText() === '' || null\"\r\n [attr.title]=\"'search' | transloco\"\r\n [attr.aria-label]=\"'search' | transloco\"\r\n (click)=\"executeSearch()\">\r\n <magnifying-glass-icon />\r\n </button>\r\n </header>\r\n </section>\r\n\r\n <!-- the same name is used everywhere to simulate an accordion -->\r\n <!-- extracts -->\r\n <ExtractsPanel [article]=\"article()\" />\r\n\r\n <!-- labels -->\r\n <LabelsPanel [article]=\"article()\" />\r\n\r\n <!-- entities -->\r\n <EntitiesPanel [article]=\"article()\" />\r\n\r\n <!-- similar documents -->\r\n <SimilarDocumentsPanel\r\n [article]=\"article()\"\r\n [strategy]=\"previewStrategy()\"\r\n (selected)=\"selected.emit($event)\" />\r\n </div>\r\n}\r\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", "solid"] }, { 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: "component", type: XMarkIcon, selector: "XMarkIcon, xmark-icon, x-mark-icon", inputs: ["class"] }, { kind: "component", type: MagnifyingGlassIcon, selector: "magnifying-glass-icon, MagnifyingGlassIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
14078
14068
  }
14079
14069
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AdvancedSearchComponent, decorators: [{
14080
14070
  type: Component,
14081
- args: [{ selector: "advanced-search", standalone: true, providers: [provideTranslocoScope("drawers")], imports: [
14082
- FormsModule,
14083
- ButtonComponent,
14084
- TranslocoPipe,
14085
- SimilarDocumentsPanel,
14086
- EntitiesPanel,
14087
- LabelsPanel,
14088
- ExtractsPanel,
14089
- XMarkIcon,
14090
- MagnifyingGlassIcon
14091
- ], template: "@if (article()) {\r\n <div\r\n [class]=\"\r\n cn(\r\n 'scroll-stable flex flex-col overflow-y-auto pr-3 pb-6 pl-6',\r\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\r\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\r\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\r\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\r\n )\r\n \">\r\n <section class=\"mt-6 mb-4 flex w-full flex-col gap-6\">\r\n <header\r\n id=\"panel-control\"\r\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\r\n <div\r\n class=\"bg-muted flex grow items-center gap-2 rounded-s rounded-e-none px-3\">\r\n <input\r\n id=\"advanced-search-input\"\r\n type=\"search\"\r\n class=\"grow focus:outline-none\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\r\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\r\n [ngModel]=\"queryText()\"\r\n (ngModelChange)=\"queryText.set($event)\"\r\n (keydown.enter)=\"executeSearch()\" />\r\n\r\n @if (queryText() !== \"\") {\r\n <button\r\n [iconOnly]=\"true\"\r\n size=\"sm\"\r\n [attr.title]=\"'clear' | transloco\"\r\n [attr.aria-label]=\"'clear' | transloco\"\r\n (click)=\"clearInput()\"\r\n (keydown.enter)=\"clearInput()\">\r\n <xmark-icon />\r\n </button>\r\n }\r\n </div>\r\n\r\n <button\r\n class=\"size-8 rounded-s-none rounded-e-lg\"\r\n [disabled]=\"queryText() === '' || null\"\r\n [attr.title]=\"'search' | transloco\"\r\n [attr.aria-label]=\"'search' | transloco\"\r\n (click)=\"executeSearch()\">\r\n <magnifying-glass-icon />\r\n </button>\r\n </header>\r\n </section>\r\n\r\n <!-- the same name is used everywhere to simulate an accordion -->\r\n <!-- extracts -->\r\n <ExtractsPanel [article]=\"article()\" />\r\n\r\n <!-- labels -->\r\n <LabelsPanel [article]=\"article()\" />\r\n\r\n <!-- entities -->\r\n <EntitiesPanel [article]=\"article()\" />\r\n\r\n <!-- similar documents -->\r\n <SimilarDocumentsPanel\r\n [article]=\"article()\"\r\n [strategy]=\"previewStrategy()\"\r\n (selected)=\"selected.emit($event)\" />\r\n </div>\r\n}\r\n", styles: [":host{--panel-max-height: none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"] }]
14071
+ args: [{ selector: "advanced-search", standalone: true, providers: [provideTranslocoScope("drawers")], imports: [FormsModule, ButtonComponent, TranslocoPipe, SimilarDocumentsPanel, EntitiesPanel, LabelsPanel, ExtractsPanel, XMarkIcon, MagnifyingGlassIcon], host: {
14072
+ "data-legacy": ""
14073
+ }, template: "@if (article()) {\r\n <div\r\n [class]=\"\r\n cn(\r\n 'scroll-stable flex flex-col overflow-y-auto pr-3 pb-6 pl-6',\r\n '[&_details]:border-muted-foreground/18 [&_details]:border-b',\r\n '[&_details>summary]:bg-menu [&_details_details]:last:border-b-0',\r\n '[&_details>summary>i>svg]:transition-transform [&_details>summary>i>svg]:duration-300',\r\n '[&>details>summary>i>svg]:group-open/parent:rotate-180'\r\n )\r\n \">\r\n <section class=\"mt-6 mb-4 flex w-full flex-col gap-6\">\r\n <header\r\n id=\"panel-control\"\r\n class=\"focus-within:outline-primary not-focus-within:hover:outline-muted-foreground group flex rounded focus-within:outline hover:outline\">\r\n <div\r\n class=\"bg-muted flex grow items-center gap-2 rounded-s rounded-e-none px-3\">\r\n <input\r\n id=\"advanced-search-input\"\r\n type=\"search\"\r\n class=\"grow focus:outline-none\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n [attr.placeholder]=\"'drawers.inputPlaceholder' | transloco\"\r\n [attr.aria-label]=\"'drawers.inputPlaceholder' | transloco\"\r\n [ngModel]=\"queryText()\"\r\n (ngModelChange)=\"queryText.set($event)\"\r\n (keydown.enter)=\"executeSearch()\" />\r\n\r\n @if (queryText() !== \"\") {\r\n <button\r\n [iconOnly]=\"true\"\r\n size=\"sm\"\r\n [attr.title]=\"'clear' | transloco\"\r\n [attr.aria-label]=\"'clear' | transloco\"\r\n (click)=\"clearInput()\"\r\n (keydown.enter)=\"clearInput()\">\r\n <xmark-icon />\r\n </button>\r\n }\r\n </div>\r\n\r\n <button\r\n class=\"size-8 rounded-s-none rounded-e-lg\"\r\n [disabled]=\"queryText() === '' || null\"\r\n [attr.title]=\"'search' | transloco\"\r\n [attr.aria-label]=\"'search' | transloco\"\r\n (click)=\"executeSearch()\">\r\n <magnifying-glass-icon />\r\n </button>\r\n </header>\r\n </section>\r\n\r\n <!-- the same name is used everywhere to simulate an accordion -->\r\n <!-- extracts -->\r\n <ExtractsPanel [article]=\"article()\" />\r\n\r\n <!-- labels -->\r\n <LabelsPanel [article]=\"article()\" />\r\n\r\n <!-- entities -->\r\n <EntitiesPanel [article]=\"article()\" />\r\n\r\n <!-- similar documents -->\r\n <SimilarDocumentsPanel\r\n [article]=\"article()\"\r\n [strategy]=\"previewStrategy()\"\r\n (selected)=\"selected.emit($event)\" />\r\n </div>\r\n}\r\n", styles: [":host{--panel-max-height: none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"] }]
14092
14074
  }], propDecorators: { article: [{ type: i0.Input, args: [{ isSignal: true, alias: "article", required: true }] }], previewStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewStrategy", required: false }] }], selected: [{ type: i0.Output, args: ["selected"] }] } });
14093
14075
 
14094
14076
  const COMPONENTS_FOR_DOCUMENT_TYPE = new InjectionToken("COMPONENTS_FOR_DOCUMENT_TYPE");