@sinequa/atomic-angular 1.14.1 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/document-workspaces/i18n/de.json +232 -0
- package/document-workspaces/i18n/en.json +232 -0
- package/document-workspaces/i18n/fr.json +232 -0
- package/document-workspaces/i18n/ja.json +232 -0
- package/document-workspaces/index.d.ts +2099 -0
- package/elements/index.d.ts +112 -16
- package/fesm2022/sinequa-atomic-angular-document-workspaces.mjs +8073 -0
- package/fesm2022/sinequa-atomic-angular-document-workspaces.mjs.map +1 -0
- package/fesm2022/sinequa-atomic-angular-elements.mjs +4538 -2457
- package/fesm2022/sinequa-atomic-angular-elements.mjs.map +1 -1
- package/fesm2022/sinequa-atomic-angular-workspace-elements.mjs +172 -0
- package/fesm2022/sinequa-atomic-angular-workspace-elements.mjs.map +1 -0
- package/fesm2022/sinequa-atomic-angular.mjs +91 -112
- package/fesm2022/sinequa-atomic-angular.mjs.map +1 -1
- package/index.d.ts +174 -173
- package/package.json +37 -16
- package/workspace-elements/index.d.ts +37 -0
- package/workspace-elements/styles/lexiq-workspaces.css +10224 -0
|
@@ -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
|
-
|
|
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(
|
|
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(
|
|
3256
|
+
}), map(result => {
|
|
3255
3257
|
result.records?.map((article) => Object.assign(article, { value: article.title, type: "default" }));
|
|
3256
3258
|
return result;
|
|
3257
|
-
}), map(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
3314
|
-
results.forEach(
|
|
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(
|
|
3319
|
-
return results.map(
|
|
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(
|
|
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
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
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(
|
|
3358
|
+
error("queryService.getDocPages failure - error: ", err);
|
|
3359
3359
|
return [];
|
|
3360
3360
|
}));
|
|
3361
3361
|
}
|
|
3362
3362
|
/**
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
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(
|
|
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() ?
|
|
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(
|
|
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-
|
|
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(
|
|
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-
|
|
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()"
|
|
@@ -9191,8 +9189,8 @@ class AggregationDateRangeDialogComponent {
|
|
|
9191
9189
|
/** Drives an @if around the pickers so they are recreated fresh on each open. */
|
|
9192
9190
|
isDialogOpen = signal(false, ...(ngDevMode ? [{ debugName: "isDialogOpen" }] : []));
|
|
9193
9191
|
dialog = viewChild(DialogComponent, ...(ngDevMode ? [{ debugName: "dialog" }] : []));
|
|
9194
|
-
customRange = viewChild(
|
|
9195
|
-
dualPickers = viewChild(
|
|
9192
|
+
customRange = viewChild("customRange", ...(ngDevMode ? [{ debugName: "customRange" }] : []));
|
|
9193
|
+
dualPickers = viewChild("dualPickers", ...(ngDevMode ? [{ debugName: "dualPickers" }] : []));
|
|
9196
9194
|
min = input(undefined, ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
9197
9195
|
max = input(undefined, ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
9198
9196
|
lang = input("en", ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
@@ -9237,10 +9235,7 @@ class AggregationDateRangeDialogComponent {
|
|
|
9237
9235
|
}
|
|
9238
9236
|
const dualPickers = this.dualPickers();
|
|
9239
9237
|
if (dualPickers) {
|
|
9240
|
-
return [
|
|
9241
|
-
dualPickers.datepickerStart()?.getDate(),
|
|
9242
|
-
dualPickers.datepickerEnd()?.getDate()
|
|
9243
|
-
];
|
|
9238
|
+
return [dualPickers.datepickerStart()?.getDate(), dualPickers.datepickerEnd()?.getDate()];
|
|
9244
9239
|
}
|
|
9245
9240
|
return [undefined, undefined];
|
|
9246
9241
|
}
|
|
@@ -9272,8 +9267,8 @@ class AggregationDateRangeDialogComponent {
|
|
|
9272
9267
|
}
|
|
9273
9268
|
|
|
9274
9269
|
<DialogFooter>
|
|
9275
|
-
<button variant="outline" (click)="dialog.cancel()">{{ 'cancel' | transloco }}</button>
|
|
9276
|
-
<button [disabled]="!hasSelection()" (click)="confirm()">{{ 'filters.validate' | transloco }}</button>
|
|
9270
|
+
<button type="button" variant="outline" (click)="dialog.cancel()">{{ 'cancel' | transloco }}</button>
|
|
9271
|
+
<button type="button" [disabled]="!hasSelection()" (click)="confirm()">{{ 'filters.validate' | transloco }}</button>
|
|
9277
9272
|
</DialogFooter>
|
|
9278
9273
|
</DialogContent>
|
|
9279
9274
|
</div>
|
|
@@ -9323,14 +9318,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
9323
9318
|
}
|
|
9324
9319
|
|
|
9325
9320
|
<DialogFooter>
|
|
9326
|
-
<button variant="outline" (click)="dialog.cancel()">{{ 'cancel' | transloco }}</button>
|
|
9327
|
-
<button [disabled]="!hasSelection()" (click)="confirm()">{{ 'filters.validate' | transloco }}</button>
|
|
9321
|
+
<button type="button" variant="outline" (click)="dialog.cancel()">{{ 'cancel' | transloco }}</button>
|
|
9322
|
+
<button type="button" [disabled]="!hasSelection()" (click)="confirm()">{{ 'filters.validate' | transloco }}</button>
|
|
9328
9323
|
</DialogFooter>
|
|
9329
9324
|
</DialogContent>
|
|
9330
9325
|
</div>
|
|
9331
9326
|
`
|
|
9332
9327
|
}]
|
|
9333
|
-
}], propDecorators: { dialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DialogComponent), { isSignal: true }] }], customRange: [{ type: i0.ViewChild, args: [
|
|
9328
|
+
}], propDecorators: { dialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DialogComponent), { isSignal: true }] }], customRange: [{ type: i0.ViewChild, args: ["customRange", { isSignal: true }] }], dualPickers: [{ type: i0.ViewChild, args: ["dualPickers", { isSignal: true }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], lang: [{ type: i0.Input, args: [{ isSignal: true, alias: "lang", required: false }] }], useDateRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "useDateRange", required: false }] }], rangeSelected: [{ type: i0.Output, args: ["rangeSelected"] }] } });
|
|
9334
9329
|
|
|
9335
9330
|
/**
|
|
9336
9331
|
* How many filters a controlled selection carries. Shared with `<Aggregation>`,
|
|
@@ -10136,7 +10131,7 @@ class AggregationDateComponent {
|
|
|
10136
10131
|
throw new Error("filters.filterInvalid");
|
|
10137
10132
|
}
|
|
10138
10133
|
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" }] });
|
|
10134
|
+
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 type=\"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 type=\"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
10135
|
}
|
|
10141
10136
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationDateComponent, decorators: [{
|
|
10142
10137
|
type: Component,
|
|
@@ -10161,7 +10156,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
10161
10156
|
// layout — a date facet has no "empty but resolved" state to gate behind
|
|
10162
10157
|
// `hideWhenEmpty` (see `isEmpty`), unlike list/tree.
|
|
10163
10158
|
"[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
|
|
10159
|
+
}, 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 type=\"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 type=\"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
10160
|
}], 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
10161
|
|
|
10167
10162
|
/**
|
|
@@ -10171,7 +10166,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
10171
10166
|
*/
|
|
10172
10167
|
class DateComponent extends AggregationDateComponent {
|
|
10173
10168
|
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
|
|
10169
|
+
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 type=\"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 type=\"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
10170
|
}
|
|
10176
10171
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: DateComponent, decorators: [{
|
|
10177
10172
|
type: Component,
|
|
@@ -10188,7 +10183,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
10188
10183
|
FilterXIcon
|
|
10189
10184
|
], host: {
|
|
10190
10185
|
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
|
|
10186
|
+
}, 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 type=\"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 type=\"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
10187
|
}] });
|
|
10193
10188
|
|
|
10194
10189
|
class ArticleEntities {
|
|
@@ -12395,6 +12390,7 @@ const COLLECTIONS_CONFIG = new InjectionToken("Collections options", {
|
|
|
12395
12390
|
class CollectionsComponent {
|
|
12396
12391
|
floating = inject(PopoverComponent, { skipSelf: true, optional: true });
|
|
12397
12392
|
userSettingsStore = inject(UserSettingsStore);
|
|
12393
|
+
queryParamsStore = inject(QueryParamsStore);
|
|
12398
12394
|
drawerStack = inject(DrawerStackService);
|
|
12399
12395
|
router = inject(Router);
|
|
12400
12396
|
options = input(...(ngDevMode ? [undefined, { debugName: "options" }] : []));
|
|
@@ -12414,6 +12410,9 @@ class CollectionsComponent {
|
|
|
12414
12410
|
}
|
|
12415
12411
|
onClick(collection) {
|
|
12416
12412
|
this.drawerStack.closeAll();
|
|
12413
|
+
// Sync the store before navigating: patchState is synchronous while router.navigate is not,
|
|
12414
|
+
// so the destination /search page must already see the basket when it fires its first query.
|
|
12415
|
+
this.queryParamsStore.patch({ basket: collection.name }, undefined, { syncUrl: false });
|
|
12417
12416
|
this.router.navigate(["/search"], { queryParams: { b: collection.name } });
|
|
12418
12417
|
}
|
|
12419
12418
|
onDelete(collection, index, e) {
|
|
@@ -12429,16 +12428,7 @@ class CollectionsComponent {
|
|
|
12429
12428
|
}
|
|
12430
12429
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: CollectionsComponent, decorators: [{
|
|
12431
12430
|
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" }]
|
|
12431
|
+
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
12432
|
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], deleteCollectionDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DeleteCollectionDialog), { isSignal: true }] }] } });
|
|
12443
12433
|
|
|
12444
12434
|
/** Static catalog of the known boolean feature flags, with human-readable metadata. */
|
|
@@ -13265,25 +13255,23 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13265
13255
|
aggregations = signal([], ...(ngDevMode ? [{ debugName: "aggregations" }] : []));
|
|
13266
13256
|
inputVariant = signal("default", ...(ngDevMode ? [{ debugName: "inputVariant" }] : []));
|
|
13267
13257
|
tabs = computed(() => {
|
|
13268
|
-
const routeData = this.router.config.find(
|
|
13258
|
+
const routeData = this.router.config.find(c => c.path === searchRoute);
|
|
13269
13259
|
return !routeData
|
|
13270
13260
|
? []
|
|
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"] })));
|
|
13261
|
+
: [{ 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
13262
|
}, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
13275
13263
|
filters = computed(() => {
|
|
13276
13264
|
const cjsonFilters = this.appStore
|
|
13277
13265
|
.customizationJson()
|
|
13278
|
-
.filters?.filter(
|
|
13279
|
-
.map(
|
|
13266
|
+
.filters?.filter(f => f.column !== "#date")
|
|
13267
|
+
.map(f => ({
|
|
13280
13268
|
column: f.column,
|
|
13281
13269
|
alias: this.appStore.getColumnAlias(f.column),
|
|
13282
13270
|
display: f.display,
|
|
13283
|
-
items: this.aggregations()?.find(
|
|
13271
|
+
items: this.aggregations()?.find(a => a.column === f.column)?.items
|
|
13284
13272
|
})) || [];
|
|
13285
13273
|
const agg = this.aggregations()
|
|
13286
|
-
.filter(
|
|
13274
|
+
.filter(f => !cjsonFilters.some(cf => cf.column === f.column))
|
|
13287
13275
|
.map((f) => ({
|
|
13288
13276
|
column: f.column,
|
|
13289
13277
|
alias: this.appStore.getColumnAlias(f.column),
|
|
@@ -13352,7 +13340,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13352
13340
|
}
|
|
13353
13341
|
this.queryParamsStore.patch({ text });
|
|
13354
13342
|
const filters = [];
|
|
13355
|
-
this.appliedFilters().forEach(
|
|
13343
|
+
this.appliedFilters().forEach(filter => {
|
|
13356
13344
|
if (filter.values.length) {
|
|
13357
13345
|
// todo should handle dates? how?
|
|
13358
13346
|
/* if (filter.column.startsWith('modified') || filter.column.startsWith('date')) {
|
|
@@ -13370,7 +13358,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13370
13358
|
});
|
|
13371
13359
|
this.queryParamsStore.clearFilters();
|
|
13372
13360
|
if (filters.length) {
|
|
13373
|
-
filters.forEach(
|
|
13361
|
+
filters.forEach(filter => {
|
|
13374
13362
|
this.queryParamsStore.updateFilter(filter);
|
|
13375
13363
|
});
|
|
13376
13364
|
}
|
|
@@ -13388,10 +13376,10 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13388
13376
|
const display = values[0].display;
|
|
13389
13377
|
if (this.appStore.isDateColumn(field)) {
|
|
13390
13378
|
// dates
|
|
13391
|
-
const agg = this.aggregations().find(
|
|
13379
|
+
const agg = this.aggregations().find(a => a.column === field);
|
|
13392
13380
|
if (agg) {
|
|
13393
13381
|
const options = translateAggregationToDateOptions(agg, false);
|
|
13394
|
-
const option = options.find(
|
|
13382
|
+
const option = options.find(o => !!o.display && value.indexOf(o.display) !== -1);
|
|
13395
13383
|
if (option)
|
|
13396
13384
|
return [
|
|
13397
13385
|
{
|
|
@@ -13409,11 +13397,11 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13409
13397
|
return [{ operator: op, value, field: f }];
|
|
13410
13398
|
}
|
|
13411
13399
|
else {
|
|
13412
|
-
const agg = this.aggregations().find(
|
|
13400
|
+
const agg = this.aggregations().find(a => a.column === field);
|
|
13413
13401
|
// if AggregationItem
|
|
13414
13402
|
if (!!value.match(aggItemRegex)?.[1] && !!agg) {
|
|
13415
|
-
const items = agg.items.filter(
|
|
13416
|
-
const filters = items.map(
|
|
13403
|
+
const items = agg.items.filter(item => values.some(v => item.value === v.value));
|
|
13404
|
+
const filters = items.map(item => parseValueAndOperatorFromItem(item, field));
|
|
13417
13405
|
return [
|
|
13418
13406
|
{
|
|
13419
13407
|
operator: "or",
|
|
@@ -13431,10 +13419,10 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13431
13419
|
{
|
|
13432
13420
|
operator,
|
|
13433
13421
|
name: agg?.name,
|
|
13434
|
-
values: values.map(
|
|
13422
|
+
values: values.map(v => v.value),
|
|
13435
13423
|
field,
|
|
13436
13424
|
display: display || value,
|
|
13437
|
-
filters: values.map(
|
|
13425
|
+
filters: values.map(v => ({
|
|
13438
13426
|
operator: "contains",
|
|
13439
13427
|
name: agg?.name,
|
|
13440
13428
|
field,
|
|
@@ -13463,7 +13451,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13463
13451
|
// 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
13452
|
const words = value.split(/\s+(AND|OR)\s+/);
|
|
13465
13453
|
return words
|
|
13466
|
-
.map(
|
|
13454
|
+
.map(w => {
|
|
13467
13455
|
if (w === "AND" || w === "OR")
|
|
13468
13456
|
return w;
|
|
13469
13457
|
return `(${fieldStr}${w})`;
|
|
@@ -13472,7 +13460,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13472
13460
|
}
|
|
13473
13461
|
case "any": {
|
|
13474
13462
|
const splitWords = value.split(" ");
|
|
13475
|
-
return `(${splitWords.map(
|
|
13463
|
+
return `(${splitWords.map(w => `${fieldStr}[${w}]`).join(" OR ")})`;
|
|
13476
13464
|
}
|
|
13477
13465
|
case "none":
|
|
13478
13466
|
return `${fieldStr}NOT [${value}]`;
|
|
@@ -13481,20 +13469,19 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13481
13469
|
}
|
|
13482
13470
|
}
|
|
13483
13471
|
getPlaceholder(key) {
|
|
13484
|
-
return
|
|
13485
|
-
this.transloco.translate("drawers.searchWords"));
|
|
13472
|
+
return this.selectData.find(d => d.operator === this.form.get(key)?.value)?.placeholder || this.transloco.translate("drawers.searchWords");
|
|
13486
13473
|
}
|
|
13487
13474
|
/** Get applied filters for a column */
|
|
13488
13475
|
getItems(column) {
|
|
13489
|
-
return this.appliedFilters().find(
|
|
13476
|
+
return this.appliedFilters().find(f => f.column === column)?.values || [];
|
|
13490
13477
|
}
|
|
13491
13478
|
/** add item to current selection */
|
|
13492
13479
|
addItem(item, filter) {
|
|
13493
|
-
const appliedFilter = this.appliedFilters().find(
|
|
13480
|
+
const appliedFilter = this.appliedFilters().find(af => af.column === filter.column);
|
|
13494
13481
|
if (!appliedFilter) {
|
|
13495
13482
|
this.appliedFilters.set(this.appliedFilters().concat([{ column: filter.column, values: [item] }]));
|
|
13496
13483
|
}
|
|
13497
|
-
else if (!appliedFilter.values.some(
|
|
13484
|
+
else if (!appliedFilter.values.some(v => v.value === item.value)) {
|
|
13498
13485
|
if (this.appStore.isDateColumn(filter.column)) {
|
|
13499
13486
|
appliedFilter.values = [item]; // only one item for date filters
|
|
13500
13487
|
}
|
|
@@ -13505,9 +13492,9 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13505
13492
|
}
|
|
13506
13493
|
/** remove item from current selection */
|
|
13507
13494
|
removeItem(item, filter) {
|
|
13508
|
-
const appliedFilter = this.appliedFilters().find(
|
|
13495
|
+
const appliedFilter = this.appliedFilters().find(af => af.column === filter.column);
|
|
13509
13496
|
if (appliedFilter) {
|
|
13510
|
-
appliedFilter.values = appliedFilter.values.filter(
|
|
13497
|
+
appliedFilter.values = appliedFilter.values.filter(v => v.value !== item.value);
|
|
13511
13498
|
}
|
|
13512
13499
|
}
|
|
13513
13500
|
/** Update suggestions on input focus */
|
|
@@ -13521,23 +13508,22 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13521
13508
|
}
|
|
13522
13509
|
setSuggestions(value) {
|
|
13523
13510
|
this.suggestions.set([]);
|
|
13524
|
-
const filter = this.filters().find(
|
|
13511
|
+
const filter = this.filters().find(f => f.column === this.currentFilter());
|
|
13525
13512
|
if (!!value && !!filter && filter.items?.length) {
|
|
13526
|
-
this.suggestions.set(this.getSuggestionItems(value.toLowerCase(), filter.items).map(
|
|
13513
|
+
this.suggestions.set(this.getSuggestionItems(value.toLowerCase(), filter.items).map(i => ({
|
|
13527
13514
|
display: i.display || String(i.value),
|
|
13528
13515
|
value: String(filter.column === "treepath" ? `/${i.$path || i.value}/*` : i.value)
|
|
13529
13516
|
})));
|
|
13530
13517
|
}
|
|
13531
13518
|
}
|
|
13532
13519
|
getSuggestionItems(value, items) {
|
|
13533
|
-
const res = items.filter(
|
|
13534
|
-
String(i.value).toLowerCase().indexOf(value) !== -1);
|
|
13520
|
+
const res = items.filter(i => (!!i.display && i.display.toLowerCase().indexOf(value) !== -1) || String(i.value).toLowerCase().indexOf(value) !== -1);
|
|
13535
13521
|
// todo handle tree items
|
|
13536
13522
|
return res;
|
|
13537
13523
|
}
|
|
13538
13524
|
getWithSubItems(items) {
|
|
13539
13525
|
const res = [...items];
|
|
13540
|
-
items.forEach(
|
|
13526
|
+
items.forEach(item => {
|
|
13541
13527
|
if (item.hasChildren && item.items?.length) {
|
|
13542
13528
|
res.push(...this.getWithSubItems(item.items));
|
|
13543
13529
|
}
|
|
@@ -13545,7 +13531,7 @@ class DrawerAdvancedFiltersComponent extends DrawerComponent {
|
|
|
13545
13531
|
return res;
|
|
13546
13532
|
}
|
|
13547
13533
|
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 }} "{{ currentTab() }}"</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" }] });
|
|
13534
|
+
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 }} "{{ currentTab() }}"</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
13535
|
}
|
|
13550
13536
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: DrawerAdvancedFiltersComponent, decorators: [{
|
|
13551
13537
|
type: Component,
|
|
@@ -13561,7 +13547,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
13561
13547
|
TabComponent,
|
|
13562
13548
|
TabsListComponent
|
|
13563
13549
|
], providers: [DrawerService, SyslangPipe, TranslocoPipe, provideTranslocoScope("drawers")], host: {
|
|
13564
|
-
class: "fixed bg-background grid h-full top-0 -right-full justify-end"
|
|
13550
|
+
class: "fixed bg-background grid h-full top-0 -right-full justify-end",
|
|
13551
|
+
"data-legacy": ""
|
|
13565
13552
|
}, 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 }} "{{ currentTab() }}"</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
13553
|
}], ctorParameters: () => [] });
|
|
13567
13554
|
|
|
@@ -14053,7 +14040,7 @@ class AdvancedSearchComponent {
|
|
|
14053
14040
|
const { queryText } = getState(this.selectionStore);
|
|
14054
14041
|
return queryText;
|
|
14055
14042
|
},
|
|
14056
|
-
computation:
|
|
14043
|
+
computation: queryText => {
|
|
14057
14044
|
const text = queryText || "";
|
|
14058
14045
|
return text ? text.trim() : "";
|
|
14059
14046
|
} }] : [{
|
|
@@ -14061,7 +14048,7 @@ class AdvancedSearchComponent {
|
|
|
14061
14048
|
const { queryText } = getState(this.selectionStore);
|
|
14062
14049
|
return queryText;
|
|
14063
14050
|
},
|
|
14064
|
-
computation:
|
|
14051
|
+
computation: queryText => {
|
|
14065
14052
|
const text = queryText || "";
|
|
14066
14053
|
return text ? text.trim() : "";
|
|
14067
14054
|
}
|
|
@@ -14074,21 +14061,13 @@ class AdvancedSearchComponent {
|
|
|
14074
14061
|
this.queryText.set("");
|
|
14075
14062
|
}
|
|
14076
14063
|
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" }] });
|
|
14064
|
+
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
14065
|
}
|
|
14079
14066
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AdvancedSearchComponent, decorators: [{
|
|
14080
14067
|
type: Component,
|
|
14081
|
-
args: [{ selector: "advanced-search", standalone: true, providers: [provideTranslocoScope("drawers")], imports: [
|
|
14082
|
-
|
|
14083
|
-
|
|
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"] }]
|
|
14068
|
+
args: [{ selector: "advanced-search", standalone: true, providers: [provideTranslocoScope("drawers")], imports: [FormsModule, ButtonComponent, TranslocoPipe, SimilarDocumentsPanel, EntitiesPanel, LabelsPanel, ExtractsPanel, XMarkIcon, MagnifyingGlassIcon], host: {
|
|
14069
|
+
"data-legacy": ""
|
|
14070
|
+
}, 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
14071
|
}], 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
14072
|
|
|
14094
14073
|
const COMPONENTS_FOR_DOCUMENT_TYPE = new InjectionToken("COMPONENTS_FOR_DOCUMENT_TYPE");
|
|
@@ -14516,7 +14495,7 @@ class AggregationPanelComponent {
|
|
|
14516
14495
|
this.searchText.set("");
|
|
14517
14496
|
}
|
|
14518
14497
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14519
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: AggregationPanelComponent, isStandalone: true, selector: "AggregationPanel, aggregation-panel", inputs: { 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 }, isDate: { classPropertyName: "isDate", publicName: "isDate", isSignal: true, isRequired: false, transformFunction: null }, isEmpty: { classPropertyName: "isEmpty", publicName: "isEmpty", isSignal: true, isRequired: false, transformFunction: null }, aggregation: { classPropertyName: "aggregation", publicName: "aggregation", isSignal: true, isRequired: false, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, filtersCount: { classPropertyName: "filtersCount", publicName: "filtersCount", isSignal: true, isRequired: false, transformFunction: null }, hasFilters: { classPropertyName: "hasFilters", publicName: "hasFilters", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, isAllSelected: { classPropertyName: "isAllSelected", publicName: "isAllSelected", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null }, itemsLength: { classPropertyName: "itemsLength", publicName: "itemsLength", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: false, transformFunction: null }, searchedItemsLength: { classPropertyName: "searchedItemsLength", publicName: "searchedItemsLength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchText: "searchTextChange", cleared: "cleared", applied: "applied", allSelected: "allSelected", allUnselected: "allUnselected", loadedMore: "loadedMore" }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group space-y-2\"\n (toggle)=\"onToggle($event)\">\n <summary\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class.text-muted-foreground]=\"isEmpty()\"\n class=\"m-0 mt-1 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 truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (!isCollapsed()) {\n @if (hasFilters()) {\n @let label = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n\n @if (isAllSelected()) {\n @let label = \"filters.unselectAllFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allUnselected.emit()\">\n <square-check-icon />\n </button>\n } @else {\n @let label = \"filters.selectAllFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allSelected.emit()\">\n <square-icon />\n </button>\n }\n }\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 <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </icon-button>\n }\n </summary>\n\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <InputGroup class=\"group/item mt-3\">\n <input\n #searchInput\n input-group\n id=\"aggregation-input-{{ aggregation()?.column }}\"\n type=\"text\"\n [attr.aria-label]=\"'search' | transloco\"\n [attr.placeholder]=\"'search' | transloco\"\n [(ngModel)]=\"searchText\"\n class=\"mt-1\" />\n <InputGroupAddon>\n <SearchIcon\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\n </InputGroupAddon>\n <InputGroupAddon align=\"inline-end\" class=\"gap-0.5!\">\n <icon-button\n size=\"sm\"\n [class]=\"\n searchText().length > 0\n ? 'rotate-90 cursor-pointer opacity-100 transition-[rotate,opacity] duration-500'\n : 'pointer-events-none rotate-0 opacity-0 transition-[rotate,opacity] duration-500'\n \"\n aria-label=\"Clear search\"\n [tabindex]=\"searchText().length > 0 ? 0 : -1\"\n (keydown.enter)=\"clearSearch($event)\"\n (click)=\"clearSearch($event)\">\n <XMarkIcon />\n </icon-button>\n <ng-content select=\"[search-addon]\" />\n </InputGroupAddon>\n </InputGroup>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n class=\"mt-1 flex w-full justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n</details>\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: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "scheme", "size", "aria-label"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "component", type: SearchIcon, selector: "SearchIcon", inputs: ["class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "component", type: FilterXIcon, selector: "filter-x-icon, FilterXIcon", inputs: ["class"] }, { kind: "component", type: SquareCheckIcon, selector: "square-check-icon, SquareCheckIcon", inputs: ["class"] }, { kind: "component", type: SquareIcon, selector: "square-icon, SquareIcon", inputs: ["class"] }, { kind: "component", type: XMarkIcon, selector: "XMarkIcon, xmark-icon, x-mark-icon", inputs: ["class"] }, { kind: "directive", type: IconButtonComponent, selector: "button[icon-button], icon-button, IconButton", inputs: ["class", "size"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
14498
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: AggregationPanelComponent, isStandalone: true, selector: "AggregationPanel, aggregation-panel", inputs: { 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 }, isDate: { classPropertyName: "isDate", publicName: "isDate", isSignal: true, isRequired: false, transformFunction: null }, isEmpty: { classPropertyName: "isEmpty", publicName: "isEmpty", isSignal: true, isRequired: false, transformFunction: null }, aggregation: { classPropertyName: "aggregation", publicName: "aggregation", isSignal: true, isRequired: false, transformFunction: null }, showFiltersCount: { classPropertyName: "showFiltersCount", publicName: "showFiltersCount", isSignal: true, isRequired: false, transformFunction: null }, filtersCount: { classPropertyName: "filtersCount", publicName: "filtersCount", isSignal: true, isRequired: false, transformFunction: null }, hasFilters: { classPropertyName: "hasFilters", publicName: "hasFilters", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, isAllSelected: { classPropertyName: "isAllSelected", publicName: "isAllSelected", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: true, isRequired: false, transformFunction: null }, itemsLength: { classPropertyName: "itemsLength", publicName: "itemsLength", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: false, transformFunction: null }, searchedItemsLength: { classPropertyName: "searchedItemsLength", publicName: "searchedItemsLength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchText: "searchTextChange", cleared: "cleared", applied: "applied", allSelected: "allSelected", allUnselected: "allUnselected", loadedMore: "loadedMore" }, viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group space-y-2\"\n (toggle)=\"onToggle($event)\">\n <summary\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class.text-muted-foreground]=\"isEmpty()\"\n class=\"m-0 mt-1 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 truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (!isCollapsed()) {\n @if (hasFilters()) {\n @let label = \"filters.clearFilters\" | transloco;\n <button\n type=\"button\"\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n\n @if (isAllSelected()) {\n @let label = \"filters.unselectAllFilters\" | transloco;\n <button\n type=\"button\"\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allUnselected.emit()\">\n <square-check-icon />\n </button>\n } @else {\n @let label = \"filters.selectAllFilters\" | transloco;\n <button\n type=\"button\"\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allSelected.emit()\">\n <square-icon />\n </button>\n }\n }\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 <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </icon-button>\n }\n </summary>\n\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <InputGroup class=\"group/item mt-3\">\n <input\n #searchInput\n input-group\n id=\"aggregation-input-{{ aggregation()?.column }}\"\n type=\"text\"\n [attr.aria-label]=\"'search' | transloco\"\n [attr.placeholder]=\"'search' | transloco\"\n [(ngModel)]=\"searchText\"\n class=\"mt-1\" />\n <InputGroupAddon>\n <SearchIcon\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\n </InputGroupAddon>\n <InputGroupAddon align=\"inline-end\" class=\"gap-0.5!\">\n <icon-button\n size=\"sm\"\n [class]=\"\n searchText().length > 0\n ? 'rotate-90 cursor-pointer opacity-100 transition-[rotate,opacity] duration-500'\n : 'pointer-events-none rotate-0 opacity-0 transition-[rotate,opacity] duration-500'\n \"\n aria-label=\"Clear search\"\n [tabindex]=\"searchText().length > 0 ? 0 : -1\"\n (keydown.enter)=\"clearSearch($event)\"\n (click)=\"clearSearch($event)\">\n <XMarkIcon />\n </icon-button>\n <ng-content select=\"[search-addon]\" />\n </InputGroupAddon>\n </InputGroup>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n</details>\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: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "scheme", "size", "aria-label"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "directive", type: InputGroupInput, selector: "input[input-group]", inputs: ["class", "type", "placeholder", "disabled"] }, { kind: "directive", type: InputGroupComponent, selector: "input-group, inputgroup, InputGroup", inputs: ["class"] }, { kind: "directive", type: InputGroupAddonComponent, selector: "input-group-addon, inputgroupaddon, InputGroupAddon", inputs: ["class", "align"] }, { kind: "component", type: SearchIcon, selector: "SearchIcon", inputs: ["class"] }, { kind: "component", type: FilterIcon, selector: "filter-icon, FilterIcon", inputs: ["class"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "component", type: FilterXIcon, selector: "filter-x-icon, FilterXIcon", inputs: ["class"] }, { kind: "component", type: SquareCheckIcon, selector: "square-check-icon, SquareCheckIcon", inputs: ["class"] }, { kind: "component", type: SquareIcon, selector: "square-icon, SquareIcon", inputs: ["class"] }, { kind: "component", type: XMarkIcon, selector: "XMarkIcon, xmark-icon, x-mark-icon", inputs: ["class"] }, { kind: "directive", type: IconButtonComponent, selector: "button[icon-button], icon-button, IconButton", inputs: ["class", "size"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
14520
14499
|
}
|
|
14521
14500
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationPanelComponent, decorators: [{
|
|
14522
14501
|
type: Component,
|
|
@@ -14538,7 +14517,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
14538
14517
|
SquareIcon,
|
|
14539
14518
|
XMarkIcon,
|
|
14540
14519
|
IconButtonComponent,
|
|
14541
|
-
], template: "<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group space-y-2\"\n (toggle)=\"onToggle($event)\">\n <summary\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class.text-muted-foreground]=\"isEmpty()\"\n class=\"m-0 mt-1 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 truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (!isCollapsed()) {\n @if (hasFilters()) {\n @let label = \"filters.clearFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n\n @if (isAllSelected()) {\n @let label = \"filters.unselectAllFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allUnselected.emit()\">\n <square-check-icon />\n </button>\n } @else {\n @let label = \"filters.selectAllFilters\" | transloco;\n <button\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allSelected.emit()\">\n <square-icon />\n </button>\n }\n }\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 <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </icon-button>\n }\n </summary>\n\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <InputGroup class=\"group/item mt-3\">\n <input\n #searchInput\n input-group\n id=\"aggregation-input-{{ aggregation()?.column }}\"\n type=\"text\"\n [attr.aria-label]=\"'search' | transloco\"\n [attr.placeholder]=\"'search' | transloco\"\n [(ngModel)]=\"searchText\"\n class=\"mt-1\" />\n <InputGroupAddon>\n <SearchIcon\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\n </InputGroupAddon>\n <InputGroupAddon align=\"inline-end\" class=\"gap-0.5!\">\n <icon-button\n size=\"sm\"\n [class]=\"\n searchText().length > 0\n ? 'rotate-90 cursor-pointer opacity-100 transition-[rotate,opacity] duration-500'\n : 'pointer-events-none rotate-0 opacity-0 transition-[rotate,opacity] duration-500'\n \"\n aria-label=\"Clear search\"\n [tabindex]=\"searchText().length > 0 ? 0 : -1\"\n (keydown.enter)=\"clearSearch($event)\"\n (click)=\"clearSearch($event)\">\n <XMarkIcon />\n </icon-button>\n <ng-content select=\"[search-addon]\" />\n </InputGroupAddon>\n </InputGroup>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n class=\"mt-1 flex w-full justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n</details>\n" }]
|
|
14520
|
+
], template: "<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group space-y-2\"\n (toggle)=\"onToggle($event)\">\n <summary\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class.text-muted-foreground]=\"isEmpty()\"\n class=\"m-0 mt-1 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 truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (!isCollapsed()) {\n @if (hasFilters()) {\n @let label = \"filters.clearFilters\" | transloco;\n <button\n type=\"button\"\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon />\n {{ label }}\n </button>\n }\n\n @if (isAllSelected()) {\n @let label = \"filters.unselectAllFilters\" | transloco;\n <button\n type=\"button\"\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allUnselected.emit()\">\n <square-check-icon />\n </button>\n } @else {\n @let label = \"filters.selectAllFilters\" | transloco;\n <button\n type=\"button\"\n variant=\"none\"\n icon-button\n [aria-label]=\"label\"\n (click)=\"$event.stopPropagation(); allSelected.emit()\">\n <square-icon />\n </button>\n }\n }\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 <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </icon-button>\n }\n </summary>\n\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <InputGroup class=\"group/item mt-3\">\n <input\n #searchInput\n input-group\n id=\"aggregation-input-{{ aggregation()?.column }}\"\n type=\"text\"\n [attr.aria-label]=\"'search' | transloco\"\n [attr.placeholder]=\"'search' | transloco\"\n [(ngModel)]=\"searchText\"\n class=\"mt-1\" />\n <InputGroupAddon>\n <SearchIcon\n class=\"text-foreground size-4 rotate-0 transition-[rotate] duration-500 group-focus-within/item:rotate-90\" />\n </InputGroupAddon>\n <InputGroupAddon align=\"inline-end\" class=\"gap-0.5!\">\n <icon-button\n size=\"sm\"\n [class]=\"\n searchText().length > 0\n ? 'rotate-90 cursor-pointer opacity-100 transition-[rotate,opacity] duration-500'\n : 'pointer-events-none rotate-0 opacity-0 transition-[rotate,opacity] duration-500'\n \"\n aria-label=\"Clear search\"\n [tabindex]=\"searchText().length > 0 ? 0 : -1\"\n (keydown.enter)=\"clearSearch($event)\"\n (click)=\"clearSearch($event)\">\n <XMarkIcon />\n </icon-button>\n <ng-content select=\"[search-addon]\" />\n </InputGroupAddon>\n </InputGroup>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n</details>\n" }]
|
|
14542
14521
|
}], ctorParameters: () => [], propDecorators: { 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 }] }], isDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDate", required: false }] }], isEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "isEmpty", required: false }] }], aggregation: [{ type: i0.Input, args: [{ isSignal: true, alias: "aggregation", required: false }] }], showFiltersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFiltersCount", required: false }] }], filtersCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersCount", required: false }] }], hasFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasFilters", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], isAllSelected: [{ type: i0.Input, args: [{ isSignal: true, alias: "isAllSelected", required: false }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }], itemsLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsLength", required: false }] }], hasMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMore", required: false }] }], searchedItemsLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchedItemsLength", required: false }] }], cleared: [{ type: i0.Output, args: ["cleared"] }], applied: [{ type: i0.Output, args: ["applied"] }], allSelected: [{ type: i0.Output, args: ["allSelected"] }], allUnselected: [{ type: i0.Output, args: ["allUnselected"] }], loadedMore: [{ type: i0.Output, args: ["loadedMore"] }], searchInput: [{ type: i0.ViewChild, args: ["searchInput", { isSignal: true }] }] } });
|
|
14543
14522
|
|
|
14544
14523
|
class AggregationTreeComponent {
|
|
@@ -15220,7 +15199,7 @@ class AggregationTreeComponent {
|
|
|
15220
15199
|
return false;
|
|
15221
15200
|
}
|
|
15222
15201
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15223
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: AggregationTreeComponent, isStandalone: true, selector: "AggregationTree, aggregation-tree, aggregationtree", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, 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 }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, applyOnSelect: { classPropertyName: "applyOnSelect", publicName: "applyOnSelect", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", 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 }, hideWhenEmpty: { classPropertyName: "hideWhenEmpty", publicName: "hideWhenEmpty", isSignal: true, isRequired: false, transformFunction: null }, itemTemplateInput: { classPropertyName: "itemTemplateInput", publicName: "itemTemplate", 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(\"block h-[inherit] max-h-[inherit] w-[inherit]\", class(), (isMissing() || (hideWhenEmpty() && isHidden())) && \"hidden\")" } }, queries: [{ propertyName: "itemDirective", first: true, predicate: AggregationItemDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "virtualItems", predicate: ["virtualItem"], descendants: true, isSignal: true }, { propertyName: "scrollElement", first: true, predicate: ["scrollElement"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1\" />\n The aggregationTree component does not support list aggregations. Please use\n the <Aggregation /> component instead.\n </div>\n}\n<aggregation-panel\n [id]=\"id()\"\n [collapsible]=\"collapsible()\"\n [collapsed]=\"collapsed()\"\n [isEmpty]=\"isEmpty()\"\n [isDate]=\"isDate()\"\n [aggregation]=\"aggregation()\"\n [showFiltersCount]=\"showFiltersCount()\"\n [filtersCount]=\"filtersCount()\"\n [hasFilters]=\"hasFilters()\"\n [selection]=\"selection()\"\n [isAllSelected]=\"isAllSelected()\"\n [(searchText)]=\"searchText\"\n [itemsLength]=\"items().length\"\n [hasMore]=\"aggregation()?.$hasMore ?? false\"\n [searchedItemsLength]=\"searchedItems().length\"\n (cleared)=\"clear()\"\n (applied)=\"apply()\"\n (allSelected)=\"selectAll()\"\n (allUnselected)=\"unselectAll()\"\n (loadedMore)=\"loadMore()\">\n <!-- Relay the host's `label` projection into the panel's `label` slot. When the\n host projects nothing, the local <ng-content> falls back to the icon + display\n (mirrors AggregationPanel's own fallback), so the header is never empty. -->\n <ng-container ngProjectAs=\"label\">\n <ng-content select=\"label\">\n @let labelIcon = aggregation()?.icon;\n @if (labelIcon) {\n <FaIcon [faClass]=\"labelIcon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n </ng-container>\n <div\n #scrollElement\n class=\"max-h-(--scroll-height,20rem) w-full scrollbar-thin overflow-auto\">\n <div\n class=\"relative w-full\"\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\n role=\"tree\"\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\n <div\n class=\"absolute top-0 left-0 w-full\"\n [style.transform]=\"\n 'translateY(' +\n (virtualizer.getVirtualItems()[0]\n ? virtualizer.getVirtualItems()[0].start\n : 0) +\n 'px)'\n \">\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\n @let item = items()[vItem.index];\n <div #virtualItem [attr.data-index]=\"vItem.index\">\n <ng-container\n [ngTemplateOutlet]=\"treeItemTpl\"\n [ngTemplateOutletContext]=\"{\n node: item,\n path: [],\n field: aggregation()?.column,\n tpl: treeItemTpl,\n parent: null\n }\">\n </ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</aggregation-panel>\n\n<ng-template\n #treeItemTpl\n let-node=\"node\"\n let-path=\"path\"\n let-field=\"field\"\n let-tpl=\"tpl\"\n let-parent=\"parent\">\n <div\n role=\"treeitem\"\n [style.--level]=\"treeItemLevel(node)\"\n [attr.aria-selected]=\"node.$selected ?? false\"\n [attr.aria-expanded]=\"\n node.hasChildren !== false ? (node.$opened ?? false) : null\n \"\n [attr.aria-disabled]=\"node.count === 0 ? 'true' : null\"\n [attr.disabled]=\"node.count === 0 ? 'disabled' : null\">\n <a\n [attr.aria-label]=\"treeItemName(node) | syslang\"\n [class]=\"\n cn(\n 'flex grow items-center gap-2 p-1 leading-7',\n node.count === 0 && 'disabled pointer-events-none',\n applyOnSelect() && 'cursor-pointer',\n (node.$selected || node.$selectedVisually) && ''\n )\n \"\n (click)=\"onTreeItemRowClick(node, parent, $event)\">\n <button\n variant=\"none\"\n [iconOnly]=\"true\"\n (click)=\"toggleTreeNode($event, node)\"\n class=\"transition-transform ease-in hover:scale-125\"\n aria-label=\"Open\">\n <ChevronRight\n [class]=\"\n cn(\n 'size-4 translate-x-1',\n node.$opened && 'rotate-90',\n !node.hasChildren && 'hidden'\n )\n \"\n width=\"16\"\n height=\"16\" />\n </button>\n @if (showCheckbox()) {\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n value=\"{{ node.value }}\"\n [attr.disabled]=\"node.count === 0 ? true : null\"\n [attr.aria-disabled]=\"node.count === 0\"\n (keydown.enter)=\"onTreeItemRowClick(node, parent, $event)\"\n [checked]=\"node.$selected || node.$selectedVisually\" />\n }\n @if (resolvedItemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: field,\n selected: node.$selected || node.$selectedVisually || false,\n count: node.count,\n name: (treeItemName(node) | syslang) ?? '',\n searchText: searchText(),\n level: treeItemLevel(node),\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n } @else {\n @let icon = node.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"self-center justify-self-center\" />\n }\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'line-clamp-1 break-all text-ellipsis',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node, field)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n (treeItemName(node) | syslang)\n : (treeItemName(node) | syslang)\n \"\n (click)=\"onTreeItemTextClick(node, parent, $event)\">\n @for (\n chunk of (treeItemName(node) | syslang) ?? \"\"\n | highlightWord: searchText() : 10;\n track $index\n ) {\n <span [class]=\"{ 'font-bold': chunk.match }\" aria-hidden=\"true\">{{\n chunk.text\n }}</span>\n }\n </span>\n @if (showCount() && node.count > 0) {\n <span class=\"ml-auto px-1 text-xs empty:hidden\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n </a>\n @if (node.hasChildren && node.$opened) {\n <div role=\"group\">\n @for (child of node.items; track $index) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n node: child,\n path: treeChildrenPath(node, path),\n field: field,\n tpl: tpl,\n parent: node\n }\">\n </ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["div[role=treeitem]:has(+div[role=treeitem]){margin-bottom:var(--agg-item-gap, 0)}div[role=treeitem]{display:block;-webkit-user-select:none;user-select:none}div[role=treeitem] a{padding-left:calc(var(--agg-tree-indent, .5rem) * var(--level, 0));line-height:var(--agg-item-height, inherit)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size", "solid"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "component", type: TriangleAlertIcon, selector: "triangle-alert-icon, TriangleAlertIcon", inputs: ["class"] }, { kind: "component", type: AggregationPanelComponent, selector: "AggregationPanel, aggregation-panel", inputs: ["id", "collapsible", "collapsed", "isDate", "isEmpty", "aggregation", "showFiltersCount", "filtersCount", "hasFilters", "selection", "isAllSelected", "searchText", "itemsLength", "hasMore", "searchedItemsLength"], outputs: ["searchTextChange", "cleared", "applied", "allSelected", "allUnselected", "loadedMore"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: HighlightWordPipe, name: "highlightWord" }] });
|
|
15202
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.29", type: AggregationTreeComponent, isStandalone: true, selector: "AggregationTree, aggregation-tree, aggregationtree", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null }, 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 }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, applyOnSelect: { classPropertyName: "applyOnSelect", publicName: "applyOnSelect", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", 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 }, hideWhenEmpty: { classPropertyName: "hideWhenEmpty", publicName: "hideWhenEmpty", isSignal: true, isRequired: false, transformFunction: null }, itemTemplateInput: { classPropertyName: "itemTemplateInput", publicName: "itemTemplate", 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(\"block h-[inherit] max-h-[inherit] w-[inherit]\", class(), (isMissing() || (hideWhenEmpty() && isHidden())) && \"hidden\")" } }, queries: [{ propertyName: "itemDirective", first: true, predicate: AggregationItemDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "virtualItems", predicate: ["virtualItem"], descendants: true, isSignal: true }, { propertyName: "scrollElement", first: true, predicate: ["scrollElement"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1\" />\n The aggregationTree component does not support list aggregations. Please use\n the <Aggregation /> component instead.\n </div>\n}\n<aggregation-panel\n [id]=\"id()\"\n [collapsible]=\"collapsible()\"\n [collapsed]=\"collapsed()\"\n [isEmpty]=\"isEmpty()\"\n [isDate]=\"isDate()\"\n [aggregation]=\"aggregation()\"\n [showFiltersCount]=\"showFiltersCount()\"\n [filtersCount]=\"filtersCount()\"\n [hasFilters]=\"hasFilters()\"\n [selection]=\"selection()\"\n [isAllSelected]=\"isAllSelected()\"\n [(searchText)]=\"searchText\"\n [itemsLength]=\"items().length\"\n [hasMore]=\"aggregation()?.$hasMore ?? false\"\n [searchedItemsLength]=\"searchedItems().length\"\n (cleared)=\"clear()\"\n (applied)=\"apply()\"\n (allSelected)=\"selectAll()\"\n (allUnselected)=\"unselectAll()\"\n (loadedMore)=\"loadMore()\">\n <!-- Relay the host's `label` projection into the panel's `label` slot. When the\n host projects nothing, the local <ng-content> falls back to the icon + display\n (mirrors AggregationPanel's own fallback), so the header is never empty. -->\n <ng-container ngProjectAs=\"label\">\n <ng-content select=\"label\">\n @let labelIcon = aggregation()?.icon;\n @if (labelIcon) {\n <FaIcon [faClass]=\"labelIcon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n </ng-container>\n <div\n #scrollElement\n class=\"max-h-(--scroll-height,20rem) w-full scrollbar-thin overflow-auto\">\n <div\n class=\"relative w-full\"\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\n role=\"tree\"\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\n <div\n class=\"absolute top-0 left-0 w-full\"\n [style.transform]=\"\n 'translateY(' +\n (virtualizer.getVirtualItems()[0]\n ? virtualizer.getVirtualItems()[0].start\n : 0) +\n 'px)'\n \">\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\n @let item = items()[vItem.index];\n <div #virtualItem [attr.data-index]=\"vItem.index\">\n <ng-container\n [ngTemplateOutlet]=\"treeItemTpl\"\n [ngTemplateOutletContext]=\"{\n node: item,\n path: [],\n field: aggregation()?.column,\n tpl: treeItemTpl,\n parent: null\n }\">\n </ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</aggregation-panel>\n\n<ng-template\n #treeItemTpl\n let-node=\"node\"\n let-path=\"path\"\n let-field=\"field\"\n let-tpl=\"tpl\"\n let-parent=\"parent\">\n <div\n role=\"treeitem\"\n [style.--level]=\"treeItemLevel(node)\"\n [attr.aria-selected]=\"node.$selected ?? false\"\n [attr.aria-expanded]=\"\n node.hasChildren !== false ? (node.$opened ?? false) : null\n \"\n [attr.aria-disabled]=\"node.count === 0 ? 'true' : null\"\n [attr.disabled]=\"node.count === 0 ? 'disabled' : null\">\n <a\n [attr.aria-label]=\"treeItemName(node) | syslang\"\n [class]=\"\n cn(\n 'flex grow items-center gap-2 p-1 leading-7',\n node.count === 0 && 'disabled pointer-events-none',\n applyOnSelect() && 'cursor-pointer',\n (node.$selected || node.$selectedVisually) && ''\n )\n \"\n (click)=\"onTreeItemRowClick(node, parent, $event)\">\n <button\n type=\"button\"\n variant=\"none\"\n [iconOnly]=\"true\"\n (click)=\"toggleTreeNode($event, node)\"\n class=\"transition-transform ease-in hover:scale-125\"\n aria-label=\"Open\">\n <ChevronRight\n [class]=\"\n cn(\n 'size-4 translate-x-1',\n node.$opened && 'rotate-90',\n !node.hasChildren && 'hidden'\n )\n \"\n width=\"16\"\n height=\"16\" />\n </button>\n @if (showCheckbox()) {\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n value=\"{{ node.value }}\"\n [attr.disabled]=\"node.count === 0 ? true : null\"\n [attr.aria-disabled]=\"node.count === 0\"\n (keydown.enter)=\"onTreeItemRowClick(node, parent, $event)\"\n [checked]=\"node.$selected || node.$selectedVisually\" />\n }\n @if (resolvedItemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: field,\n selected: node.$selected || node.$selectedVisually || false,\n count: node.count,\n name: (treeItemName(node) | syslang) ?? '',\n searchText: searchText(),\n level: treeItemLevel(node),\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n } @else {\n @let icon = node.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"self-center justify-self-center\" />\n }\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'line-clamp-1 break-all text-ellipsis',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node, field)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n (treeItemName(node) | syslang)\n : (treeItemName(node) | syslang)\n \"\n (click)=\"onTreeItemTextClick(node, parent, $event)\">\n @for (\n chunk of (treeItemName(node) | syslang) ?? \"\"\n | highlightWord: searchText() : 10;\n track $index\n ) {\n <span [class]=\"{ 'font-bold': chunk.match }\" aria-hidden=\"true\">{{\n chunk.text\n }}</span>\n }\n </span>\n @if (showCount() && node.count > 0) {\n <span class=\"ml-auto px-1 text-xs empty:hidden\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n </a>\n @if (node.hasChildren && node.$opened) {\n <div role=\"group\">\n @for (child of node.items; track $index) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n node: child,\n path: treeChildrenPath(node, path),\n field: field,\n tpl: tpl,\n parent: node\n }\">\n </ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["div[role=treeitem]:has(+div[role=treeitem]){margin-bottom:var(--agg-item-gap, 0)}div[role=treeitem]{display:block;-webkit-user-select:none;user-select:none}div[role=treeitem] a{padding-left:calc(var(--agg-tree-indent, .5rem) * var(--level, 0));line-height:var(--agg-item-height, inherit)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size", "solid"] }, { kind: "component", type: ChevronRightIcon, selector: "chevron-right, ChevronRight, chevronright, ChevronRightIcon, chevron-right-icon, chevronrighticon", inputs: ["class"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass", "class"] }, { kind: "component", type: TriangleAlertIcon, selector: "triangle-alert-icon, TriangleAlertIcon", inputs: ["class"] }, { kind: "component", type: AggregationPanelComponent, selector: "AggregationPanel, aggregation-panel", inputs: ["id", "collapsible", "collapsed", "isDate", "isEmpty", "aggregation", "showFiltersCount", "filtersCount", "hasFilters", "selection", "isAllSelected", "searchText", "itemsLength", "hasMore", "searchedItemsLength"], outputs: ["searchTextChange", "cleared", "applied", "allSelected", "allUnselected", "loadedMore"] }, { kind: "pipe", type: SyslangPipe, name: "syslang" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: HighlightWordPipe, name: "highlightWord" }] });
|
|
15224
15203
|
}
|
|
15225
15204
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImport: i0, type: AggregationTreeComponent, decorators: [{
|
|
15226
15205
|
type: Component,
|
|
@@ -15238,7 +15217,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.29", ngImpo
|
|
|
15238
15217
|
AggregationPanelComponent
|
|
15239
15218
|
], standalone: true, host: {
|
|
15240
15219
|
"[class]": 'cn("block h-[inherit] max-h-[inherit] w-[inherit]", class(), (isMissing() || (hideWhenEmpty() && isHidden())) && "hidden")'
|
|
15241
|
-
}, template: "@if (!aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1\" />\n The aggregationTree component does not support list aggregations. Please use\n the <Aggregation /> component instead.\n </div>\n}\n<aggregation-panel\n [id]=\"id()\"\n [collapsible]=\"collapsible()\"\n [collapsed]=\"collapsed()\"\n [isEmpty]=\"isEmpty()\"\n [isDate]=\"isDate()\"\n [aggregation]=\"aggregation()\"\n [showFiltersCount]=\"showFiltersCount()\"\n [filtersCount]=\"filtersCount()\"\n [hasFilters]=\"hasFilters()\"\n [selection]=\"selection()\"\n [isAllSelected]=\"isAllSelected()\"\n [(searchText)]=\"searchText\"\n [itemsLength]=\"items().length\"\n [hasMore]=\"aggregation()?.$hasMore ?? false\"\n [searchedItemsLength]=\"searchedItems().length\"\n (cleared)=\"clear()\"\n (applied)=\"apply()\"\n (allSelected)=\"selectAll()\"\n (allUnselected)=\"unselectAll()\"\n (loadedMore)=\"loadMore()\">\n <!-- Relay the host's `label` projection into the panel's `label` slot. When the\n host projects nothing, the local <ng-content> falls back to the icon + display\n (mirrors AggregationPanel's own fallback), so the header is never empty. -->\n <ng-container ngProjectAs=\"label\">\n <ng-content select=\"label\">\n @let labelIcon = aggregation()?.icon;\n @if (labelIcon) {\n <FaIcon [faClass]=\"labelIcon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n </ng-container>\n <div\n #scrollElement\n class=\"max-h-(--scroll-height,20rem) w-full scrollbar-thin overflow-auto\">\n <div\n class=\"relative w-full\"\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\n role=\"tree\"\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\n <div\n class=\"absolute top-0 left-0 w-full\"\n [style.transform]=\"\n 'translateY(' +\n (virtualizer.getVirtualItems()[0]\n ? virtualizer.getVirtualItems()[0].start\n : 0) +\n 'px)'\n \">\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\n @let item = items()[vItem.index];\n <div #virtualItem [attr.data-index]=\"vItem.index\">\n <ng-container\n [ngTemplateOutlet]=\"treeItemTpl\"\n [ngTemplateOutletContext]=\"{\n node: item,\n path: [],\n field: aggregation()?.column,\n tpl: treeItemTpl,\n parent: null\n }\">\n </ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</aggregation-panel>\n\n<ng-template\n #treeItemTpl\n let-node=\"node\"\n let-path=\"path\"\n let-field=\"field\"\n let-tpl=\"tpl\"\n let-parent=\"parent\">\n <div\n role=\"treeitem\"\n [style.--level]=\"treeItemLevel(node)\"\n [attr.aria-selected]=\"node.$selected ?? false\"\n [attr.aria-expanded]=\"\n node.hasChildren !== false ? (node.$opened ?? false) : null\n \"\n [attr.aria-disabled]=\"node.count === 0 ? 'true' : null\"\n [attr.disabled]=\"node.count === 0 ? 'disabled' : null\">\n <a\n [attr.aria-label]=\"treeItemName(node) | syslang\"\n [class]=\"\n cn(\n 'flex grow items-center gap-2 p-1 leading-7',\n node.count === 0 && 'disabled pointer-events-none',\n applyOnSelect() && 'cursor-pointer',\n (node.$selected || node.$selectedVisually) && ''\n )\n \"\n (click)=\"onTreeItemRowClick(node, parent, $event)\">\n <button\n variant=\"none\"\n [iconOnly]=\"true\"\n (click)=\"toggleTreeNode($event, node)\"\n class=\"transition-transform ease-in hover:scale-125\"\n aria-label=\"Open\">\n <ChevronRight\n [class]=\"\n cn(\n 'size-4 translate-x-1',\n node.$opened && 'rotate-90',\n !node.hasChildren && 'hidden'\n )\n \"\n width=\"16\"\n height=\"16\" />\n </button>\n @if (showCheckbox()) {\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n value=\"{{ node.value }}\"\n [attr.disabled]=\"node.count === 0 ? true : null\"\n [attr.aria-disabled]=\"node.count === 0\"\n (keydown.enter)=\"onTreeItemRowClick(node, parent, $event)\"\n [checked]=\"node.$selected || node.$selectedVisually\" />\n }\n @if (resolvedItemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: field,\n selected: node.$selected || node.$selectedVisually || false,\n count: node.count,\n name: (treeItemName(node) | syslang) ?? '',\n searchText: searchText(),\n level: treeItemLevel(node),\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n } @else {\n @let icon = node.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"self-center justify-self-center\" />\n }\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'line-clamp-1 break-all text-ellipsis',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node, field)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n (treeItemName(node) | syslang)\n : (treeItemName(node) | syslang)\n \"\n (click)=\"onTreeItemTextClick(node, parent, $event)\">\n @for (\n chunk of (treeItemName(node) | syslang) ?? \"\"\n | highlightWord: searchText() : 10;\n track $index\n ) {\n <span [class]=\"{ 'font-bold': chunk.match }\" aria-hidden=\"true\">{{\n chunk.text\n }}</span>\n }\n </span>\n @if (showCount() && node.count > 0) {\n <span class=\"ml-auto px-1 text-xs empty:hidden\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n </a>\n @if (node.hasChildren && node.$opened) {\n <div role=\"group\">\n @for (child of node.items; track $index) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n node: child,\n path: treeChildrenPath(node, path),\n field: field,\n tpl: tpl,\n parent: node\n }\">\n </ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["div[role=treeitem]:has(+div[role=treeitem]){margin-bottom:var(--agg-item-gap, 0)}div[role=treeitem]{display:block;-webkit-user-select:none;user-select:none}div[role=treeitem] a{padding-left:calc(var(--agg-tree-indent, .5rem) * var(--level, 0));line-height:var(--agg-item-height, inherit)}\n"] }]
|
|
15220
|
+
}, template: "@if (!aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1\" />\n The aggregationTree component does not support list aggregations. Please use\n the <Aggregation /> component instead.\n </div>\n}\n<aggregation-panel\n [id]=\"id()\"\n [collapsible]=\"collapsible()\"\n [collapsed]=\"collapsed()\"\n [isEmpty]=\"isEmpty()\"\n [isDate]=\"isDate()\"\n [aggregation]=\"aggregation()\"\n [showFiltersCount]=\"showFiltersCount()\"\n [filtersCount]=\"filtersCount()\"\n [hasFilters]=\"hasFilters()\"\n [selection]=\"selection()\"\n [isAllSelected]=\"isAllSelected()\"\n [(searchText)]=\"searchText\"\n [itemsLength]=\"items().length\"\n [hasMore]=\"aggregation()?.$hasMore ?? false\"\n [searchedItemsLength]=\"searchedItems().length\"\n (cleared)=\"clear()\"\n (applied)=\"apply()\"\n (allSelected)=\"selectAll()\"\n (allUnselected)=\"unselectAll()\"\n (loadedMore)=\"loadMore()\">\n <!-- Relay the host's `label` projection into the panel's `label` slot. When the\n host projects nothing, the local <ng-content> falls back to the icon + display\n (mirrors AggregationPanel's own fallback), so the header is never empty. -->\n <ng-container ngProjectAs=\"label\">\n <ng-content select=\"label\">\n @let labelIcon = aggregation()?.icon;\n @if (labelIcon) {\n <FaIcon [faClass]=\"labelIcon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n </ng-container>\n <div\n #scrollElement\n class=\"max-h-(--scroll-height,20rem) w-full scrollbar-thin overflow-auto\">\n <div\n class=\"relative w-full\"\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\n role=\"tree\"\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\n <div\n class=\"absolute top-0 left-0 w-full\"\n [style.transform]=\"\n 'translateY(' +\n (virtualizer.getVirtualItems()[0]\n ? virtualizer.getVirtualItems()[0].start\n : 0) +\n 'px)'\n \">\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\n @let item = items()[vItem.index];\n <div #virtualItem [attr.data-index]=\"vItem.index\">\n <ng-container\n [ngTemplateOutlet]=\"treeItemTpl\"\n [ngTemplateOutletContext]=\"{\n node: item,\n path: [],\n field: aggregation()?.column,\n tpl: treeItemTpl,\n parent: null\n }\">\n </ng-container>\n </div>\n }\n </div>\n </div>\n </div>\n</aggregation-panel>\n\n<ng-template\n #treeItemTpl\n let-node=\"node\"\n let-path=\"path\"\n let-field=\"field\"\n let-tpl=\"tpl\"\n let-parent=\"parent\">\n <div\n role=\"treeitem\"\n [style.--level]=\"treeItemLevel(node)\"\n [attr.aria-selected]=\"node.$selected ?? false\"\n [attr.aria-expanded]=\"\n node.hasChildren !== false ? (node.$opened ?? false) : null\n \"\n [attr.aria-disabled]=\"node.count === 0 ? 'true' : null\"\n [attr.disabled]=\"node.count === 0 ? 'disabled' : null\">\n <a\n [attr.aria-label]=\"treeItemName(node) | syslang\"\n [class]=\"\n cn(\n 'flex grow items-center gap-2 p-1 leading-7',\n node.count === 0 && 'disabled pointer-events-none',\n applyOnSelect() && 'cursor-pointer',\n (node.$selected || node.$selectedVisually) && ''\n )\n \"\n (click)=\"onTreeItemRowClick(node, parent, $event)\">\n <button\n type=\"button\"\n variant=\"none\"\n [iconOnly]=\"true\"\n (click)=\"toggleTreeNode($event, node)\"\n class=\"transition-transform ease-in hover:scale-125\"\n aria-label=\"Open\">\n <ChevronRight\n [class]=\"\n cn(\n 'size-4 translate-x-1',\n node.$opened && 'rotate-90',\n !node.hasChildren && 'hidden'\n )\n \"\n width=\"16\"\n height=\"16\" />\n </button>\n @if (showCheckbox()) {\n <input\n type=\"checkbox\"\n role=\"checkbox\"\n value=\"{{ node.value }}\"\n [attr.disabled]=\"node.count === 0 ? true : null\"\n [attr.aria-disabled]=\"node.count === 0\"\n (keydown.enter)=\"onTreeItemRowClick(node, parent, $event)\"\n [checked]=\"node.$selected || node.$selectedVisually\" />\n }\n @if (resolvedItemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: field,\n selected: node.$selected || node.$selectedVisually || false,\n count: node.count,\n name: (treeItemName(node) | syslang) ?? '',\n searchText: searchText(),\n level: treeItemLevel(node),\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n } @else {\n @let icon = node.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"self-center justify-self-center\" />\n }\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'line-clamp-1 break-all text-ellipsis',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node, field)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n (treeItemName(node) | syslang)\n : (treeItemName(node) | syslang)\n \"\n (click)=\"onTreeItemTextClick(node, parent, $event)\">\n @for (\n chunk of (treeItemName(node) | syslang) ?? \"\"\n | highlightWord: searchText() : 10;\n track $index\n ) {\n <span [class]=\"{ 'font-bold': chunk.match }\" aria-hidden=\"true\">{{\n chunk.text\n }}</span>\n }\n </span>\n @if (showCount() && node.count > 0) {\n <span class=\"ml-auto px-1 text-xs empty:hidden\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n </a>\n @if (node.hasChildren && node.$opened) {\n <div role=\"group\">\n @for (child of node.items; track $index) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n node: child,\n path: treeChildrenPath(node, path),\n field: field,\n tpl: tpl,\n parent: node\n }\">\n </ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["div[role=treeitem]:has(+div[role=treeitem]){margin-bottom:var(--agg-item-gap, 0)}div[role=treeitem]{display:block;-webkit-user-select:none;user-select:none}div[role=treeitem] a{padding-left:calc(var(--agg-tree-indent, .5rem) * var(--level, 0));line-height:var(--agg-item-height, inherit)}\n"] }]
|
|
15242
15221
|
}], ctorParameters: () => [], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }], 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 }] }], showCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheckbox", required: false }] }], applyOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "applyOnSelect", required: false }] }], expandedLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedLevel", 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 }] }], hideWhenEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideWhenEmpty", 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"] }], virtualItems: [{ type: i0.ViewChildren, args: ["virtualItem", { isSignal: true }] }], scrollElement: [{ type: i0.ViewChild, args: ["scrollElement", { isSignal: true }] }], itemDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AggregationItemDirective), { isSignal: true }] }], itemTemplateInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], searchText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchText", required: false }] }, { type: i0.Output, args: ["searchTextChange"] }] } });
|
|
15243
15222
|
|
|
15244
15223
|
class AggregationListComponent {
|