@sinequa/atomic-angular 2.4.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/multi-selection-toolbar/i18n/de.json +2 -1
- package/components/multi-selection-toolbar/i18n/en.json +2 -1
- package/components/multi-selection-toolbar/i18n/fr.json +2 -1
- package/features/list-panel/i18n/de.json +6 -1
- package/features/list-panel/i18n/en.json +6 -1
- package/features/list-panel/i18n/fr.json +6 -1
- package/fesm2022/sinequa-atomic-angular.mjs +771 -230
- package/fesm2022/sinequa-atomic-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/providers/session-expiry/i18n/de.json +4 -2
- package/providers/session-expiry/i18n/en.json +4 -2
- package/providers/session-expiry/i18n/fr.json +4 -2
- package/types/sinequa-atomic-angular.d.ts +353 -36
|
@@ -2,7 +2,7 @@ import * as i0 from "@angular/core";
|
|
|
2
2
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, HostBinding, HostListener, Inject, Injectable, InjectionToken, Injector, LOCALE_ID, Optional, Pipe, Service, TemplateRef, ViewEncapsulation, afterNextRender, afterRenderEffect, assertInInjectionContext, booleanAttribute, computed, contentChild, contentChildren, effect, inject, input, isDevMode, linkedSignal, makeEnvironmentProviders, model, numberAttribute, output, provideEnvironmentInitializer, resource, runInInjectionContext, signal, untracked, viewChild, viewChildren } from "@angular/core";
|
|
3
3
|
import { BehaviorSubject, EMPTY, Subject, Subscription, catchError, debounceTime, filter, firstValueFrom, from, fromEvent, map, of, scan, shareReplay, switchMap, tap, throwError } from "rxjs";
|
|
4
4
|
import { TranslocoPipe, TranslocoService, provideTranslocoScope } from "@jsverse/transloco";
|
|
5
|
-
import { ArrowDownZaIcon, ArrowLeftIcon, ArrowRightFromBracketIcon, ArrowRightIcon, ArrowUpAzIcon, ArrowUpRightFromSquareIcon, ArrowsMaximizeIcon, AutocompleteComponent, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent, BadgeComponent, BarsIcon, BellIcon, BookmarkIcon, BreakpointObserverService, ButtonComponent, CalendarDayIcon, CheckIcon, CheckboxComponent, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon, CircleCheckIcon, CommentIcon, CommentsIcon, DIALOG_REF, DesktopIcon, DialogBodyComponent, DialogComponent, DialogContentComponent, DialogDescriptionComponent, DialogFooterComponent, DialogHeaderComponent, DialogTitleComponent, DropdownDirective, EditIcon, EllipsisIcon, EllipsisVerticalIcon, EyeIcon, EyeSlashIcon, FileHTMLIcon, FileIcon, FileOutputIcon, FileSpreadsheetIcon, FileTextIcon, FilterIcon, FilterXIcon, FlagEnglishIcon, FlagFrenchIcon, FlagGermanIcon, FlashlightIcon, FolderIcon, FolderOpenIcon, FrownIcon, GearIcon, GitForkIcon, GlobeIcon, HighlighterIcon, HistoryIcon, HomeIcon, ImageIcon, InboxIcon, InfoCircleIcon, InputComponent, InputControlDirective, InputIconRightDirective, KbdComponent, KbdGroupComponent, KeyIcon, KeyboardIcon, LanguageIcon, LightbulbIcon, LightbulbSlashIcon, LinkComponent, ListComponent, ListFilterIcon, ListItemActionComponent, ListItemAvatarDirective, ListItemComponent, ListItemLeftDirective, ListItemTextComponent, LoadingCircleIcon, MagnifyingGlassIcon, MagnifyingGlassMinusIcon, MagnifyingGlassPlusIcon, MenuComponent, MenuContentComponent, MenuItemComponent, MenuTriggerDirective, MoonIcon, PaletteIcon, PaperclipIcon, PenToSquareIcon, PlusIcon, PopoverDirective, PresentationIcon, QuestionCircleIcon, RadioComponent, RobotIcon, SaveIcon, SearchBarComponent, SearchInputComponent, SelectComponent, SelectTriggerDirective, SendIcon, SheetBodyComponent, SheetComponent, SheetHeaderComponent, SlashIcon, SlidersIcon, SparklesIcon, SpinnerIcon, SquareCheckIcon, SquareIcon, SquareMinusIcon, StarIcon, SunBrightIcon, SwitchComponent, SyncIcon, TabComponent, TabListComponent, TabPanelComponent, TabsComponent, TagComponent, TagIcon, TagsIcon, TextareaComponent, TextareaControlDirective, ThumbsDownIcon, ThumbsUpIcon, ToggleComponent, ToggleGroupComponent, ToggleItemComponent, ToggleLeftIcon, ToggleRightIcon, TooltipDirective, TrashCanIcon, TrashIcon, TreeComponent, TreeItemComponent, TreeItemExpanderComponent, TreeItemGroupComponent, TriangleAlertIcon, UndoIcon, UserIcon, UserSecretIcon, VideoIcon, XMarkIcon, createCallable, injectCallRef } from "@sinequa/galactik";
|
|
5
|
+
import { ArrowDownIcon, ArrowDownZaIcon, ArrowLeftIcon, ArrowRightFromBracketIcon, ArrowRightIcon, ArrowUpAzIcon, ArrowUpIcon, ArrowUpRightFromSquareIcon, ArrowsMaximizeIcon, AutocompleteComponent, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent, BadgeComponent, BarsIcon, BellIcon, BookmarkIcon, BreakpointObserverService, ButtonComponent, CalendarDayIcon, CheckIcon, CheckboxComponent, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon, CircleCheckIcon, CommentIcon, CommentsIcon, DIALOG_REF, DesktopIcon, DialogBodyComponent, DialogComponent, DialogContentComponent, DialogDescriptionComponent, DialogFooterComponent, DialogHeaderComponent, DialogTitleComponent, DropdownDirective, EditIcon, EllipsisIcon, EllipsisVerticalIcon, EyeIcon, EyeSlashIcon, FileHTMLIcon, FileIcon, FileOutputIcon, FileSpreadsheetIcon, FileTextIcon, FilterIcon, FilterXIcon, FlagEnglishIcon, FlagFrenchIcon, FlagGermanIcon, FlashlightIcon, FolderIcon, FolderOpenIcon, FrownIcon, GearIcon, GitForkIcon, GlobeIcon, HighlighterIcon, HistoryIcon, HomeIcon, ImageIcon, InboxIcon, InfoCircleIcon, InputComponent, InputControlDirective, InputIconRightDirective, KbdComponent, KbdGroupComponent, KeyIcon, KeyboardIcon, LanguageIcon, LightbulbIcon, LightbulbSlashIcon, LinkComponent, ListComponent, ListFilterIcon, ListItemActionComponent, ListItemAvatarDirective, ListItemComponent, ListItemLeftDirective, ListItemTextComponent, LoadingCircleIcon, MagnifyingGlassIcon, MagnifyingGlassMinusIcon, MagnifyingGlassPlusIcon, MenuComponent, MenuContentComponent, MenuItemComponent, MenuTriggerDirective, MoonIcon, PaletteIcon, PaperclipIcon, PenToSquareIcon, PlusIcon, PopoverDirective, PresentationIcon, QuestionCircleIcon, RadioComponent, RobotIcon, SaveIcon, SearchBarComponent, SearchInputComponent, SelectComponent, SelectTriggerDirective, SendIcon, SheetBodyComponent, SheetComponent, SheetHeaderComponent, SlashIcon, SlidersIcon, SparklesIcon, SpinnerIcon, SquareCheckIcon, SquareIcon, SquareMinusIcon, StarIcon, SunBrightIcon, SwitchComponent, SyncIcon, TabComponent, TabListComponent, TabPanelComponent, TabsComponent, TagComponent, TagIcon, TagsIcon, TextareaComponent, TextareaControlDirective, ThumbsDownIcon, ThumbsUpIcon, ToggleComponent, ToggleGroupComponent, ToggleItemComponent, ToggleLeftIcon, ToggleRightIcon, TooltipDirective, TrashCanIcon, TrashIcon, TreeComponent, TreeItemComponent, TreeItemExpanderComponent, TreeItemGroupComponent, TriangleAlertIcon, UndoIcon, UserIcon, UserSecretIcon, VideoIcon, XMarkIcon, createCallable, injectCallRef, isApplePlatform } from "@sinequa/galactik";
|
|
6
6
|
import { withDevtools } from "@angular-architects/ngrx-toolkit";
|
|
7
7
|
import { getState, patchState, signalStore, signalStoreFeature, withComputed, withMethods, withState } from "@ngrx/signals";
|
|
8
8
|
import { ActivatedRoute, NavigationEnd, Router, RouterLink, RouterModule } from "@angular/router";
|
|
@@ -214,47 +214,55 @@ function withAppFeatures() {
|
|
|
214
214
|
data: {}
|
|
215
215
|
}), withMethods((store) => {
|
|
216
216
|
const client = inject(ATOMIC_CLIENT);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Object.
|
|
229
|
-
|
|
217
|
+
const hydrate = (app) => {
|
|
218
|
+
patchState(store, app);
|
|
219
|
+
const columnMap = {};
|
|
220
|
+
Object.values(extraColumns).forEach((col) => {
|
|
221
|
+
columnMap[col.name.toLocaleLowerCase()] = col;
|
|
222
|
+
if (col.aliases) col.aliases.forEach((alias) => {
|
|
223
|
+
columnMap[alias.toLocaleLowerCase()] = col;
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
const schema = app.indexes._?.columns;
|
|
227
|
+
if (schema) {
|
|
228
|
+
Object.keys(schema).forEach((schemaKey) => {
|
|
229
|
+
const col = schema[schemaKey.toLocaleLowerCase()];
|
|
230
|
+
if (!col) return;
|
|
231
|
+
columnMap[schemaKey.toLocaleLowerCase()] = col;
|
|
230
232
|
if (col.aliases) col.aliases.forEach((alias) => {
|
|
231
233
|
columnMap[alias.toLocaleLowerCase()] = col;
|
|
232
234
|
});
|
|
233
235
|
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Object.
|
|
237
|
-
const col = schema[
|
|
236
|
+
Object.keys(app.queries).forEach((queryKey) => {
|
|
237
|
+
const query = app.queries[queryKey];
|
|
238
|
+
if (query.columnsInfo?.columns) Object.values(query.columnsInfo.columns).forEach((c) => {
|
|
239
|
+
const col = schema[c.name.toLocaleLowerCase()];
|
|
238
240
|
if (!col) return;
|
|
239
|
-
columnMap[
|
|
240
|
-
if (
|
|
241
|
+
columnMap[c.name.toLocaleLowerCase()] = col;
|
|
242
|
+
if (c.aliases) c.aliases.split(/[,;|]/).map((a) => a.trim()).forEach((alias) => {
|
|
241
243
|
columnMap[alias.toLocaleLowerCase()] = col;
|
|
242
244
|
});
|
|
243
245
|
});
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
246
|
+
});
|
|
247
|
+
patchState(store, { columnMap });
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
const fail = (error) => {
|
|
251
|
+
console.error("Error fetching app data:", error);
|
|
252
|
+
throw error;
|
|
253
|
+
};
|
|
254
|
+
return {
|
|
255
|
+
async initialize() {
|
|
256
|
+
let app;
|
|
257
|
+
try {
|
|
258
|
+
app = await client.api.app.get();
|
|
259
|
+
} catch (error) {
|
|
260
|
+
return fail(error);
|
|
256
261
|
}
|
|
262
|
+
hydrate(app);
|
|
257
263
|
},
|
|
264
|
+
hydrate,
|
|
265
|
+
fail,
|
|
258
266
|
async initializeWithAppName(appName) {
|
|
259
267
|
const app = await client.api.app.get(appName);
|
|
260
268
|
patchState(store, app);
|
|
@@ -500,7 +508,23 @@ const PrincipalStore = signalStore({ providedIn: "root" }, withDevtools("Princip
|
|
|
500
508
|
})), withMethods((store) => {
|
|
501
509
|
const client = inject(ATOMIC_CLIENT);
|
|
502
510
|
let pendingInitialization = null;
|
|
511
|
+
const hydrate = (principal) => {
|
|
512
|
+
const { userOverrideActive = false } = client.config;
|
|
513
|
+
patchState(store, {
|
|
514
|
+
...initialPrincipal,
|
|
515
|
+
...principal,
|
|
516
|
+
userOverrideActive,
|
|
517
|
+
state: "loaded"
|
|
518
|
+
});
|
|
519
|
+
};
|
|
520
|
+
const fail = (error) => {
|
|
521
|
+
console.error("Principal fetch failed", error);
|
|
522
|
+
patchState(store, { state: "error" });
|
|
523
|
+
throw error;
|
|
524
|
+
};
|
|
503
525
|
return {
|
|
526
|
+
hydrate,
|
|
527
|
+
fail,
|
|
504
528
|
principal() {
|
|
505
529
|
const { userOverrideActive: _, ...rest } = getState(store);
|
|
506
530
|
return Object.entries(rest).reduce((acc, [k, v]) => {
|
|
@@ -513,18 +537,9 @@ const PrincipalStore = signalStore({ providedIn: "root" }, withDevtools("Princip
|
|
|
513
537
|
pendingInitialization = (async () => {
|
|
514
538
|
patchState(store, { state: "loading" });
|
|
515
539
|
try {
|
|
516
|
-
|
|
517
|
-
const { userOverrideActive = false } = client.config;
|
|
518
|
-
patchState(store, {
|
|
519
|
-
...initialPrincipal,
|
|
520
|
-
...principal,
|
|
521
|
-
userOverrideActive,
|
|
522
|
-
state: "loaded"
|
|
523
|
-
});
|
|
540
|
+
hydrate(await client.api.principal.get());
|
|
524
541
|
} catch (error) {
|
|
525
|
-
|
|
526
|
-
patchState(store, { state: "error" });
|
|
527
|
-
throw error;
|
|
542
|
+
fail(error);
|
|
528
543
|
} finally {
|
|
529
544
|
pendingInitialization = null;
|
|
530
545
|
}
|
|
@@ -1256,6 +1271,16 @@ function AuthGuard() {
|
|
|
1256
1271
|
return true;
|
|
1257
1272
|
};
|
|
1258
1273
|
}
|
|
1274
|
+
const STARTUP_DATA_SOURCE = new InjectionToken("STARTUP_DATA_SOURCE", { factory: () => null });
|
|
1275
|
+
function provideStartupAggregation(endpoint = "bff/bootstrap") {
|
|
1276
|
+
return makeEnvironmentProviders([{
|
|
1277
|
+
provide: STARTUP_DATA_SOURCE,
|
|
1278
|
+
useFactory: () => {
|
|
1279
|
+
const client = inject(ATOMIC_CLIENT);
|
|
1280
|
+
return () => client.http.get(endpoint);
|
|
1281
|
+
}
|
|
1282
|
+
}]);
|
|
1283
|
+
}
|
|
1259
1284
|
var UserSettingsPersistence = class UserSettingsPersistence {
|
|
1260
1285
|
loaded = signal(false, ...ngDevMode ? [{ debugName: "loaded" }] : /* istanbul ignore next */ []);
|
|
1261
1286
|
isLoaded = this.loaded.asReadonly();
|
|
@@ -1735,18 +1760,25 @@ function withUserSettingsFeatures() {
|
|
|
1735
1760
|
}), withMethods((store) => {
|
|
1736
1761
|
const client = inject(ATOMIC_CLIENT);
|
|
1737
1762
|
const persistence = inject(UserSettingsPersistence);
|
|
1763
|
+
const hydrate = (settings) => {
|
|
1764
|
+
patchState(store, {
|
|
1765
|
+
...USER_SETTINGS_DEFAULTS,
|
|
1766
|
+
...settings
|
|
1767
|
+
});
|
|
1768
|
+
persistence.markLoaded();
|
|
1769
|
+
};
|
|
1770
|
+
const fail = (err) => {
|
|
1771
|
+
error("Error fetching user settings:", err);
|
|
1772
|
+
persistence.markUnloaded();
|
|
1773
|
+
};
|
|
1738
1774
|
return {
|
|
1775
|
+
hydrate,
|
|
1776
|
+
fail,
|
|
1739
1777
|
async initialize() {
|
|
1740
1778
|
try {
|
|
1741
|
-
|
|
1742
|
-
patchState(store, {
|
|
1743
|
-
...USER_SETTINGS_DEFAULTS,
|
|
1744
|
-
...settings
|
|
1745
|
-
});
|
|
1746
|
-
persistence.markLoaded();
|
|
1779
|
+
hydrate(await client.api.userSettings.get());
|
|
1747
1780
|
} catch (err) {
|
|
1748
|
-
|
|
1749
|
-
persistence.markUnloaded();
|
|
1781
|
+
fail(err);
|
|
1750
1782
|
}
|
|
1751
1783
|
},
|
|
1752
1784
|
async reset() {
|
|
@@ -1776,6 +1808,14 @@ function withAgentsFeatures() {
|
|
|
1776
1808
|
}));
|
|
1777
1809
|
}
|
|
1778
1810
|
const UserSettingsStore = signalStore({ providedIn: "root" }, withDevtools("UserSettings"), withBookmarkFeatures(), withRecentSearchesFeatures(), withSavedSearchesFeatures(), withBasketsFeatures(), withAssistantFeatures(), withUserSettingsFeatures(), withAlertsFeatures(), withAgentsFeatures(), withDarkModeFeatures(), withHighlightCategoriesFeatures());
|
|
1811
|
+
const toPart = (result) => result.status === "fulfilled" ? {
|
|
1812
|
+
ok: true,
|
|
1813
|
+
value: result.value
|
|
1814
|
+
} : {
|
|
1815
|
+
ok: false,
|
|
1816
|
+
error: result.reason
|
|
1817
|
+
};
|
|
1818
|
+
const provided = (part) => part && typeof part === "object" && part.ok === true ? Promise.resolve(part.value) : void 0;
|
|
1779
1819
|
const ROUTE_COMPONENTS = new InjectionToken("ROUTE_COMPONENTS", { factory: () => [] });
|
|
1780
1820
|
var ApplicationService = class ApplicationService {
|
|
1781
1821
|
userSettingsStore = inject(UserSettingsStore);
|
|
@@ -1785,6 +1825,7 @@ var ApplicationService = class ApplicationService {
|
|
|
1785
1825
|
router = inject(Router);
|
|
1786
1826
|
titleService = inject(Title);
|
|
1787
1827
|
client = inject(ATOMIC_CLIENT);
|
|
1828
|
+
startupDataSource = inject(STARTUP_DATA_SOURCE);
|
|
1788
1829
|
components = inject(ROUTE_COMPONENTS);
|
|
1789
1830
|
defaultComponent = computed(() => this.components.find((c) => c.path === "all")?.component, ...ngDevMode ? [{ debugName: "defaultComponent" }] : /* istanbul ignore next */ []);
|
|
1790
1831
|
defaultLayoutComponent = computed(() => this.components.find((c) => c.isRoot)?.component, ...ngDevMode ? [{ debugName: "defaultLayoutComponent" }] : /* istanbul ignore next */ []);
|
|
@@ -1807,18 +1848,46 @@ var ApplicationService = class ApplicationService {
|
|
|
1807
1848
|
}
|
|
1808
1849
|
async initializeStores(options) {
|
|
1809
1850
|
try {
|
|
1810
|
-
await this.
|
|
1851
|
+
const data = await this.loadStartupData();
|
|
1852
|
+
this.apply(data.app, this.appStore);
|
|
1811
1853
|
info("appStore", getState(this.appStore));
|
|
1812
|
-
|
|
1854
|
+
this.apply(data.principal, this.principalStore);
|
|
1813
1855
|
info("principalStore", getState(this.principalStore));
|
|
1814
1856
|
this.queryParamsStore.reset({ syncUrl: options?.syncUrl ?? !options?.isBootstrap });
|
|
1815
|
-
|
|
1857
|
+
this.apply(data.userSettings, this.userSettingsStore);
|
|
1816
1858
|
info("userSettingsStore", getState(this.userSettingsStore));
|
|
1817
1859
|
} catch (err) {
|
|
1818
1860
|
error("Error during application initialization", err);
|
|
1819
1861
|
throw err;
|
|
1820
1862
|
}
|
|
1821
1863
|
}
|
|
1864
|
+
async loadStartupData() {
|
|
1865
|
+
const source = await this.readStartupDataSource();
|
|
1866
|
+
const [app, principal, userSettings] = await Promise.allSettled([
|
|
1867
|
+
provided(source?.app) ?? this.client.api.app.get(),
|
|
1868
|
+
provided(source?.principal) ?? this.client.api.principal.get(),
|
|
1869
|
+
provided(source?.userSettings) ?? this.client.api.userSettings.get()
|
|
1870
|
+
]);
|
|
1871
|
+
return {
|
|
1872
|
+
app: toPart(app),
|
|
1873
|
+
principal: toPart(principal),
|
|
1874
|
+
userSettings: toPart(userSettings)
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1877
|
+
async readStartupDataSource() {
|
|
1878
|
+
if (!this.startupDataSource) return void 0;
|
|
1879
|
+
try {
|
|
1880
|
+
const data = await this.startupDataSource();
|
|
1881
|
+
if (data && typeof data === "object") return data;
|
|
1882
|
+
warn("Start-up aggregation answered no data, reading each part instead", data);
|
|
1883
|
+
} catch (err) {
|
|
1884
|
+
warn("Start-up aggregation failed, reading each part instead", err);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
apply(part, store) {
|
|
1888
|
+
if (part.ok) store.hydrate(part.value);
|
|
1889
|
+
else store.fail(part.error);
|
|
1890
|
+
}
|
|
1822
1891
|
createRoutes() {
|
|
1823
1892
|
const { queries, data: custom, customJSONs = [] } = getState(this.appStore);
|
|
1824
1893
|
const queriesMap = Object.entries(queries).map(([key, value]) => ({
|
|
@@ -6619,7 +6688,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
6619
6688
|
}] }
|
|
6620
6689
|
});
|
|
6621
6690
|
const Export = createCallable(ExportDialog);
|
|
6622
|
-
const multiSelectionToolbarVariants = cva("flex divide-x rounded-xl bg-linear-to-b px-3 py-2 shadow [&_ul]:flex [&_ul]:flex-col [&_ul]:p-1 [&>
|
|
6691
|
+
const multiSelectionToolbarVariants = cva("flex divide-x rounded-xl bg-linear-to-b px-3 py-2 shadow [&_ul]:flex [&_ul]:flex-col [&_ul]:p-1 [&>div]:px-2", {
|
|
6623
6692
|
variants: { variant: {
|
|
6624
6693
|
dark: "divide-gray-800 bg-gray-900 from-gray-500 to-gray-900 text-white",
|
|
6625
6694
|
light: "divide-gray-400 bg-white from-white to-purple-50 text-gray-800",
|
|
@@ -6635,7 +6704,9 @@ var MultiSelectionToolbarComponent = class MultiSelectionToolbarComponent {
|
|
|
6635
6704
|
appFeatures = this.appStore.general();
|
|
6636
6705
|
class = input("", ...ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []);
|
|
6637
6706
|
variant = input("dark", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
|
|
6707
|
+
hint = input(...ngDevMode ? [void 0, { debugName: "hint" }] : /* istanbul ignore next */ []);
|
|
6638
6708
|
updatedCollections = output();
|
|
6709
|
+
cleared = output();
|
|
6639
6710
|
count = this.selection.multiSelectCount;
|
|
6640
6711
|
variants = computed(() => cn(multiSelectionToolbarVariants({
|
|
6641
6712
|
variant: this.variant(),
|
|
@@ -6650,8 +6721,30 @@ var MultiSelectionToolbarComponent = class MultiSelectionToolbarComponent {
|
|
|
6650
6721
|
}
|
|
6651
6722
|
return `search-results-assistant`;
|
|
6652
6723
|
}, ...ngDevMode ? [{ debugName: "instanceId" }] : /* istanbul ignore next */ []);
|
|
6653
|
-
enabledUserInput = computed(() => this.appStore.assistants()[this.instanceId()]?.modeSettings
|
|
6654
|
-
|
|
6724
|
+
enabledUserInput = computed(() => this.appStore.assistants()[this.instanceId()]?.modeSettings?.enabledUserInput === true, ...ngDevMode ? [{ debugName: "enabledUserInput" }] : /* istanbul ignore next */ []);
|
|
6725
|
+
allowAI = input(false, ...ngDevMode ? [{ debugName: "allowAI" }] : /* istanbul ignore next */ []);
|
|
6726
|
+
showAssistantAction = computed(() => this.allowAI() && this.appStore.isAssistantAllowed(this.instanceId()) && this.enabledUserInput(), ...ngDevMode ? [{ debugName: "showAssistantAction" }] : /* istanbul ignore next */ []);
|
|
6727
|
+
showHint = signal(false, ...ngDevMode ? [{ debugName: "showHint" }] : /* istanbul ignore next */ []);
|
|
6728
|
+
armed = true;
|
|
6729
|
+
constructor() {
|
|
6730
|
+
effect(() => {
|
|
6731
|
+
const count = this.count();
|
|
6732
|
+
untracked(() => {
|
|
6733
|
+
if (count === 0) {
|
|
6734
|
+
this.armed = true;
|
|
6735
|
+
this.showHint.set(false);
|
|
6736
|
+
} else if (this.armed) {
|
|
6737
|
+
this.armed = false;
|
|
6738
|
+
this.showHint.set(true);
|
|
6739
|
+
} else this.showHint.set(false);
|
|
6740
|
+
});
|
|
6741
|
+
});
|
|
6742
|
+
}
|
|
6743
|
+
clearSelection = () => {
|
|
6744
|
+
if (this.count() === 0) return;
|
|
6745
|
+
this.selection.clearMultiSelection();
|
|
6746
|
+
this.cleared.emit();
|
|
6747
|
+
};
|
|
6655
6748
|
openCollectionDialog = () => AddToCollection.call(getState(this.selection).multiSelection, { injector: this.injector }).then((event) => {
|
|
6656
6749
|
if (event === "dialog-no" || event === "dialog-yes") {
|
|
6657
6750
|
this.updatedCollections.emit();
|
|
@@ -6688,9 +6781,26 @@ var MultiSelectionToolbarComponent = class MultiSelectionToolbarComponent {
|
|
|
6688
6781
|
isSignal: true,
|
|
6689
6782
|
isRequired: false,
|
|
6690
6783
|
transformFunction: null
|
|
6784
|
+
},
|
|
6785
|
+
hint: {
|
|
6786
|
+
classPropertyName: "hint",
|
|
6787
|
+
publicName: "hint",
|
|
6788
|
+
isSignal: true,
|
|
6789
|
+
isRequired: false,
|
|
6790
|
+
transformFunction: null
|
|
6791
|
+
},
|
|
6792
|
+
allowAI: {
|
|
6793
|
+
classPropertyName: "allowAI",
|
|
6794
|
+
publicName: "allowAI",
|
|
6795
|
+
isSignal: true,
|
|
6796
|
+
isRequired: false,
|
|
6797
|
+
transformFunction: null
|
|
6691
6798
|
}
|
|
6692
6799
|
},
|
|
6693
|
-
outputs: {
|
|
6800
|
+
outputs: {
|
|
6801
|
+
updatedCollections: "updatedCollections",
|
|
6802
|
+
cleared: "cleared"
|
|
6803
|
+
},
|
|
6694
6804
|
host: {
|
|
6695
6805
|
properties: {
|
|
6696
6806
|
"class.opacity-100": "count() > 0",
|
|
@@ -6701,37 +6811,57 @@ var MultiSelectionToolbarComponent = class MultiSelectionToolbarComponent {
|
|
|
6701
6811
|
providers: [provideTranslocoScope("multi-selection-toolbar", "article", "collections", "export")],
|
|
6702
6812
|
ngImport: i0,
|
|
6703
6813
|
template: `
|
|
6704
|
-
|
|
6705
|
-
|
|
6814
|
+
<!-- Région de statut hors de la barre : celle-ci est inerte sans sélection, et une région
|
|
6815
|
+
inerte n'est pas annoncée. Le texte n'existe que tant que la sélection est non vide. -->
|
|
6816
|
+
<span role="status" class="sr-only">
|
|
6817
|
+
@if (count() > 0) {
|
|
6818
|
+
{{ 'multiSelectionToolbar.itemsSelected' | transloco: { count: count() } }}
|
|
6819
|
+
@if (showHint() && hint()) {
|
|
6820
|
+
. {{ hint() }}
|
|
6821
|
+
}
|
|
6822
|
+
}
|
|
6823
|
+
</span>
|
|
6824
|
+
|
|
6825
|
+
<!-- inert sans sélection : la barre n'est que transparente et hors écran, ses boutons resteraient
|
|
6826
|
+
sinon dans l'ordre de tabulation et activables (Entrée ouvrait « Ajouter à une collection » sur
|
|
6827
|
+
un panier vide, ES-31356). -->
|
|
6828
|
+
<div
|
|
6829
|
+
id="multi-select-toolbar"
|
|
6830
|
+
role="toolbar"
|
|
6831
|
+
[attr.aria-label]="'multiSelectionToolbar.label' | transloco"
|
|
6832
|
+
[attr.inert]="count() === 0 ? '' : null"
|
|
6833
|
+
(keydown.escape)="clearSelection()"
|
|
6834
|
+
[class]="cn(variants(), class())">
|
|
6835
|
+
<div class="ps-0!">
|
|
6706
6836
|
<button class="cursor-pointer inline-flex items-center gap-1" (click)="clearSelection()">
|
|
6707
6837
|
{{ 'multiSelectionToolbar.itemsSelected' | transloco: { count: count() } }}
|
|
6708
|
-
<x-mark-icon />
|
|
6838
|
+
<x-mark-icon aria-hidden="true" />
|
|
6709
6839
|
</button>
|
|
6710
|
-
</
|
|
6840
|
+
</div>
|
|
6711
6841
|
|
|
6712
|
-
<
|
|
6713
|
-
<button class="cursor-pointer inline-flex items-center gap-1"
|
|
6714
|
-
<inbox-icon />
|
|
6842
|
+
<div>
|
|
6843
|
+
<button class="cursor-pointer inline-flex items-center gap-1" (click)="openCollectionDialog()">
|
|
6844
|
+
<inbox-icon aria-hidden="true" />
|
|
6715
6845
|
{{ 'collections.label' | transloco }}
|
|
6716
6846
|
</button>
|
|
6717
|
-
</
|
|
6847
|
+
</div>
|
|
6718
6848
|
|
|
6719
|
-
<
|
|
6849
|
+
<div>
|
|
6720
6850
|
<button class="cursor-pointer inline-flex items-center gap-1" (click)="openExportDialog()">
|
|
6721
|
-
<file-output-icon />
|
|
6851
|
+
<file-output-icon aria-hidden="true" />
|
|
6722
6852
|
{{ 'export.title' | transloco }}
|
|
6723
6853
|
</button>
|
|
6724
|
-
</
|
|
6854
|
+
</div>
|
|
6725
6855
|
|
|
6726
|
-
@if (
|
|
6727
|
-
<
|
|
6856
|
+
@if (showAssistantAction()) {
|
|
6857
|
+
<div class="pe-0!">
|
|
6728
6858
|
<button class="cursor-pointer inline-flex items-center gap-1" (click)="attachToAssistant()">
|
|
6729
|
-
<sparkles-icon />
|
|
6859
|
+
<sparkles-icon aria-hidden="true" />
|
|
6730
6860
|
{{ 'article.addToAIOverview' | transloco }}
|
|
6731
6861
|
</button>
|
|
6732
|
-
</
|
|
6862
|
+
</div>
|
|
6733
6863
|
}
|
|
6734
|
-
</
|
|
6864
|
+
</div>
|
|
6735
6865
|
`,
|
|
6736
6866
|
isInline: true,
|
|
6737
6867
|
dependencies: [
|
|
@@ -6785,37 +6915,57 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
6785
6915
|
],
|
|
6786
6916
|
providers: [provideTranslocoScope("multi-selection-toolbar", "article", "collections", "export")],
|
|
6787
6917
|
template: `
|
|
6788
|
-
|
|
6789
|
-
|
|
6918
|
+
<!-- Région de statut hors de la barre : celle-ci est inerte sans sélection, et une région
|
|
6919
|
+
inerte n'est pas annoncée. Le texte n'existe que tant que la sélection est non vide. -->
|
|
6920
|
+
<span role="status" class="sr-only">
|
|
6921
|
+
@if (count() > 0) {
|
|
6922
|
+
{{ 'multiSelectionToolbar.itemsSelected' | transloco: { count: count() } }}
|
|
6923
|
+
@if (showHint() && hint()) {
|
|
6924
|
+
. {{ hint() }}
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
</span>
|
|
6928
|
+
|
|
6929
|
+
<!-- inert sans sélection : la barre n'est que transparente et hors écran, ses boutons resteraient
|
|
6930
|
+
sinon dans l'ordre de tabulation et activables (Entrée ouvrait « Ajouter à une collection » sur
|
|
6931
|
+
un panier vide, ES-31356). -->
|
|
6932
|
+
<div
|
|
6933
|
+
id="multi-select-toolbar"
|
|
6934
|
+
role="toolbar"
|
|
6935
|
+
[attr.aria-label]="'multiSelectionToolbar.label' | transloco"
|
|
6936
|
+
[attr.inert]="count() === 0 ? '' : null"
|
|
6937
|
+
(keydown.escape)="clearSelection()"
|
|
6938
|
+
[class]="cn(variants(), class())">
|
|
6939
|
+
<div class="ps-0!">
|
|
6790
6940
|
<button class="cursor-pointer inline-flex items-center gap-1" (click)="clearSelection()">
|
|
6791
6941
|
{{ 'multiSelectionToolbar.itemsSelected' | transloco: { count: count() } }}
|
|
6792
|
-
<x-mark-icon />
|
|
6942
|
+
<x-mark-icon aria-hidden="true" />
|
|
6793
6943
|
</button>
|
|
6794
|
-
</
|
|
6944
|
+
</div>
|
|
6795
6945
|
|
|
6796
|
-
<
|
|
6797
|
-
<button class="cursor-pointer inline-flex items-center gap-1"
|
|
6798
|
-
<inbox-icon />
|
|
6946
|
+
<div>
|
|
6947
|
+
<button class="cursor-pointer inline-flex items-center gap-1" (click)="openCollectionDialog()">
|
|
6948
|
+
<inbox-icon aria-hidden="true" />
|
|
6799
6949
|
{{ 'collections.label' | transloco }}
|
|
6800
6950
|
</button>
|
|
6801
|
-
</
|
|
6951
|
+
</div>
|
|
6802
6952
|
|
|
6803
|
-
<
|
|
6953
|
+
<div>
|
|
6804
6954
|
<button class="cursor-pointer inline-flex items-center gap-1" (click)="openExportDialog()">
|
|
6805
|
-
<file-output-icon />
|
|
6955
|
+
<file-output-icon aria-hidden="true" />
|
|
6806
6956
|
{{ 'export.title' | transloco }}
|
|
6807
6957
|
</button>
|
|
6808
|
-
</
|
|
6958
|
+
</div>
|
|
6809
6959
|
|
|
6810
|
-
@if (
|
|
6811
|
-
<
|
|
6960
|
+
@if (showAssistantAction()) {
|
|
6961
|
+
<div class="pe-0!">
|
|
6812
6962
|
<button class="cursor-pointer inline-flex items-center gap-1" (click)="attachToAssistant()">
|
|
6813
|
-
<sparkles-icon />
|
|
6963
|
+
<sparkles-icon aria-hidden="true" />
|
|
6814
6964
|
{{ 'article.addToAIOverview' | transloco }}
|
|
6815
6965
|
</button>
|
|
6816
|
-
</
|
|
6966
|
+
</div>
|
|
6817
6967
|
}
|
|
6818
|
-
</
|
|
6968
|
+
</div>
|
|
6819
6969
|
`,
|
|
6820
6970
|
host: {
|
|
6821
6971
|
class: "fixed -bottom-20 left-[50%] translate-x-[-50%] z-50 transition-[translate,opacity,discrete] duration-300 opacity-0",
|
|
@@ -6824,6 +6974,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
6824
6974
|
}
|
|
6825
6975
|
}]
|
|
6826
6976
|
}],
|
|
6977
|
+
ctorParameters: () => [],
|
|
6827
6978
|
propDecorators: {
|
|
6828
6979
|
class: [{
|
|
6829
6980
|
type: i0.Input,
|
|
@@ -6841,9 +6992,29 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
6841
6992
|
required: false
|
|
6842
6993
|
}]
|
|
6843
6994
|
}],
|
|
6995
|
+
hint: [{
|
|
6996
|
+
type: i0.Input,
|
|
6997
|
+
args: [{
|
|
6998
|
+
isSignal: true,
|
|
6999
|
+
alias: "hint",
|
|
7000
|
+
required: false
|
|
7001
|
+
}]
|
|
7002
|
+
}],
|
|
6844
7003
|
updatedCollections: [{
|
|
6845
7004
|
type: i0.Output,
|
|
6846
7005
|
args: ["updatedCollections"]
|
|
7006
|
+
}],
|
|
7007
|
+
cleared: [{
|
|
7008
|
+
type: i0.Output,
|
|
7009
|
+
args: ["cleared"]
|
|
7010
|
+
}],
|
|
7011
|
+
allowAI: [{
|
|
7012
|
+
type: i0.Input,
|
|
7013
|
+
args: [{
|
|
7014
|
+
isSignal: true,
|
|
7015
|
+
alias: "allowAI",
|
|
7016
|
+
required: false
|
|
7017
|
+
}]
|
|
6847
7018
|
}]
|
|
6848
7019
|
}
|
|
6849
7020
|
});
|
|
@@ -18727,11 +18898,18 @@ var ListPanelComponent = class ListPanelComponent {
|
|
|
18727
18898
|
getValue = input.required(...ngDevMode ? [{ debugName: "getValue" }] : /* istanbul ignore next */ []);
|
|
18728
18899
|
getLabel = input(...ngDevMode ? [void 0, { debugName: "getLabel" }] : /* istanbul ignore next */ []);
|
|
18729
18900
|
deleteButtonTitle = input("remove", ...ngDevMode ? [{ debugName: "deleteButtonTitle" }] : /* istanbul ignore next */ []);
|
|
18901
|
+
deletable = input(true, {
|
|
18902
|
+
...ngDevMode ? { debugName: "deletable" } : /* istanbul ignore next */ {},
|
|
18903
|
+
transform: booleanAttribute
|
|
18904
|
+
});
|
|
18730
18905
|
ariaLabel = input(...ngDevMode ? [void 0, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
|
|
18731
18906
|
itemClass = input("", ...ngDevMode ? [{ debugName: "itemClass" }] : /* istanbul ignore next */ []);
|
|
18732
18907
|
itemClick = output();
|
|
18733
18908
|
delete = output();
|
|
18734
18909
|
itemTemplate = contentChild(ListPanelItemDirective, ...ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []);
|
|
18910
|
+
deleteKeys = isApplePlatform() ? ["Delete", "Backspace"] : ["Delete"];
|
|
18911
|
+
list = viewChild(ListComponent, ...ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []);
|
|
18912
|
+
keyboardFocused = computed(() => this.list()?.keyboardFocused() ?? false, ...ngDevMode ? [{ debugName: "keyboardFocused" }] : /* istanbul ignore next */ []);
|
|
18735
18913
|
host = inject(ElementRef);
|
|
18736
18914
|
injector = inject(Injector);
|
|
18737
18915
|
pendingFocusIndex = signal(null, ...ngDevMode ? [{ debugName: "pendingFocusIndex" }] : /* istanbul ignore next */ []);
|
|
@@ -18807,6 +18985,13 @@ var ListPanelComponent = class ListPanelComponent {
|
|
|
18807
18985
|
isRequired: false,
|
|
18808
18986
|
transformFunction: null
|
|
18809
18987
|
},
|
|
18988
|
+
deletable: {
|
|
18989
|
+
classPropertyName: "deletable",
|
|
18990
|
+
publicName: "deletable",
|
|
18991
|
+
isSignal: true,
|
|
18992
|
+
isRequired: false,
|
|
18993
|
+
transformFunction: null
|
|
18994
|
+
},
|
|
18810
18995
|
ariaLabel: {
|
|
18811
18996
|
classPropertyName: "ariaLabel",
|
|
18812
18997
|
publicName: "ariaLabel",
|
|
@@ -18827,6 +19012,7 @@ var ListPanelComponent = class ListPanelComponent {
|
|
|
18827
19012
|
delete: "delete"
|
|
18828
19013
|
},
|
|
18829
19014
|
host: { classAttribute: "block max-h-115 overflow-auto" },
|
|
19015
|
+
providers: [provideTranslocoScope("list-panel")],
|
|
18830
19016
|
queries: [{
|
|
18831
19017
|
propertyName: "itemTemplate",
|
|
18832
19018
|
first: true,
|
|
@@ -18834,6 +19020,13 @@ var ListPanelComponent = class ListPanelComponent {
|
|
|
18834
19020
|
descendants: true,
|
|
18835
19021
|
isSignal: true
|
|
18836
19022
|
}],
|
|
19023
|
+
viewQueries: [{
|
|
19024
|
+
propertyName: "list",
|
|
19025
|
+
first: true,
|
|
19026
|
+
predicate: ListComponent,
|
|
19027
|
+
descendants: true,
|
|
19028
|
+
isSignal: true
|
|
19029
|
+
}],
|
|
18837
19030
|
ngImport: i0,
|
|
18838
19031
|
template: `
|
|
18839
19032
|
<List variant="list-navigation" size="medium" class="gap-1" selectionMode="explicit" [attr.aria-label]="ariaLabel()">
|
|
@@ -18846,9 +19039,13 @@ var ListPanelComponent = class ListPanelComponent {
|
|
|
18846
19039
|
(keydown.enter)="activate(item, $event)"
|
|
18847
19040
|
(keydown.space)="activate(item, $event)">
|
|
18848
19041
|
<ng-container *ngTemplateOutlet="itemTemplate()?.template; context: { $implicit: item }" />
|
|
18849
|
-
|
|
18850
|
-
<
|
|
18851
|
-
|
|
19042
|
+
@if (deletable()) {
|
|
19043
|
+
<ListItemAction [ariaLabel]="deleteButtonTitle() | transloco" [keys]="deleteKeys" [shortcut]="'listPanel.deleteShortcut' | transloco"
|
|
19044
|
+
[description]="'listPanel.deleteDescription' | transloco: { key: 'listPanel.deleteShortcut' | transloco }"
|
|
19045
|
+
(click)="onDelete(item, i, $event)">
|
|
19046
|
+
<TrashIcon />
|
|
19047
|
+
</ListItemAction>
|
|
19048
|
+
}
|
|
18852
19049
|
</ListItem>
|
|
18853
19050
|
} @empty {
|
|
18854
19051
|
<span class="py-4 text-center text-neutral-500">
|
|
@@ -18903,7 +19100,13 @@ var ListPanelComponent = class ListPanelComponent {
|
|
|
18903
19100
|
kind: "component",
|
|
18904
19101
|
type: ListItemActionComponent,
|
|
18905
19102
|
selector: "ListItemAction,list-item-action,listitemaction",
|
|
18906
|
-
inputs: [
|
|
19103
|
+
inputs: [
|
|
19104
|
+
"ariaLabel",
|
|
19105
|
+
"disabled",
|
|
19106
|
+
"keys",
|
|
19107
|
+
"shortcut",
|
|
19108
|
+
"description"
|
|
19109
|
+
],
|
|
18907
19110
|
exportAs: ["listItemAction"]
|
|
18908
19111
|
},
|
|
18909
19112
|
{
|
|
@@ -18923,6 +19126,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
18923
19126
|
type: Component,
|
|
18924
19127
|
args: [{
|
|
18925
19128
|
selector: "list-panel, ListPanel",
|
|
19129
|
+
providers: [provideTranslocoScope("list-panel")],
|
|
18926
19130
|
imports: [
|
|
18927
19131
|
NgTemplateOutlet,
|
|
18928
19132
|
TrashIcon,
|
|
@@ -18942,9 +19146,13 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
18942
19146
|
(keydown.enter)="activate(item, $event)"
|
|
18943
19147
|
(keydown.space)="activate(item, $event)">
|
|
18944
19148
|
<ng-container *ngTemplateOutlet="itemTemplate()?.template; context: { $implicit: item }" />
|
|
18945
|
-
|
|
18946
|
-
<
|
|
18947
|
-
|
|
19149
|
+
@if (deletable()) {
|
|
19150
|
+
<ListItemAction [ariaLabel]="deleteButtonTitle() | transloco" [keys]="deleteKeys" [shortcut]="'listPanel.deleteShortcut' | transloco"
|
|
19151
|
+
[description]="'listPanel.deleteDescription' | transloco: { key: 'listPanel.deleteShortcut' | transloco }"
|
|
19152
|
+
(click)="onDelete(item, i, $event)">
|
|
19153
|
+
<TrashIcon />
|
|
19154
|
+
</ListItemAction>
|
|
19155
|
+
}
|
|
18948
19156
|
</ListItem>
|
|
18949
19157
|
} @empty {
|
|
18950
19158
|
<span class="py-4 text-center text-neutral-500">
|
|
@@ -18991,6 +19199,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
18991
19199
|
required: false
|
|
18992
19200
|
}]
|
|
18993
19201
|
}],
|
|
19202
|
+
deletable: [{
|
|
19203
|
+
type: i0.Input,
|
|
19204
|
+
args: [{
|
|
19205
|
+
isSignal: true,
|
|
19206
|
+
alias: "deletable",
|
|
19207
|
+
required: false
|
|
19208
|
+
}]
|
|
19209
|
+
}],
|
|
18994
19210
|
ariaLabel: [{
|
|
18995
19211
|
type: i0.Input,
|
|
18996
19212
|
args: [{
|
|
@@ -19018,6 +19234,10 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
19018
19234
|
itemTemplate: [{
|
|
19019
19235
|
type: i0.ContentChild,
|
|
19020
19236
|
args: [i0.forwardRef(() => ListPanelItemDirective), { isSignal: true }]
|
|
19237
|
+
}],
|
|
19238
|
+
list: [{
|
|
19239
|
+
type: i0.ViewChild,
|
|
19240
|
+
args: [i0.forwardRef(() => ListComponent), { isSignal: true }]
|
|
19021
19241
|
}]
|
|
19022
19242
|
}
|
|
19023
19243
|
});
|
|
@@ -19027,6 +19247,10 @@ var ListPanelFooterComponent = class ListPanelFooterComponent {
|
|
|
19027
19247
|
hasMore = input.required(...ngDevMode ? [{ debugName: "hasMore" }] : /* istanbul ignore next */ []);
|
|
19028
19248
|
config = input.required(...ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []);
|
|
19029
19249
|
loadMore = output();
|
|
19250
|
+
navigationHint = input(false, {
|
|
19251
|
+
...ngDevMode ? { debugName: "navigationHint" } : /* istanbul ignore next */ {},
|
|
19252
|
+
transform: booleanAttribute
|
|
19253
|
+
});
|
|
19030
19254
|
onLoadMore(event) {
|
|
19031
19255
|
event.stopPropagation();
|
|
19032
19256
|
this.loadMore.emit();
|
|
@@ -19066,10 +19290,17 @@ var ListPanelFooterComponent = class ListPanelFooterComponent {
|
|
|
19066
19290
|
isSignal: true,
|
|
19067
19291
|
isRequired: true,
|
|
19068
19292
|
transformFunction: null
|
|
19293
|
+
},
|
|
19294
|
+
navigationHint: {
|
|
19295
|
+
classPropertyName: "navigationHint",
|
|
19296
|
+
publicName: "navigationHint",
|
|
19297
|
+
isSignal: true,
|
|
19298
|
+
isRequired: false,
|
|
19299
|
+
transformFunction: null
|
|
19069
19300
|
}
|
|
19070
19301
|
},
|
|
19071
19302
|
outputs: { loadMore: "loadMore" },
|
|
19072
|
-
host: { properties: { "class": "cn('flex flex-col px-2 mt-2', class())" } },
|
|
19303
|
+
host: { properties: { "class": "cn('flex flex-col px-2 mt-2 py-(--spacing-xs)', class())" } },
|
|
19073
19304
|
providers: [provideTranslocoScope("list-panel")],
|
|
19074
19305
|
ngImport: i0,
|
|
19075
19306
|
template: `
|
|
@@ -19080,9 +19311,33 @@ var ListPanelFooterComponent = class ListPanelFooterComponent {
|
|
|
19080
19311
|
</button>
|
|
19081
19312
|
}
|
|
19082
19313
|
@let seeMore = 'listPanel.seeMore' | transloco;
|
|
19083
|
-
<
|
|
19084
|
-
|
|
19085
|
-
|
|
19314
|
+
<div class="flex items-center gap-(--spacing-xs)">
|
|
19315
|
+
<!-- Aide de navigation de la liste, tant que navigationHint est vrai (focus clavier dans la liste) : le
|
|
19316
|
+
focus est un arrêt unique de tabulation, les flèches font le reste, et rien ne le dit.
|
|
19317
|
+
aria-hidden : le listbox annonce déjà sa navigation aux lecteurs d'écran, et l'ouverture
|
|
19318
|
+
d'une ligne est ce que tout le monde attend d'Entrée. La touche Suppr est, elle, écrite dans la
|
|
19319
|
+
ligne. -->
|
|
19320
|
+
@if (navigationHint()) {
|
|
19321
|
+
<p aria-hidden="true" class="flex min-w-0 flex-wrap items-center gap-x-(--spacing-xs) gap-y-(--spacing-4xs) text-(length:--size-sm) leading-(--line-height-2) text-(--font-neutral-base)">
|
|
19322
|
+
<span class="inline-flex items-center gap-(--spacing-2xs)">
|
|
19323
|
+
<!-- Des icônes et non les caractères ↑ ↓ : le centre visuel d'une flèche typographique ne tombe pas au
|
|
19324
|
+
milieu de la ligne de texte, et elle sortait décentrée de sa touche. -->
|
|
19325
|
+
<span class="inline-flex gap-(--spacing-4xs)">
|
|
19326
|
+
<kbd><arrow-up-icon /></kbd>
|
|
19327
|
+
<kbd><arrow-down-icon /></kbd>
|
|
19328
|
+
</span>
|
|
19329
|
+
{{ 'listPanel.hintNavigate' | transloco }}
|
|
19330
|
+
</span>
|
|
19331
|
+
<span class="inline-flex items-center gap-(--spacing-2xs)">
|
|
19332
|
+
<kbd>{{ 'listPanel.keyEnter' | transloco }}</kbd>
|
|
19333
|
+
{{ 'listPanel.hintOpen' | transloco }}
|
|
19334
|
+
</span>
|
|
19335
|
+
</p>
|
|
19336
|
+
}
|
|
19337
|
+
<button variant="secondary" size="sm" class="ml-auto shrink-0" [attr.title]="seeMore" [routerLink]="[config().routerLink]">
|
|
19338
|
+
{{ seeMore }}
|
|
19339
|
+
</button>
|
|
19340
|
+
</div>
|
|
19086
19341
|
`,
|
|
19087
19342
|
isInline: true,
|
|
19088
19343
|
dependencies: [
|
|
@@ -19117,6 +19372,24 @@ var ListPanelFooterComponent = class ListPanelFooterComponent {
|
|
|
19117
19372
|
"size"
|
|
19118
19373
|
]
|
|
19119
19374
|
},
|
|
19375
|
+
{
|
|
19376
|
+
kind: "directive",
|
|
19377
|
+
type: KbdComponent,
|
|
19378
|
+
selector: "kbd, Kbd",
|
|
19379
|
+
inputs: ["class", "size"]
|
|
19380
|
+
},
|
|
19381
|
+
{
|
|
19382
|
+
kind: "component",
|
|
19383
|
+
type: ArrowUpIcon,
|
|
19384
|
+
selector: "arrow-up, arrow-up-icon, ArrowUp, ArrowUpIcon",
|
|
19385
|
+
inputs: ["class"]
|
|
19386
|
+
},
|
|
19387
|
+
{
|
|
19388
|
+
kind: "component",
|
|
19389
|
+
type: ArrowDownIcon,
|
|
19390
|
+
selector: "arrow-down, arrow-down-icon, ArrowDown, ArrowDownIcon",
|
|
19391
|
+
inputs: ["class"]
|
|
19392
|
+
},
|
|
19120
19393
|
{
|
|
19121
19394
|
kind: "pipe",
|
|
19122
19395
|
type: TranslocoPipe,
|
|
@@ -19137,7 +19410,10 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
19137
19410
|
imports: [
|
|
19138
19411
|
TranslocoPipe,
|
|
19139
19412
|
RouterLink,
|
|
19140
|
-
ButtonComponent
|
|
19413
|
+
ButtonComponent,
|
|
19414
|
+
KbdComponent,
|
|
19415
|
+
ArrowUpIcon,
|
|
19416
|
+
ArrowDownIcon
|
|
19141
19417
|
],
|
|
19142
19418
|
providers: [provideTranslocoScope("list-panel")],
|
|
19143
19419
|
template: `
|
|
@@ -19148,11 +19424,35 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
19148
19424
|
</button>
|
|
19149
19425
|
}
|
|
19150
19426
|
@let seeMore = 'listPanel.seeMore' | transloco;
|
|
19151
|
-
<
|
|
19152
|
-
|
|
19153
|
-
|
|
19427
|
+
<div class="flex items-center gap-(--spacing-xs)">
|
|
19428
|
+
<!-- Aide de navigation de la liste, tant que navigationHint est vrai (focus clavier dans la liste) : le
|
|
19429
|
+
focus est un arrêt unique de tabulation, les flèches font le reste, et rien ne le dit.
|
|
19430
|
+
aria-hidden : le listbox annonce déjà sa navigation aux lecteurs d'écran, et l'ouverture
|
|
19431
|
+
d'une ligne est ce que tout le monde attend d'Entrée. La touche Suppr est, elle, écrite dans la
|
|
19432
|
+
ligne. -->
|
|
19433
|
+
@if (navigationHint()) {
|
|
19434
|
+
<p aria-hidden="true" class="flex min-w-0 flex-wrap items-center gap-x-(--spacing-xs) gap-y-(--spacing-4xs) text-(length:--size-sm) leading-(--line-height-2) text-(--font-neutral-base)">
|
|
19435
|
+
<span class="inline-flex items-center gap-(--spacing-2xs)">
|
|
19436
|
+
<!-- Des icônes et non les caractères ↑ ↓ : le centre visuel d'une flèche typographique ne tombe pas au
|
|
19437
|
+
milieu de la ligne de texte, et elle sortait décentrée de sa touche. -->
|
|
19438
|
+
<span class="inline-flex gap-(--spacing-4xs)">
|
|
19439
|
+
<kbd><arrow-up-icon /></kbd>
|
|
19440
|
+
<kbd><arrow-down-icon /></kbd>
|
|
19441
|
+
</span>
|
|
19442
|
+
{{ 'listPanel.hintNavigate' | transloco }}
|
|
19443
|
+
</span>
|
|
19444
|
+
<span class="inline-flex items-center gap-(--spacing-2xs)">
|
|
19445
|
+
<kbd>{{ 'listPanel.keyEnter' | transloco }}</kbd>
|
|
19446
|
+
{{ 'listPanel.hintOpen' | transloco }}
|
|
19447
|
+
</span>
|
|
19448
|
+
</p>
|
|
19449
|
+
}
|
|
19450
|
+
<button variant="secondary" size="sm" class="ml-auto shrink-0" [attr.title]="seeMore" [routerLink]="[config().routerLink]">
|
|
19451
|
+
{{ seeMore }}
|
|
19452
|
+
</button>
|
|
19453
|
+
</div>
|
|
19154
19454
|
`,
|
|
19155
|
-
host: { "[class]": "cn('flex flex-col px-2 mt-2', class())" }
|
|
19455
|
+
host: { "[class]": "cn('flex flex-col px-2 mt-2 py-(--spacing-xs)', class())" }
|
|
19156
19456
|
}]
|
|
19157
19457
|
}],
|
|
19158
19458
|
propDecorators: {
|
|
@@ -19183,6 +19483,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
19183
19483
|
loadMore: [{
|
|
19184
19484
|
type: i0.Output,
|
|
19185
19485
|
args: ["loadMore"]
|
|
19486
|
+
}],
|
|
19487
|
+
navigationHint: [{
|
|
19488
|
+
type: i0.Input,
|
|
19489
|
+
args: [{
|
|
19490
|
+
isSignal: true,
|
|
19491
|
+
alias: "navigationHint",
|
|
19492
|
+
required: false
|
|
19493
|
+
}]
|
|
19186
19494
|
}]
|
|
19187
19495
|
}
|
|
19188
19496
|
});
|
|
@@ -19368,7 +19676,7 @@ var BookmarksComponent = class BookmarksComponent {
|
|
|
19368
19676
|
} },
|
|
19369
19677
|
providers: [provideTranslocoScope("bookmarks")],
|
|
19370
19678
|
ngImport: i0,
|
|
19371
|
-
template: "<ListPanelHeader\n [label]=\"'bookmarks.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n [items]=\"paginatedBookmarks()\"\n [getValue]=\"idOf\"\n [getLabel]=\"labelOf\"\n deleteButtonTitle=\"bookmarks.removeBookmark\"\n [ariaLabel]=\"'bookmarks.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-bookmark>\n <ListItemLeft>\n <BookmarkIcon solid class=\"shrink-0\" />\n <ListItemText>{{ bookmark.label }}</ListItemText>\n </ListItemLeft>\n\n @if (bookmark.author) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <UserIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.author }}</span>\n </Tag>\n }\n @if (bookmark.parentFolder) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <FolderIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.parentFolder }}</span>\n </Tag>\n }\n </ng-template>\n\n {{ \"bookmarks.noBookmarks\" | transloco }}\n</ListPanel>\n\n@if (paginatedBookmarks().length > 0) {\n <ListPanelFooter\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n",
|
|
19679
|
+
template: "<ListPanelHeader\n [label]=\"'bookmarks.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n #panel\n [items]=\"paginatedBookmarks()\"\n [getValue]=\"idOf\"\n [getLabel]=\"labelOf\"\n deleteButtonTitle=\"bookmarks.removeBookmark\"\n [ariaLabel]=\"'bookmarks.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-bookmark>\n <ListItemLeft>\n <BookmarkIcon solid class=\"shrink-0\" />\n <ListItemText>{{ bookmark.label }}</ListItemText>\n </ListItemLeft>\n\n @if (bookmark.author) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <UserIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.author }}</span>\n </Tag>\n }\n @if (bookmark.parentFolder) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <FolderIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.parentFolder }}</span>\n </Tag>\n }\n </ng-template>\n\n {{ \"bookmarks.noBookmarks\" | transloco }}\n</ListPanel>\n\n@if (paginatedBookmarks().length > 0) {\n <ListPanelFooter\n [navigationHint]=\"panel.keyboardFocused()\"\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n",
|
|
19372
19680
|
dependencies: [
|
|
19373
19681
|
{
|
|
19374
19682
|
kind: "component",
|
|
@@ -19385,6 +19693,7 @@ var BookmarksComponent = class BookmarksComponent {
|
|
|
19385
19693
|
"getValue",
|
|
19386
19694
|
"getLabel",
|
|
19387
19695
|
"deleteButtonTitle",
|
|
19696
|
+
"deletable",
|
|
19388
19697
|
"ariaLabel",
|
|
19389
19698
|
"itemClass"
|
|
19390
19699
|
],
|
|
@@ -19397,7 +19706,8 @@ var BookmarksComponent = class BookmarksComponent {
|
|
|
19397
19706
|
inputs: [
|
|
19398
19707
|
"class",
|
|
19399
19708
|
"hasMore",
|
|
19400
|
-
"config"
|
|
19709
|
+
"config",
|
|
19710
|
+
"navigationHint"
|
|
19401
19711
|
],
|
|
19402
19712
|
outputs: ["loadMore"]
|
|
19403
19713
|
},
|
|
@@ -19479,7 +19789,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
19479
19789
|
TagComponent
|
|
19480
19790
|
],
|
|
19481
19791
|
providers: [provideTranslocoScope("bookmarks")],
|
|
19482
|
-
template: "<ListPanelHeader\n [label]=\"'bookmarks.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n [items]=\"paginatedBookmarks()\"\n [getValue]=\"idOf\"\n [getLabel]=\"labelOf\"\n deleteButtonTitle=\"bookmarks.removeBookmark\"\n [ariaLabel]=\"'bookmarks.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-bookmark>\n <ListItemLeft>\n <BookmarkIcon solid class=\"shrink-0\" />\n <ListItemText>{{ bookmark.label }}</ListItemText>\n </ListItemLeft>\n\n @if (bookmark.author) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <UserIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.author }}</span>\n </Tag>\n }\n @if (bookmark.parentFolder) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <FolderIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.parentFolder }}</span>\n </Tag>\n }\n </ng-template>\n\n {{ \"bookmarks.noBookmarks\" | transloco }}\n</ListPanel>\n\n@if (paginatedBookmarks().length > 0) {\n <ListPanelFooter\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n"
|
|
19792
|
+
template: "<ListPanelHeader\n [label]=\"'bookmarks.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n #panel\n [items]=\"paginatedBookmarks()\"\n [getValue]=\"idOf\"\n [getLabel]=\"labelOf\"\n deleteButtonTitle=\"bookmarks.removeBookmark\"\n [ariaLabel]=\"'bookmarks.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-bookmark>\n <ListItemLeft>\n <BookmarkIcon solid class=\"shrink-0\" />\n <ListItemText>{{ bookmark.label }}</ListItemText>\n </ListItemLeft>\n\n @if (bookmark.author) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <UserIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.author }}</span>\n </Tag>\n }\n @if (bookmark.parentFolder) {\n <Tag variant=\"primary\" scheme=\"sage\" size=\"xs\" class=\"gap-1\">\n <FolderIcon class=\"size-3\" />\n <span class=\"min-w-0 truncate\">{{ bookmark.parentFolder }}</span>\n </Tag>\n }\n </ng-template>\n\n {{ \"bookmarks.noBookmarks\" | transloco }}\n</ListPanel>\n\n@if (paginatedBookmarks().length > 0) {\n <ListPanelFooter\n [navigationHint]=\"panel.keyboardFocused()\"\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n"
|
|
19483
19793
|
}]
|
|
19484
19794
|
}],
|
|
19485
19795
|
ctorParameters: () => [],
|
|
@@ -19735,7 +20045,7 @@ var CollectionsComponent = class CollectionsComponent {
|
|
|
19735
20045
|
} },
|
|
19736
20046
|
providers: [provideTranslocoScope("collections")],
|
|
19737
20047
|
ngImport: i0,
|
|
19738
|
-
template: "<ListPanelHeader\n [label]=\"'collections.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n [items]=\"paginatedCollections()\"\n [getValue]=\"nameOf\"\n [getLabel]=\"nameOf\"\n deleteButtonTitle=\"collections.deleteCollection\"\n [ariaLabel]=\"'collections.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-collection>\n <ListItemLeft>\n <inbox-icon />\n <ListItemText>{{ collection.name }}</ListItemText>\n </ListItemLeft>\n </ng-template>\n\n {{ \"collections.noCollections\" | transloco }}\n</ListPanel>\n\n@if (paginatedCollections().length > 0) {\n <ListPanelFooter\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n",
|
|
20048
|
+
template: "<ListPanelHeader\n [label]=\"'collections.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n #panel\n [items]=\"paginatedCollections()\"\n [getValue]=\"nameOf\"\n [getLabel]=\"nameOf\"\n deleteButtonTitle=\"collections.deleteCollection\"\n [ariaLabel]=\"'collections.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-collection>\n <ListItemLeft>\n <inbox-icon />\n <ListItemText>{{ collection.name }}</ListItemText>\n </ListItemLeft>\n </ng-template>\n\n {{ \"collections.noCollections\" | transloco }}\n</ListPanel>\n\n@if (paginatedCollections().length > 0) {\n <ListPanelFooter\n [navigationHint]=\"panel.keyboardFocused()\"\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n",
|
|
19739
20049
|
dependencies: [
|
|
19740
20050
|
{
|
|
19741
20051
|
kind: "component",
|
|
@@ -19752,6 +20062,7 @@ var CollectionsComponent = class CollectionsComponent {
|
|
|
19752
20062
|
"getValue",
|
|
19753
20063
|
"getLabel",
|
|
19754
20064
|
"deleteButtonTitle",
|
|
20065
|
+
"deletable",
|
|
19755
20066
|
"ariaLabel",
|
|
19756
20067
|
"itemClass"
|
|
19757
20068
|
],
|
|
@@ -19764,7 +20075,8 @@ var CollectionsComponent = class CollectionsComponent {
|
|
|
19764
20075
|
inputs: [
|
|
19765
20076
|
"class",
|
|
19766
20077
|
"hasMore",
|
|
19767
|
-
"config"
|
|
20078
|
+
"config",
|
|
20079
|
+
"navigationHint"
|
|
19768
20080
|
],
|
|
19769
20081
|
outputs: ["loadMore"]
|
|
19770
20082
|
},
|
|
@@ -19820,7 +20132,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
19820
20132
|
ListItemTextComponent
|
|
19821
20133
|
],
|
|
19822
20134
|
providers: [provideTranslocoScope("collections")],
|
|
19823
|
-
template: "<ListPanelHeader\n [label]=\"'collections.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n [items]=\"paginatedCollections()\"\n [getValue]=\"nameOf\"\n [getLabel]=\"nameOf\"\n deleteButtonTitle=\"collections.deleteCollection\"\n [ariaLabel]=\"'collections.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-collection>\n <ListItemLeft>\n <inbox-icon />\n <ListItemText>{{ collection.name }}</ListItemText>\n </ListItemLeft>\n </ng-template>\n\n {{ \"collections.noCollections\" | transloco }}\n</ListPanel>\n\n@if (paginatedCollections().length > 0) {\n <ListPanelFooter\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n"
|
|
20135
|
+
template: "<ListPanelHeader\n [label]=\"'collections.label' | transloco\"\n [floating]=\"!!floating\" />\n\n<ListPanel\n #panel\n [items]=\"paginatedCollections()\"\n [getValue]=\"nameOf\"\n [getLabel]=\"nameOf\"\n deleteButtonTitle=\"collections.deleteCollection\"\n [ariaLabel]=\"'collections.label' | transloco\"\n (itemClick)=\"onClick($event)\"\n (delete)=\"onDelete($event)\">\n <ng-template listPanelItem let-collection>\n <ListItemLeft>\n <inbox-icon />\n <ListItemText>{{ collection.name }}</ListItemText>\n </ListItemLeft>\n </ng-template>\n\n {{ \"collections.noCollections\" | transloco }}\n</ListPanel>\n\n@if (paginatedCollections().length > 0) {\n <ListPanelFooter\n [navigationHint]=\"panel.keyboardFocused()\"\n [hasMore]=\"hasMore()\"\n [config]=\"config\"\n (loadMore)=\"loadMore()\" />\n}\n"
|
|
19824
20136
|
}]
|
|
19825
20137
|
}],
|
|
19826
20138
|
ctorParameters: () => [],
|
|
@@ -22795,6 +23107,7 @@ var AggregationDateComponent = class AggregationDateComponent {
|
|
|
22795
23107
|
uid = nextAggregationDateId++;
|
|
22796
23108
|
startId = `datepicker-range-start-${this.uid}`;
|
|
22797
23109
|
endId = `datepicker-range-end-${this.uid}`;
|
|
23110
|
+
class = input("", ...ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []);
|
|
22798
23111
|
name = input(null, ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
|
|
22799
23112
|
column = input.required(...ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []);
|
|
22800
23113
|
id = input(null, ...ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []);
|
|
@@ -23281,6 +23594,13 @@ var AggregationDateComponent = class AggregationDateComponent {
|
|
|
23281
23594
|
isStandalone: true,
|
|
23282
23595
|
selector: "aggregation-date, AggregationDate, aggregationdate",
|
|
23283
23596
|
inputs: {
|
|
23597
|
+
class: {
|
|
23598
|
+
classPropertyName: "class",
|
|
23599
|
+
publicName: "class",
|
|
23600
|
+
isSignal: true,
|
|
23601
|
+
isRequired: false,
|
|
23602
|
+
transformFunction: null
|
|
23603
|
+
},
|
|
23284
23604
|
name: {
|
|
23285
23605
|
classPropertyName: "name",
|
|
23286
23606
|
publicName: "name",
|
|
@@ -23396,10 +23716,10 @@ var AggregationDateComponent = class AggregationDateComponent {
|
|
|
23396
23716
|
aggregationOverridesChange: "aggregationOverridesChange",
|
|
23397
23717
|
searchText: "searchTextChange"
|
|
23398
23718
|
},
|
|
23399
|
-
host: { properties: { "class": "cn(\"@container
|
|
23719
|
+
host: { properties: { "class": "cn(\"@container flex h-[inherit] max-h-[inherit] flex-col\", class(), isEmpty() && \"hidden\")" } },
|
|
23400
23720
|
providers: [provideTranslocoScope("filters")],
|
|
23401
23721
|
ngImport: i0,
|
|
23402
|
-
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion). A facet is a\n disclosure, not a grid row: see `aggregation-panel.html` for the why (same pattern, duplicated here\n since this facet type doesn't go through `AggregationPanelComponent`). The `<summary>` itself is\n `tabindex=\"-1\"`: the header's buttons (apply, clear, chevron) are the keyboard stops, see the\n chevron below. -->\n<details
|
|
23722
|
+
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion). A facet is a\n disclosure, not a grid row: see `aggregation-panel.html` for the why (same pattern, duplicated here\n since this facet type doesn't go through `AggregationPanelComponent`). The `<summary>` itself is\n `tabindex=\"-1\"`: the header's buttons (apply, clear, chevron) are the keyboard stops, see the\n chevron below. -->\n<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col space-y-2 details-content:flex details-content:min-h-0 details-content:flex-1 details-content:flex-col\">\n <!-- scroll-mb-3/scroll-mt-16: see aggregation-panel-row.html for the full rationale\n (bottom margin against the container's edge, much bigger top margin to also clear\n <More>'s sticky facet-name search box when navigating ArrowUp). -->\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible()\"\n [class]=\"rowStateClass\"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 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=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0\"\n [aria-label]=\"clearLabel\"\n [tooltip]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon class=\"shrink-0\" />\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 class=\"overflow-hidden\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon class=\"shrink-0\" />\n <span class=\"truncate\">{{ label }}</span>\n </button>\n }\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [aria-label]=\"'filters.toggle' | transloco\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n </button>\n }\n </summary>\n\n <!-- content wrapper -->\n <!-- RGAA 11.5 / WCAG 1.3.1: the radios below all share one `name`, so they are one set\n and have to be exposed as one. `role=\"group\"` here rather than `role=\"radiogroup\"`\n on the list: a radiogroup owns its radios directly, and the <li> in between would be\n invalid owned children — the list would also stop announcing how many options it\n holds. The name is the aggregation's own title, the words the header already shows;\n with no title the group stays unnamed rather than carrying an empty label. -->\n @let groupName = aggregation()?.display;\n <form\n class=\"flex min-h-0 flex-1 flex-col\"\n (keydown.enter)=\"onOptionEnter($event)\">\n <div\n class=\"flex min-h-0 flex-1 flex-col\"\n role=\"group\"\n [attr.aria-label]=\"groupName ? (groupName | syslang | transloco) : null\">\n <ul\n class=\"flex min-h-0 flex-1 snap-y snap-start scrollbar-thin flex-col gap-0.5 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track option.display) {\n <li\n role=\"listitem\"\n [attr.aria-label]=\"\n maskedLabel(option) ?? (option.display | syslang | transloco)\n \"\n [class]=\"\n cn(\n itemStateClass,\n 'flex cursor-pointer items-center p-2 text-sm text-(--font-neutral-base) select-none',\n dateModel().option === option.display &&\n 'bg-(--bg-primary-lighter)',\n option.hidden && 'hidden',\n option.disabled && 'pointer-events-none opacity-40'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <radio\n name=\"date-filter\"\n class=\"grow\"\n [checked]=\"dateModel().option === option.display\"\n [disabled]=\"option.disabled\"\n (checkedChange)=\"selectOption(option.display)\">\n {{\n maskedLabel(option) ?? (option.display | syslang | transloco)\n }}\n </radio>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n [class]=\"\n cn(\n itemStateClass,\n 'flex cursor-pointer items-center gap-(--spacing-xs) p-2 text-sm text-(--font-neutral-base) select-none',\n dateModel().option === 'custom-range' &&\n 'bg-(--bg-primary-lighter)'\n )\n \">\n <radio\n name=\"date-filter\"\n class=\"grow items-center\"\n [checked]=\"dateModel().option === 'custom-range'\"\n (checkedChange)=\"selectOption('custom-range')\">\n <div class=\"flex flex-wrap items-center gap-x-1 gap-y-1\">\n <div class=\"flex items-center gap-1\">\n <label\n [attr.for]=\"startId\"\n class=\"radio-label min-w-8 truncate\"\n >{{ \"filters.from\" | transloco }}</label\n >\n <input-group\n class=\"h-8 max-w-[18ch] min-w-[18ch] has-[[readonly]]:border-(--stroke-primary-muted)\">\n <input\n input-control\n [id]=\"startId\"\n name=\"start\"\n type=\"text\"\n readonly\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\"\n (keydown.enter)=\"onRangeInputEnter($event)\" />\n </input-group>\n </div>\n <div class=\"flex items-center gap-1\">\n <label\n [attr.for]=\"endId\"\n class=\"radio-label min-w-8 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input-group\n class=\"h-8 max-w-[18ch] min-w-[18ch] has-[[readonly]]:border-(--stroke-primary-muted)\">\n <input\n input-control\n [id]=\"endId\"\n name=\"end\"\n type=\"text\"\n readonly\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\"\n (keydown.enter)=\"onRangeInputEnter($event)\" />\n </input-group>\n </div>\n </div>\n </radio>\n </li>\n }\n </ul>\n </div>\n </form>\n</details>\n",
|
|
23403
23723
|
styles: [":host{min-width:200px}ul[role=list]{scrollbar-width:thin}\n"],
|
|
23404
23724
|
dependencies: [
|
|
23405
23725
|
{
|
|
@@ -23533,13 +23853,21 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
23533
23853
|
RadioComponent,
|
|
23534
23854
|
TooltipDirective
|
|
23535
23855
|
],
|
|
23536
|
-
host: { "[class]": "cn(\"@container
|
|
23537
|
-
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion). A facet is a\n disclosure, not a grid row: see `aggregation-panel.html` for the why (same pattern, duplicated here\n since this facet type doesn't go through `AggregationPanelComponent`). The `<summary>` itself is\n `tabindex=\"-1\"`: the header's buttons (apply, clear, chevron) are the keyboard stops, see the\n chevron below. -->\n<details
|
|
23856
|
+
host: { "[class]": "cn(\"@container flex h-[inherit] max-h-[inherit] flex-col\", class(), isEmpty() && \"hidden\")" },
|
|
23857
|
+
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion). A facet is a\n disclosure, not a grid row: see `aggregation-panel.html` for the why (same pattern, duplicated here\n since this facet type doesn't go through `AggregationPanelComponent`). The `<summary>` itself is\n `tabindex=\"-1\"`: the header's buttons (apply, clear, chevron) are the keyboard stops, see the\n chevron below. -->\n<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col space-y-2 details-content:flex details-content:min-h-0 details-content:flex-1 details-content:flex-col\">\n <!-- scroll-mb-3/scroll-mt-16: see aggregation-panel-row.html for the full rationale\n (bottom margin against the container's edge, much bigger top margin to also clear\n <More>'s sticky facet-name search box when navigating ArrowUp). -->\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible()\"\n [class]=\"rowStateClass\"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 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=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0\"\n [aria-label]=\"clearLabel\"\n [tooltip]=\"clearLabel\"\n (click)=\"$event.stopPropagation(); clear()\">\n <filter-x-icon class=\"shrink-0\" />\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 class=\"overflow-hidden\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); apply()\">\n <FilterIcon class=\"shrink-0\" />\n <span class=\"truncate\">{{ label }}</span>\n </button>\n }\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [aria-label]=\"'filters.toggle' | transloco\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n </button>\n }\n </summary>\n\n <!-- content wrapper -->\n <!-- RGAA 11.5 / WCAG 1.3.1: the radios below all share one `name`, so they are one set\n and have to be exposed as one. `role=\"group\"` here rather than `role=\"radiogroup\"`\n on the list: a radiogroup owns its radios directly, and the <li> in between would be\n invalid owned children — the list would also stop announcing how many options it\n holds. The name is the aggregation's own title, the words the header already shows;\n with no title the group stays unnamed rather than carrying an empty label. -->\n @let groupName = aggregation()?.display;\n <form\n class=\"flex min-h-0 flex-1 flex-col\"\n (keydown.enter)=\"onOptionEnter($event)\">\n <div\n class=\"flex min-h-0 flex-1 flex-col\"\n role=\"group\"\n [attr.aria-label]=\"groupName ? (groupName | syslang | transloco) : null\">\n <ul\n class=\"flex min-h-0 flex-1 snap-y snap-start scrollbar-thin flex-col gap-0.5 overflow-auto pt-2\"\n role=\"list\">\n @for (option of dateOptions(); track option.display) {\n <li\n role=\"listitem\"\n [attr.aria-label]=\"\n maskedLabel(option) ?? (option.display | syslang | transloco)\n \"\n [class]=\"\n cn(\n itemStateClass,\n 'flex cursor-pointer items-center p-2 text-sm text-(--font-neutral-base) select-none',\n dateModel().option === option.display &&\n 'bg-(--bg-primary-lighter)',\n option.hidden && 'hidden',\n option.disabled && 'pointer-events-none opacity-40'\n )\n \"\n [attr.aria-hidden]=\"option.disabled\">\n <radio\n name=\"date-filter\"\n class=\"grow\"\n [checked]=\"dateModel().option === option.display\"\n [disabled]=\"option.disabled\"\n (checkedChange)=\"selectOption(option.display)\">\n {{\n maskedLabel(option) ?? (option.display | syslang | transloco)\n }}\n </radio>\n </li>\n }\n\n @if (allowCustomRange) {\n <li\n role=\"listitem\"\n aria-label=\"open date range picker\"\n [class]=\"\n cn(\n itemStateClass,\n 'flex cursor-pointer items-center gap-(--spacing-xs) p-2 text-sm text-(--font-neutral-base) select-none',\n dateModel().option === 'custom-range' &&\n 'bg-(--bg-primary-lighter)'\n )\n \">\n <radio\n name=\"date-filter\"\n class=\"grow items-center\"\n [checked]=\"dateModel().option === 'custom-range'\"\n (checkedChange)=\"selectOption('custom-range')\">\n <div class=\"flex flex-wrap items-center gap-x-1 gap-y-1\">\n <div class=\"flex items-center gap-1\">\n <label\n [attr.for]=\"startId\"\n class=\"radio-label min-w-8 truncate\"\n >{{ \"filters.from\" | transloco }}</label\n >\n <input-group\n class=\"h-8 max-w-[18ch] min-w-[18ch] has-[[readonly]]:border-(--stroke-primary-muted)\">\n <input\n input-control\n [id]=\"startId\"\n name=\"start\"\n type=\"text\"\n readonly\n [value]=\"customRangeFrom()\"\n (click)=\"selectAndOpenDialog()\"\n (keydown.enter)=\"onRangeInputEnter($event)\" />\n </input-group>\n </div>\n <div class=\"flex items-center gap-1\">\n <label\n [attr.for]=\"endId\"\n class=\"radio-label min-w-8 truncate text-right\"\n >{{ \"filters.to\" | transloco }}</label\n >\n <input-group\n class=\"h-8 max-w-[18ch] min-w-[18ch] has-[[readonly]]:border-(--stroke-primary-muted)\">\n <input\n input-control\n [id]=\"endId\"\n name=\"end\"\n type=\"text\"\n readonly\n [value]=\"customRangeTo()\"\n (click)=\"selectAndOpenDialog()\"\n (keydown.enter)=\"onRangeInputEnter($event)\" />\n </input-group>\n </div>\n </div>\n </radio>\n </li>\n }\n </ul>\n </div>\n </form>\n</details>\n",
|
|
23538
23858
|
styles: [":host{min-width:200px}ul[role=list]{scrollbar-width:thin}\n"]
|
|
23539
23859
|
}]
|
|
23540
23860
|
}],
|
|
23541
23861
|
ctorParameters: () => [],
|
|
23542
23862
|
propDecorators: {
|
|
23863
|
+
class: [{
|
|
23864
|
+
type: i0.Input,
|
|
23865
|
+
args: [{
|
|
23866
|
+
isSignal: true,
|
|
23867
|
+
alias: "class",
|
|
23868
|
+
required: false
|
|
23869
|
+
}]
|
|
23870
|
+
}],
|
|
23543
23871
|
name: [{
|
|
23544
23872
|
type: i0.Input,
|
|
23545
23873
|
args: [{
|
|
@@ -23865,6 +24193,7 @@ var AggregationPanelComponent = class AggregationPanelComponent {
|
|
|
23865
24193
|
allUnselected: "allUnselected",
|
|
23866
24194
|
loadedMore: "loadedMore"
|
|
23867
24195
|
},
|
|
24196
|
+
host: { classAttribute: "flex min-h-0 flex-1 flex-col" },
|
|
23868
24197
|
providers: [provideTranslocoScope("filters")],
|
|
23869
24198
|
viewQueries: [{
|
|
23870
24199
|
propertyName: "searchBox",
|
|
@@ -23874,7 +24203,7 @@ var AggregationPanelComponent = class AggregationPanelComponent {
|
|
|
23874
24203
|
isSignal: true
|
|
23875
24204
|
}],
|
|
23876
24205
|
ngImport: i0,
|
|
23877
|
-
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's buttons (apply, clear,\n select-all, chevron), never the header row, and the chevron is the keyboard way to collapse.\n Label, header actions and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #labelSlot>\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</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" 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=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon class=\"shrink-0\" />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"overflow-hidden\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon class=\"shrink-0\" />\n <span class=\"truncate\">{{ label }}</span>\n </button>\n }\n\n <!-- Nothing is projected into this box, so it had no accessible name at all (RGAA 11.1) —\n only its position next to the facet's title said what it selects. The name is stable\n whichever way it is about to act: `aria-checked` (true / mixed / false) is what tells the\n user where the selection stands. -->\n <checkbox\n class=\"shrink-0\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection() && !isAllSelected()\"\n [aria-label]=\"'filters.selectAllFilters' | transloco\"\n (checkedChange)=\"$event ? allSelected.emit() : allUnselected.emit()\" />\n }\n\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div>\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <!-- No `hotkey`: this field is one of many facet search boxes on the page, so it must not\n advertise a global shortcut. It used to pass `''` to neutralize SearchInput's old\n `\"shift+/\"` default, which left an empty `aria-keyshortcuts` attribute behind; the default\n is gone, so omitting the input is enough. -->\n <!-- A placeholder is not a label (RGAA 11.1): it goes away on the first keystroke, and it is\n the same word in every facet panel of the page. The name says WHICH facet this box\n filters — the one thing that tells a dozen identical fields apart. -->\n <!-- mt-2: without it, the search box sits flush under <summary>, and the header's focus ring reads as touching it. -->\n <SearchInput\n class=\"mt-2 mb-3\"\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\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 </div>\n</ng-template>\n\n<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group p-0.5\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"(isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\"\n class=\"m-0 flex h-8 w-full scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n</details>\n",
|
|
24206
|
+
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's buttons (apply, clear,\n select-all, chevron), never the header row, and the chevron is the keyboard way to collapse.\n Label, header actions and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #labelSlot>\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</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" 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=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon class=\"shrink-0\" />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"overflow-hidden\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon class=\"shrink-0\" />\n <span class=\"truncate\">{{ label }}</span>\n </button>\n }\n\n <!-- Nothing is projected into this box, so it had no accessible name at all (RGAA 11.1) —\n only its position next to the facet's title said what it selects. The name is stable\n whichever way it is about to act: `aria-checked` (true / mixed / false) is what tells the\n user where the selection stands. -->\n <checkbox\n class=\"shrink-0\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection() && !isAllSelected()\"\n [aria-label]=\"'filters.selectAllFilters' | transloco\"\n (checkedChange)=\"$event ? allSelected.emit() : allUnselected.emit()\" />\n }\n\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div class=\"flex min-h-0 flex-1 flex-col\">\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <!-- No `hotkey`: this field is one of many facet search boxes on the page, so it must not\n advertise a global shortcut. It used to pass `''` to neutralize SearchInput's old\n `\"shift+/\"` default, which left an empty `aria-keyshortcuts` attribute behind; the default\n is gone, so omitting the input is enough. -->\n <!-- A placeholder is not a label (RGAA 11.1): it goes away on the first keystroke, and it is\n the same word in every facet panel of the page. The name says WHICH facet this box\n filters — the one thing that tells a dozen identical fields apart. -->\n <!-- mt-2: without it, the search box sits flush under <summary>, and the header's focus ring reads as touching it. -->\n <SearchInput\n class=\"mt-2 mb-3 shrink-0\"\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full shrink-0 justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n </div>\n</ng-template>\n\n<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col p-0.5 details-content:flex details-content:min-h-0 details-content:flex-1 details-content:flex-col\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"(isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n</details>\n",
|
|
23878
24207
|
dependencies: [
|
|
23879
24208
|
{
|
|
23880
24209
|
kind: "directive",
|
|
@@ -24017,7 +24346,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
24017
24346
|
TooltipDirective
|
|
24018
24347
|
],
|
|
24019
24348
|
providers: [provideTranslocoScope("filters")],
|
|
24020
|
-
|
|
24349
|
+
host: { class: "flex min-h-0 flex-1 flex-col" },
|
|
24350
|
+
template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's buttons (apply, clear,\n select-all, chevron), never the header row, and the chevron is the keyboard way to collapse.\n Label, header actions and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #labelSlot>\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</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" 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=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); cleared.emit()\">\n <filter-x-icon class=\"shrink-0\" />\n </button>\n }\n @if (selection()) {\n @let label = \"filters.apply\" | transloco;\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"overflow-hidden\"\n [aria-label]=\"label\"\n [tooltip]=\"label\"\n (click)=\"$event.stopPropagation(); applied.emit()\">\n <FilterIcon class=\"shrink-0\" />\n <span class=\"truncate\">{{ label }}</span>\n </button>\n }\n\n <!-- Nothing is projected into this box, so it had no accessible name at all (RGAA 11.1) —\n only its position next to the facet's title said what it selects. The name is stable\n whichever way it is about to act: `aria-checked` (true / mixed / false) is what tells the\n user where the selection stands. -->\n <checkbox\n class=\"shrink-0\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selection() && !isAllSelected()\"\n [aria-label]=\"'filters.selectAllFilters' | transloco\"\n (checkedChange)=\"$event ? allSelected.emit() : allUnselected.emit()\" />\n }\n\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div class=\"flex min-h-0 flex-1 flex-col\">\n @if (aggregation()?.searchable && itemsLength() > 0) {\n <!-- No `hotkey`: this field is one of many facet search boxes on the page, so it must not\n advertise a global shortcut. It used to pass `''` to neutralize SearchInput's old\n `\"shift+/\"` default, which left an empty `aria-keyshortcuts` attribute behind; the default\n is gone, so omitting the input is enough. -->\n <!-- A placeholder is not a label (RGAA 11.1): it goes away on the first keystroke, and it is\n the same word in every facet panel of the page. The name says WHICH facet this box\n filters — the one thing that tells a dozen identical fields apart. -->\n <!-- mt-2: without it, the search box sits flush under <summary>, and the header's focus ring reads as touching it. -->\n <SearchInput\n class=\"mt-2 mb-3 shrink-0\"\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full shrink-0 justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n </div>\n</ng-template>\n\n<details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col p-0.5 details-content:flex details-content:min-h-0 details-content:flex-1 details-content:flex-col\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"(isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n</details>\n"
|
|
24021
24351
|
}]
|
|
24022
24352
|
}],
|
|
24023
24353
|
ctorParameters: () => [],
|
|
@@ -24848,7 +25178,7 @@ var AggregationTreeComponent = class AggregationTreeComponent {
|
|
|
24848
25178
|
filtersChange: "filtersChange",
|
|
24849
25179
|
searchText: "searchTextChange"
|
|
24850
25180
|
},
|
|
24851
|
-
host: { properties: { "class": "cn(\"
|
|
25181
|
+
host: { properties: { "class": "cn(\"flex h-[inherit] max-h-[inherit] flex-col\", class(), (isMissing() || (hideWhenEmpty() && isHidden())) && \"hidden\")" } },
|
|
24852
25182
|
queries: [{
|
|
24853
25183
|
propertyName: "itemDirective",
|
|
24854
25184
|
first: true,
|
|
@@ -24857,7 +25187,7 @@ var AggregationTreeComponent = class AggregationTreeComponent {
|
|
|
24857
25187
|
isSignal: true
|
|
24858
25188
|
}],
|
|
24859
25189
|
ngImport: i0,
|
|
24860
|
-
template: "@if (!aggregation()?.isTree) {\n <div role=\"alert\" class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\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 class=\"max-h-(--scroll-height,20rem) w-full scrollbar-thin overflow-auto pb-3\">\n <ul\n ngTree\n #tree=\"ngTree\"\n [multi]=\"true\"\n [(value)]=\"selected\"\n (valueChange)=\"onSelectionChange($event)\"\n /* Translated like the flat list's own label (aggregation-list.html): this was the raw\n `display`, so the accessible name of a whole facet came out in the source language.\n The pipes apply to the whole nullish chain, `|` being the loosest operator Angular\n parses — no parentheses needed. */\n [attr.aria-label]=\"aggregation()?.display ?? name() | syslang | transloco\"\n class=\"basic-tree m-1\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: nodes(), parent: tree }\" />\n </ul>\n </div>\n</aggregation-panel>\n\n<ng-template #treeNodes let-nodes=\"nodes\" let-parent=\"parent\">\n @for (node of nodes; track node.$path) {\n @let label = node.display ?? node.value ?? \"\";\n <li\n ngTreeItem\n #treeItem=\"ngTreeItem\"\n [parent]=\"parent\"\n [value]=\"node.$path\"\n [label]=\"label\"\n [disabled]=\"node.disabled\"\n [(expanded)]=\"node.$opened\"\n (expandedChange)=\"onExpandedChange(node, $event)\"\n [attr.aria-label]=\"label\"\n [attr.aria-describedby]=\"\n nodeDescription(node) ? descriptionId(node.$path) : null\n \"\n [class]=\"cn('m-0 block w-full p-0', itemStateClass)\"\n (keydown.enter)=\"onTreeItemEnterKey(node, $event)\"\n (keydown.space)=\"onTreeItemSpaceKey(node, $event)\">\n <!-- 2. Ce div prend tout l'espace et intercepte tous les clics de la ligne -->\n <div\n class=\"flex w-full cursor-pointer items-center gap-2 py-0.5 text-sm leading-6\"\n (click)=\"onTreeItemRowClick(node, $event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\">\n @if (showCheckbox()) {\n <!-- `inert` keeps the native input out of the tab order and out of hit-testing:\n a role=\"treeitem\" admits no focusable descendant, and the click must reach\n the row handler above. Selection is announced by the <li>'s aria-selected. -->\n <!-- --spacing-xs: 0 kills the gap the checkbox keeps between its box and its\n (here empty) text block. Set as a custom property rather than a utility\n class: the CVA already sets gap-(--spacing-xs), and two same-specificity\n classes would be resolved by stylesheet order, not by us. -->\n <span\n inert\n aria-hidden=\"true\"\n class=\"inline-flex shrink-0\"\n style=\"--spacing-xs: 0\">\n <checkbox\n [checked]=\"treeItem.selected() || node.$selectedVisually || false\"\n [disabled]=\"node.disabled\"\n [class]=\"\n cn(\n 'pointer-events-none',\n (treeItem.selected() || node.$selectedVisually) &&\n 'selected-icon'\n )\n \" />\n </span>\n }\n <!-- Depth indent sits on the chevron, after the checkbox: the checkboxes of every\n level stay flush left (aligned with a flat list's), and since this adds no extra\n flex child, the step between consecutive levels is exactly one indent. -->\n @let depthIndent =\n \"calc(var(--agg-tree-indent, 0.5rem) * \" +\n (treeItem.level() - 1) +\n \")\";\n @if (node.hasChildren) {\n <!-- Expand/collapse affordance for the mouse only, hence a <span> and not a <button>:\n the keyboard already expands with ArrowRight / ArrowLeft, handled by ngTreeItem, and\n a role=\"treeitem\" admits no focusable descendant — so this was a <button> nobody\n could reach, already carrying aria-hidden and tabindex=\"-1\" to say so. Every audit\n reads it as a button with no accessible name (RGAA 7.1, 11.9). Same shape as the leaf\n branch below. -->\n <span\n aria-hidden=\"true\"\n (click)=\"toggleTreeNode(treeItem, $event)\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex cursor-pointer items-center justify-center\">\n <ChevronRightIcon\n [class]=\"\n cn('expand-icon shrink-0', node.$opened && 'rotate-90')\n \" />\n <FolderIcon class=\"shrink-0\" />\n </span>\n } @else {\n <span\n aria-hidden=\"true\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex items-center justify-center\">\n <!-- Reserves the chevron's own width (`.expand-icon` is a styling hook with\n no rule of its own), so a leaf lines up with its parent nodes. -->\n <span class=\"expand-icon w-4 shrink-0\"></span>\n <FileIcon class=\"size-4 shrink-0\" />\n </span>\n }\n @if (resolvedItemTemplate(); as tpl) {\n <span\n class=\"grow truncate select-none\"\n (click)=\"onTreeItemTextClick(node, $event)\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: aggregation()?.column,\n selected: treeItem.selected() ?? false,\n count: node.count,\n name: label,\n searchText: searchText(),\n level: node.$level ?? 0,\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n </span>\n } @else {\n <!-- ce span est essentiel pour le style -->\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'grow truncate select-none',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n label\n : label\n \"\n (click)=\"onTreeItemTextClick(node, $event)\">\n @for (\n chunk of label | 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\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n @let description = nodeDescription(node);\n @if (description) {\n <!-- `hidden`, not `sr-only`: read through aria-describedby only. A visually-hidden\n span would also be counted in the treeitem's name (computed from its content). -->\n <span hidden [id]=\"descriptionId(node.$path)\">{{ description }}</span>\n }\n </div>\n </li>\n @if (node.hasChildren) {\n <!-- No indentation here: it would shift the checkbox too. Depth is applied\n inside the row, after the checkbox, so every checkbox stays flush left. -->\n <!-- The <ul> sits INSIDE the deferred content, not around it: `ngTreeItemGroup` only\n instantiates its view when the node opens, so a <ul> declared outside stayed in the DOM,\n empty, for every collapsed node — a structural tag with nothing to structure (RGAA 8.9).\n The @if cannot move onto the <ul> either: the directive registers itself with its tree\n item on init and has to exist for as long as the item does. -->\n <ng-template\n ngTreeItemGroup\n [ownedBy]=\"treeItem\"\n #group=\"ngTreeItemGroup\">\n <ul role=\"group\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: node.items, parent: group }\" />\n </ul>\n </ng-template>\n }\n }\n</ng-template>\n",
|
|
25190
|
+
template: "@if (!aggregation()?.isTree) {\n <div role=\"alert\" class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\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 class=\"min-h-0 w-full flex-1 scrollbar-thin overflow-auto pb-3\">\n <ul\n ngTree\n #tree=\"ngTree\"\n [multi]=\"true\"\n [(value)]=\"selected\"\n (valueChange)=\"onSelectionChange($event)\"\n /* Translated like the flat list's own label (aggregation-list.html): this was the raw\n `display`, so the accessible name of a whole facet came out in the source language.\n The pipes apply to the whole nullish chain, `|` being the loosest operator Angular\n parses — no parentheses needed. */\n [attr.aria-label]=\"aggregation()?.display ?? name() | syslang | transloco\"\n class=\"basic-tree m-1\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: nodes(), parent: tree }\" />\n </ul>\n </div>\n</aggregation-panel>\n\n<ng-template #treeNodes let-nodes=\"nodes\" let-parent=\"parent\">\n @for (node of nodes; track node.$path) {\n @let label = node.display ?? node.value ?? \"\";\n <li\n ngTreeItem\n #treeItem=\"ngTreeItem\"\n [parent]=\"parent\"\n [value]=\"node.$path\"\n [label]=\"label\"\n [disabled]=\"node.disabled\"\n [(expanded)]=\"node.$opened\"\n (expandedChange)=\"onExpandedChange(node, $event)\"\n [attr.aria-label]=\"label\"\n [attr.aria-describedby]=\"\n nodeDescription(node) ? descriptionId(node.$path) : null\n \"\n [class]=\"cn('m-0 block w-full p-0', itemStateClass)\"\n (keydown.enter)=\"onTreeItemEnterKey(node, $event)\"\n (keydown.space)=\"onTreeItemSpaceKey(node, $event)\">\n <!-- 2. Ce div prend tout l'espace et intercepte tous les clics de la ligne -->\n <div\n class=\"flex w-full cursor-pointer items-center gap-2 py-0.5 text-sm leading-6\"\n (click)=\"onTreeItemRowClick(node, $event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\">\n @if (showCheckbox()) {\n <!-- `inert` keeps the native input out of the tab order and out of hit-testing:\n a role=\"treeitem\" admits no focusable descendant, and the click must reach\n the row handler above. Selection is announced by the <li>'s aria-selected. -->\n <!-- --spacing-xs: 0 kills the gap the checkbox keeps between its box and its\n (here empty) text block. Set as a custom property rather than a utility\n class: the CVA already sets gap-(--spacing-xs), and two same-specificity\n classes would be resolved by stylesheet order, not by us. -->\n <span\n inert\n aria-hidden=\"true\"\n class=\"inline-flex shrink-0\"\n style=\"--spacing-xs: 0\">\n <checkbox\n [checked]=\"treeItem.selected() || node.$selectedVisually || false\"\n [disabled]=\"node.disabled\"\n [class]=\"\n cn(\n 'pointer-events-none',\n (treeItem.selected() || node.$selectedVisually) &&\n 'selected-icon'\n )\n \" />\n </span>\n }\n <!-- Depth indent sits on the chevron, after the checkbox: the checkboxes of every\n level stay flush left (aligned with a flat list's), and since this adds no extra\n flex child, the step between consecutive levels is exactly one indent. -->\n @let depthIndent =\n \"calc(var(--agg-tree-indent, 0.5rem) * \" +\n (treeItem.level() - 1) +\n \")\";\n @if (node.hasChildren) {\n <!-- Expand/collapse affordance for the mouse only, hence a <span> and not a <button>:\n the keyboard already expands with ArrowRight / ArrowLeft, handled by ngTreeItem, and\n a role=\"treeitem\" admits no focusable descendant — so this was a <button> nobody\n could reach, already carrying aria-hidden and tabindex=\"-1\" to say so. Every audit\n reads it as a button with no accessible name (RGAA 7.1, 11.9). Same shape as the leaf\n branch below. -->\n <span\n aria-hidden=\"true\"\n (click)=\"toggleTreeNode(treeItem, $event)\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex cursor-pointer items-center justify-center\">\n <ChevronRightIcon\n [class]=\"\n cn('expand-icon shrink-0', node.$opened && 'rotate-90')\n \" />\n <FolderIcon class=\"shrink-0\" />\n </span>\n } @else {\n <span\n aria-hidden=\"true\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex items-center justify-center\">\n <!-- Reserves the chevron's own width (`.expand-icon` is a styling hook with\n no rule of its own), so a leaf lines up with its parent nodes. -->\n <span class=\"expand-icon w-4 shrink-0\"></span>\n <FileIcon class=\"size-4 shrink-0\" />\n </span>\n }\n @if (resolvedItemTemplate(); as tpl) {\n <span\n class=\"grow truncate select-none\"\n (click)=\"onTreeItemTextClick(node, $event)\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: aggregation()?.column,\n selected: treeItem.selected() ?? false,\n count: node.count,\n name: label,\n searchText: searchText(),\n level: node.$level ?? 0,\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n </span>\n } @else {\n <!-- ce span est essentiel pour le style -->\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'grow truncate select-none',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n label\n : label\n \"\n (click)=\"onTreeItemTextClick(node, $event)\">\n @for (\n chunk of label | 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\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n @let description = nodeDescription(node);\n @if (description) {\n <!-- `hidden`, not `sr-only`: read through aria-describedby only. A visually-hidden\n span would also be counted in the treeitem's name (computed from its content). -->\n <span hidden [id]=\"descriptionId(node.$path)\">{{ description }}</span>\n }\n </div>\n </li>\n @if (node.hasChildren) {\n <!-- No indentation here: it would shift the checkbox too. Depth is applied\n inside the row, after the checkbox, so every checkbox stays flush left. -->\n <!-- The <ul> sits INSIDE the deferred content, not around it: `ngTreeItemGroup` only\n instantiates its view when the node opens, so a <ul> declared outside stayed in the DOM,\n empty, for every collapsed node — a structural tag with nothing to structure (RGAA 8.9).\n The @if cannot move onto the <ul> either: the directive registers itself with its tree\n item on init and has to exist for as long as the item does. -->\n <ng-template\n ngTreeItemGroup\n [ownedBy]=\"treeItem\"\n #group=\"ngTreeItemGroup\">\n <ul role=\"group\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: node.items, parent: group }\" />\n </ul>\n </ng-template>\n }\n }\n</ng-template>\n",
|
|
24861
25191
|
dependencies: [
|
|
24862
25192
|
{
|
|
24863
25193
|
kind: "directive",
|
|
@@ -25031,8 +25361,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
25031
25361
|
TreeItemGroup,
|
|
25032
25362
|
AggregationPanelComponent
|
|
25033
25363
|
],
|
|
25034
|
-
host: { "[class]": "cn(\"
|
|
25035
|
-
template: "@if (!aggregation()?.isTree) {\n <div role=\"alert\" class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\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 class=\"max-h-(--scroll-height,20rem) w-full scrollbar-thin overflow-auto pb-3\">\n <ul\n ngTree\n #tree=\"ngTree\"\n [multi]=\"true\"\n [(value)]=\"selected\"\n (valueChange)=\"onSelectionChange($event)\"\n /* Translated like the flat list's own label (aggregation-list.html): this was the raw\n `display`, so the accessible name of a whole facet came out in the source language.\n The pipes apply to the whole nullish chain, `|` being the loosest operator Angular\n parses — no parentheses needed. */\n [attr.aria-label]=\"aggregation()?.display ?? name() | syslang | transloco\"\n class=\"basic-tree m-1\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: nodes(), parent: tree }\" />\n </ul>\n </div>\n</aggregation-panel>\n\n<ng-template #treeNodes let-nodes=\"nodes\" let-parent=\"parent\">\n @for (node of nodes; track node.$path) {\n @let label = node.display ?? node.value ?? \"\";\n <li\n ngTreeItem\n #treeItem=\"ngTreeItem\"\n [parent]=\"parent\"\n [value]=\"node.$path\"\n [label]=\"label\"\n [disabled]=\"node.disabled\"\n [(expanded)]=\"node.$opened\"\n (expandedChange)=\"onExpandedChange(node, $event)\"\n [attr.aria-label]=\"label\"\n [attr.aria-describedby]=\"\n nodeDescription(node) ? descriptionId(node.$path) : null\n \"\n [class]=\"cn('m-0 block w-full p-0', itemStateClass)\"\n (keydown.enter)=\"onTreeItemEnterKey(node, $event)\"\n (keydown.space)=\"onTreeItemSpaceKey(node, $event)\">\n <!-- 2. Ce div prend tout l'espace et intercepte tous les clics de la ligne -->\n <div\n class=\"flex w-full cursor-pointer items-center gap-2 py-0.5 text-sm leading-6\"\n (click)=\"onTreeItemRowClick(node, $event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\">\n @if (showCheckbox()) {\n <!-- `inert` keeps the native input out of the tab order and out of hit-testing:\n a role=\"treeitem\" admits no focusable descendant, and the click must reach\n the row handler above. Selection is announced by the <li>'s aria-selected. -->\n <!-- --spacing-xs: 0 kills the gap the checkbox keeps between its box and its\n (here empty) text block. Set as a custom property rather than a utility\n class: the CVA already sets gap-(--spacing-xs), and two same-specificity\n classes would be resolved by stylesheet order, not by us. -->\n <span\n inert\n aria-hidden=\"true\"\n class=\"inline-flex shrink-0\"\n style=\"--spacing-xs: 0\">\n <checkbox\n [checked]=\"treeItem.selected() || node.$selectedVisually || false\"\n [disabled]=\"node.disabled\"\n [class]=\"\n cn(\n 'pointer-events-none',\n (treeItem.selected() || node.$selectedVisually) &&\n 'selected-icon'\n )\n \" />\n </span>\n }\n <!-- Depth indent sits on the chevron, after the checkbox: the checkboxes of every\n level stay flush left (aligned with a flat list's), and since this adds no extra\n flex child, the step between consecutive levels is exactly one indent. -->\n @let depthIndent =\n \"calc(var(--agg-tree-indent, 0.5rem) * \" +\n (treeItem.level() - 1) +\n \")\";\n @if (node.hasChildren) {\n <!-- Expand/collapse affordance for the mouse only, hence a <span> and not a <button>:\n the keyboard already expands with ArrowRight / ArrowLeft, handled by ngTreeItem, and\n a role=\"treeitem\" admits no focusable descendant — so this was a <button> nobody\n could reach, already carrying aria-hidden and tabindex=\"-1\" to say so. Every audit\n reads it as a button with no accessible name (RGAA 7.1, 11.9). Same shape as the leaf\n branch below. -->\n <span\n aria-hidden=\"true\"\n (click)=\"toggleTreeNode(treeItem, $event)\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex cursor-pointer items-center justify-center\">\n <ChevronRightIcon\n [class]=\"\n cn('expand-icon shrink-0', node.$opened && 'rotate-90')\n \" />\n <FolderIcon class=\"shrink-0\" />\n </span>\n } @else {\n <span\n aria-hidden=\"true\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex items-center justify-center\">\n <!-- Reserves the chevron's own width (`.expand-icon` is a styling hook with\n no rule of its own), so a leaf lines up with its parent nodes. -->\n <span class=\"expand-icon w-4 shrink-0\"></span>\n <FileIcon class=\"size-4 shrink-0\" />\n </span>\n }\n @if (resolvedItemTemplate(); as tpl) {\n <span\n class=\"grow truncate select-none\"\n (click)=\"onTreeItemTextClick(node, $event)\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: aggregation()?.column,\n selected: treeItem.selected() ?? false,\n count: node.count,\n name: label,\n searchText: searchText(),\n level: node.$level ?? 0,\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n </span>\n } @else {\n <!-- ce span est essentiel pour le style -->\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'grow truncate select-none',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n label\n : label\n \"\n (click)=\"onTreeItemTextClick(node, $event)\">\n @for (\n chunk of label | 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\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n @let description = nodeDescription(node);\n @if (description) {\n <!-- `hidden`, not `sr-only`: read through aria-describedby only. A visually-hidden\n span would also be counted in the treeitem's name (computed from its content). -->\n <span hidden [id]=\"descriptionId(node.$path)\">{{ description }}</span>\n }\n </div>\n </li>\n @if (node.hasChildren) {\n <!-- No indentation here: it would shift the checkbox too. Depth is applied\n inside the row, after the checkbox, so every checkbox stays flush left. -->\n <!-- The <ul> sits INSIDE the deferred content, not around it: `ngTreeItemGroup` only\n instantiates its view when the node opens, so a <ul> declared outside stayed in the DOM,\n empty, for every collapsed node — a structural tag with nothing to structure (RGAA 8.9).\n The @if cannot move onto the <ul> either: the directive registers itself with its tree\n item on init and has to exist for as long as the item does. -->\n <ng-template\n ngTreeItemGroup\n [ownedBy]=\"treeItem\"\n #group=\"ngTreeItemGroup\">\n <ul role=\"group\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: node.items, parent: group }\" />\n </ul>\n </ng-template>\n }\n }\n</ng-template>\n"
|
|
25364
|
+
host: { "[class]": "cn(\"flex h-[inherit] max-h-[inherit] flex-col\", class(), (isMissing() || (hideWhenEmpty() && isHidden())) && \"hidden\")" },
|
|
25365
|
+
template: "@if (!aggregation()?.isTree) {\n <div role=\"alert\" class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\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 class=\"min-h-0 w-full flex-1 scrollbar-thin overflow-auto pb-3\">\n <ul\n ngTree\n #tree=\"ngTree\"\n [multi]=\"true\"\n [(value)]=\"selected\"\n (valueChange)=\"onSelectionChange($event)\"\n /* Translated like the flat list's own label (aggregation-list.html): this was the raw\n `display`, so the accessible name of a whole facet came out in the source language.\n The pipes apply to the whole nullish chain, `|` being the loosest operator Angular\n parses — no parentheses needed. */\n [attr.aria-label]=\"aggregation()?.display ?? name() | syslang | transloco\"\n class=\"basic-tree m-1\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: nodes(), parent: tree }\" />\n </ul>\n </div>\n</aggregation-panel>\n\n<ng-template #treeNodes let-nodes=\"nodes\" let-parent=\"parent\">\n @for (node of nodes; track node.$path) {\n @let label = node.display ?? node.value ?? \"\";\n <li\n ngTreeItem\n #treeItem=\"ngTreeItem\"\n [parent]=\"parent\"\n [value]=\"node.$path\"\n [label]=\"label\"\n [disabled]=\"node.disabled\"\n [(expanded)]=\"node.$opened\"\n (expandedChange)=\"onExpandedChange(node, $event)\"\n [attr.aria-label]=\"label\"\n [attr.aria-describedby]=\"\n nodeDescription(node) ? descriptionId(node.$path) : null\n \"\n [class]=\"cn('m-0 block w-full p-0', itemStateClass)\"\n (keydown.enter)=\"onTreeItemEnterKey(node, $event)\"\n (keydown.space)=\"onTreeItemSpaceKey(node, $event)\">\n <!-- 2. Ce div prend tout l'espace et intercepte tous les clics de la ligne -->\n <div\n class=\"flex w-full cursor-pointer items-center gap-2 py-0.5 text-sm leading-6\"\n (click)=\"onTreeItemRowClick(node, $event)\"\n (mousedown)=\"$event.stopPropagation()\"\n (pointerdown)=\"$event.stopPropagation()\">\n @if (showCheckbox()) {\n <!-- `inert` keeps the native input out of the tab order and out of hit-testing:\n a role=\"treeitem\" admits no focusable descendant, and the click must reach\n the row handler above. Selection is announced by the <li>'s aria-selected. -->\n <!-- --spacing-xs: 0 kills the gap the checkbox keeps between its box and its\n (here empty) text block. Set as a custom property rather than a utility\n class: the CVA already sets gap-(--spacing-xs), and two same-specificity\n classes would be resolved by stylesheet order, not by us. -->\n <span\n inert\n aria-hidden=\"true\"\n class=\"inline-flex shrink-0\"\n style=\"--spacing-xs: 0\">\n <checkbox\n [checked]=\"treeItem.selected() || node.$selectedVisually || false\"\n [disabled]=\"node.disabled\"\n [class]=\"\n cn(\n 'pointer-events-none',\n (treeItem.selected() || node.$selectedVisually) &&\n 'selected-icon'\n )\n \" />\n </span>\n }\n <!-- Depth indent sits on the chevron, after the checkbox: the checkboxes of every\n level stay flush left (aligned with a flat list's), and since this adds no extra\n flex child, the step between consecutive levels is exactly one indent. -->\n @let depthIndent =\n \"calc(var(--agg-tree-indent, 0.5rem) * \" +\n (treeItem.level() - 1) +\n \")\";\n @if (node.hasChildren) {\n <!-- Expand/collapse affordance for the mouse only, hence a <span> and not a <button>:\n the keyboard already expands with ArrowRight / ArrowLeft, handled by ngTreeItem, and\n a role=\"treeitem\" admits no focusable descendant — so this was a <button> nobody\n could reach, already carrying aria-hidden and tabindex=\"-1\" to say so. Every audit\n reads it as a button with no accessible name (RGAA 7.1, 11.9). Same shape as the leaf\n branch below. -->\n <span\n aria-hidden=\"true\"\n (click)=\"toggleTreeNode(treeItem, $event)\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex cursor-pointer items-center justify-center\">\n <ChevronRightIcon\n [class]=\"\n cn('expand-icon shrink-0', node.$opened && 'rotate-90')\n \" />\n <FolderIcon class=\"shrink-0\" />\n </span>\n } @else {\n <span\n aria-hidden=\"true\"\n [style.marginInlineStart]=\"depthIndent\"\n class=\"inline-flex items-center justify-center\">\n <!-- Reserves the chevron's own width (`.expand-icon` is a styling hook with\n no rule of its own), so a leaf lines up with its parent nodes. -->\n <span class=\"expand-icon w-4 shrink-0\"></span>\n <FileIcon class=\"size-4 shrink-0\" />\n </span>\n }\n @if (resolvedItemTemplate(); as tpl) {\n <span\n class=\"grow truncate select-none\"\n (click)=\"onTreeItemTextClick(node, $event)\">\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: node,\n field: aggregation()?.column,\n selected: treeItem.selected() ?? false,\n count: node.count,\n name: label,\n searchText: searchText(),\n level: node.$level ?? 0,\n expanded: node.$opened ?? false,\n hasChildren: node.hasChildren ?? false\n }\" />\n </span>\n } @else {\n <!-- ce span est essentiel pour le style -->\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'grow truncate select-none',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isTreeItemFiltered(node)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n label\n : label\n \"\n (click)=\"onTreeItemTextClick(node, $event)\">\n @for (\n chunk of label | 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\" aria-hidden=\"true\">{{\n node.count\n }}</span>\n }\n }\n @let description = nodeDescription(node);\n @if (description) {\n <!-- `hidden`, not `sr-only`: read through aria-describedby only. A visually-hidden\n span would also be counted in the treeitem's name (computed from its content). -->\n <span hidden [id]=\"descriptionId(node.$path)\">{{ description }}</span>\n }\n </div>\n </li>\n @if (node.hasChildren) {\n <!-- No indentation here: it would shift the checkbox too. Depth is applied\n inside the row, after the checkbox, so every checkbox stays flush left. -->\n <!-- The <ul> sits INSIDE the deferred content, not around it: `ngTreeItemGroup` only\n instantiates its view when the node opens, so a <ul> declared outside stayed in the DOM,\n empty, for every collapsed node — a structural tag with nothing to structure (RGAA 8.9).\n The @if cannot move onto the <ul> either: the directive registers itself with its tree\n item on init and has to exist for as long as the item does. -->\n <ng-template\n ngTreeItemGroup\n [ownedBy]=\"treeItem\"\n #group=\"ngTreeItemGroup\">\n <ul role=\"group\">\n <ng-template\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ nodes: node.items, parent: group }\" />\n </ul>\n </ng-template>\n }\n }\n</ng-template>\n"
|
|
25036
25366
|
}]
|
|
25037
25367
|
}],
|
|
25038
25368
|
ctorParameters: () => [],
|
|
@@ -25689,7 +26019,7 @@ var AggregationListComponent = class AggregationListComponent {
|
|
|
25689
26019
|
},
|
|
25690
26020
|
host: {
|
|
25691
26021
|
listeners: { "keydown.enter": "onHostEnterKey($event)" },
|
|
25692
|
-
properties: { "class": "cn(\"
|
|
26022
|
+
properties: { "class": "cn(\"flex h-[inherit] max-h-[inherit] flex-col\", class(), (isMissing() || (hideWhenEmpty() && isEmpty())) && \"hidden\")" }
|
|
25693
26023
|
},
|
|
25694
26024
|
queries: [{
|
|
25695
26025
|
propertyName: "itemDirective",
|
|
@@ -25721,7 +26051,7 @@ var AggregationListComponent = class AggregationListComponent {
|
|
|
25721
26051
|
}
|
|
25722
26052
|
],
|
|
25723
26053
|
ngImport: i0,
|
|
25724
|
-
template: "@if (aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\n The aggregation component no longer supports tree aggregations. Please use\n the <AggregationTree /> 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=\"
|
|
26054
|
+
template: "@if (aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\n The aggregation component no longer supports tree aggregations. Please use\n the <AggregationTree /> 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=\"min-h-0 w-full flex-1 scrollbar-thin overflow-auto px-1 pt-1 pb-3\">\n <div\n ngListbox\n multi\n selectionMode=\"explicit\"\n [value]=\"selectedValues()\"\n (valueChange)=\"syncListboxValue($event)\"\n [wrap]=\"false\"\n [softDisabled]=\"false\"\n class=\"relative w-full\"\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\n @let item = items()[vItem.index];\n @let description = rowDescription(item);\n <div\n #row\n ngOption\n [attr.aria-describedby]=\"\n description ? descriptionId(vItem.index) : null\n \"\n [attr.data-index]=\"vItem.index\"\n [value]=\"item.value\"\n [disabled]=\"item.count === 0\"\n [class]=\"cn('absolute w-full', menuItemBaseClass)\"\n (keydown.enter)=\"onOptionEnterKey(item, $event)\"\n (keydown.space)=\"\n onListItemRowClick(item, $event); $event.preventDefault()\n \"\n [style.transform]=\"'translateY(' + vItem.start + 'px)'\"\n role=\"option\">\n <ng-container\n [ngTemplateOutlet]=\"listItemTpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n field: aggregation()?.column\n }\">\n </ng-container>\n @if (description) {\n <!-- `hidden`, not `sr-only`: read through aria-describedby only. A visually-hidden\n span would also be counted in the option's name (computed from its content). -->\n <span hidden [id]=\"descriptionId(vItem.index)\">{{\n description\n }}</span>\n }\n </div>\n }\n </div>\n </div>\n</aggregation-panel>\n\n<ng-template #listItemTpl let-item let-field=\"field\">\n <a\n [attr.aria-label]=\"listItemName(item) | syslang\"\n [class]=\"\n cn(\n '-m-1.5 flex min-w-0 grow items-center gap-2 leading-6',\n item.count === 0 && 'pointer-events-none text-(--font-neutral-muted)'\n )\n \"\n (click)=\"onListItemRowClick(item, $event)\">\n @if (showCheckbox()) {\n <!-- `inert` keeps the native input out of the tab order and out of hit-testing:\n keyboard navigation belongs to ngListbox/ngOption (roving tabindex), the\n selection is already exposed by role=\"option\" + aria-selected, and the click\n must reach the <a> above. Same treatment as the tree.\n --spacing-xs: 0 kills the gap the checkbox keeps between its box and its\n (here empty) text block. -->\n <span\n inert\n aria-hidden=\"true\"\n class=\"inline-flex shrink-0\"\n style=\"--spacing-xs: 0\">\n <checkbox\n [checked]=\"item.$selected ?? false\"\n [disabled]=\"item.count === 0\"\n [class]=\"'pointer-events-none'\" />\n </span>\n }\n @if (resolvedItemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n field: field,\n selected: item.$selected ?? false,\n count: item.count,\n name: (listItemName(item) | syslang) ?? '',\n searchText: searchText()\n }\" />\n } @else {\n @let icon = $any(item).icon;\n @if (icon) {\n <FaIcon\n [faClass]=\"icon\"\n class=\"shrink-0 self-center justify-self-center\" />\n }\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'line-clamp-1 cursor-pointer break-all text-ellipsis select-none',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isListItemFiltered(item, field)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n (listItemName(item) | syslang)\n : (listItemName(item) | syslang)\n \"\n (click)=\"onListItemTextClick(item, $event)\">\n @for (\n chunk of (listItemName(item) | 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() && item.count > 0) {\n <span class=\"ml-auto px-1 text-xs empty:hidden\" aria-hidden=\"true\">{{\n item.count\n }}</span>\n }\n }\n </a>\n</ng-template>\n",
|
|
25725
26055
|
dependencies: [
|
|
25726
26056
|
{
|
|
25727
26057
|
kind: "directive",
|
|
@@ -25862,10 +26192,10 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
25862
26192
|
CheckboxComponent
|
|
25863
26193
|
],
|
|
25864
26194
|
host: {
|
|
25865
|
-
"[class]": "cn(\"
|
|
26195
|
+
"[class]": "cn(\"flex h-[inherit] max-h-[inherit] flex-col\", class(), (isMissing() || (hideWhenEmpty() && isEmpty())) && \"hidden\")",
|
|
25866
26196
|
"(keydown.enter)": "onHostEnterKey($event)"
|
|
25867
26197
|
},
|
|
25868
|
-
template: "@if (aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\n The aggregation component no longer supports tree aggregations. Please use\n the <AggregationTree /> 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=\"
|
|
26198
|
+
template: "@if (aggregation()?.isTree) {\n <div class=\"p-2 text-sm text-red-500\">\n <triangle-alert-icon class=\"mr-1 shrink-0\" />\n The aggregation component no longer supports tree aggregations. Please use\n the <AggregationTree /> 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=\"min-h-0 w-full flex-1 scrollbar-thin overflow-auto px-1 pt-1 pb-3\">\n <div\n ngListbox\n multi\n selectionMode=\"explicit\"\n [value]=\"selectedValues()\"\n (valueChange)=\"syncListboxValue($event)\"\n [wrap]=\"false\"\n [softDisabled]=\"false\"\n class=\"relative w-full\"\n [style.height]=\"virtualizer.getTotalSize() + 'px'\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-label]=\"aggregation()?.display | syslang | transloco\">\n @for (vItem of virtualizer.getVirtualItems(); track vItem.index) {\n @let item = items()[vItem.index];\n @let description = rowDescription(item);\n <div\n #row\n ngOption\n [attr.aria-describedby]=\"\n description ? descriptionId(vItem.index) : null\n \"\n [attr.data-index]=\"vItem.index\"\n [value]=\"item.value\"\n [disabled]=\"item.count === 0\"\n [class]=\"cn('absolute w-full', menuItemBaseClass)\"\n (keydown.enter)=\"onOptionEnterKey(item, $event)\"\n (keydown.space)=\"\n onListItemRowClick(item, $event); $event.preventDefault()\n \"\n [style.transform]=\"'translateY(' + vItem.start + 'px)'\"\n role=\"option\">\n <ng-container\n [ngTemplateOutlet]=\"listItemTpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n field: aggregation()?.column\n }\">\n </ng-container>\n @if (description) {\n <!-- `hidden`, not `sr-only`: read through aria-describedby only. A visually-hidden\n span would also be counted in the option's name (computed from its content). -->\n <span hidden [id]=\"descriptionId(vItem.index)\">{{\n description\n }}</span>\n }\n </div>\n }\n </div>\n </div>\n</aggregation-panel>\n\n<ng-template #listItemTpl let-item let-field=\"field\">\n <a\n [attr.aria-label]=\"listItemName(item) | syslang\"\n [class]=\"\n cn(\n '-m-1.5 flex min-w-0 grow items-center gap-2 leading-6',\n item.count === 0 && 'pointer-events-none text-(--font-neutral-muted)'\n )\n \"\n (click)=\"onListItemRowClick(item, $event)\">\n @if (showCheckbox()) {\n <!-- `inert` keeps the native input out of the tab order and out of hit-testing:\n keyboard navigation belongs to ngListbox/ngOption (roving tabindex), the\n selection is already exposed by role=\"option\" + aria-selected, and the click\n must reach the <a> above. Same treatment as the tree.\n --spacing-xs: 0 kills the gap the checkbox keeps between its box and its\n (here empty) text block. -->\n <span\n inert\n aria-hidden=\"true\"\n class=\"inline-flex shrink-0\"\n style=\"--spacing-xs: 0\">\n <checkbox\n [checked]=\"item.$selected ?? false\"\n [disabled]=\"item.count === 0\"\n [class]=\"'pointer-events-none'\" />\n </span>\n }\n @if (resolvedItemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n field: field,\n selected: item.$selected ?? false,\n count: item.count,\n name: (listItemName(item) | syslang) ?? '',\n searchText: searchText()\n }\" />\n } @else {\n @let icon = $any(item).icon;\n @if (icon) {\n <FaIcon\n [faClass]=\"icon\"\n class=\"shrink-0 self-center justify-self-center\" />\n }\n @let appliesOnLabelClick = quickFilter() || applyOnSelect();\n <span\n [class]=\"\n cn(\n 'line-clamp-1 cursor-pointer break-all text-ellipsis select-none',\n appliesOnLabelClick && 'hover:underline'\n )\n \"\n [title]=\"\n appliesOnLabelClick\n ? ((isListItemFiltered(item, field)\n ? 'filters.removeFilter'\n : 'filters.addFilter'\n ) | transloco) +\n ': ' +\n (listItemName(item) | syslang)\n : (listItemName(item) | syslang)\n \"\n (click)=\"onListItemTextClick(item, $event)\">\n @for (\n chunk of (listItemName(item) | 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() && item.count > 0) {\n <span class=\"ml-auto px-1 text-xs empty:hidden\" aria-hidden=\"true\">{{\n item.count\n }}</span>\n }\n }\n </a>\n</ng-template>\n"
|
|
25869
26199
|
}]
|
|
25870
26200
|
}],
|
|
25871
26201
|
ctorParameters: () => [],
|
|
@@ -26312,7 +26642,7 @@ var AggregationComponent = class AggregationComponent {
|
|
|
26312
26642
|
selectionChange: "selectionChange",
|
|
26313
26643
|
filtersChange: "filtersChange"
|
|
26314
26644
|
},
|
|
26315
|
-
host: { properties: { "class": "cn(\"
|
|
26645
|
+
host: { properties: { "class": "cn(\"flex h-[inherit] max-h-[inherit] flex-col\",class(), (isMissing() || (hideWhenEmpty() && isEmpty())) && \"hidden\")" } },
|
|
26316
26646
|
queries: [{
|
|
26317
26647
|
propertyName: "itemDirective",
|
|
26318
26648
|
first: true,
|
|
@@ -26348,6 +26678,7 @@ var AggregationComponent = class AggregationComponent {
|
|
|
26348
26678
|
@switch (resolvedType()) {
|
|
26349
26679
|
@case ("date") {
|
|
26350
26680
|
<AggregationDate
|
|
26681
|
+
class="min-h-0 flex-1"
|
|
26351
26682
|
[id]="id()"
|
|
26352
26683
|
[name]="name()"
|
|
26353
26684
|
[column]="column()"
|
|
@@ -26369,6 +26700,7 @@ var AggregationComponent = class AggregationComponent {
|
|
|
26369
26700
|
}
|
|
26370
26701
|
@case ("tree") {
|
|
26371
26702
|
<AggregationTree
|
|
26703
|
+
class="min-h-0 w-auto flex-1"
|
|
26372
26704
|
[id]="id()"
|
|
26373
26705
|
[name]="name()"
|
|
26374
26706
|
[column]="column()"
|
|
@@ -26395,6 +26727,7 @@ var AggregationComponent = class AggregationComponent {
|
|
|
26395
26727
|
}
|
|
26396
26728
|
@default {
|
|
26397
26729
|
<AggregationList
|
|
26730
|
+
class="min-h-0 flex-1"
|
|
26398
26731
|
[id]="id()"
|
|
26399
26732
|
[name]="name()"
|
|
26400
26733
|
[column]="column()"
|
|
@@ -26494,6 +26827,7 @@ var AggregationComponent = class AggregationComponent {
|
|
|
26494
26827
|
type: AggregationDateComponent,
|
|
26495
26828
|
selector: "aggregation-date, AggregationDate, aggregationdate",
|
|
26496
26829
|
inputs: [
|
|
26830
|
+
"class",
|
|
26497
26831
|
"name",
|
|
26498
26832
|
"column",
|
|
26499
26833
|
"id",
|
|
@@ -26541,6 +26875,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
26541
26875
|
@switch (resolvedType()) {
|
|
26542
26876
|
@case ("date") {
|
|
26543
26877
|
<AggregationDate
|
|
26878
|
+
class="min-h-0 flex-1"
|
|
26544
26879
|
[id]="id()"
|
|
26545
26880
|
[name]="name()"
|
|
26546
26881
|
[column]="column()"
|
|
@@ -26562,6 +26897,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
26562
26897
|
}
|
|
26563
26898
|
@case ("tree") {
|
|
26564
26899
|
<AggregationTree
|
|
26900
|
+
class="min-h-0 w-auto flex-1"
|
|
26565
26901
|
[id]="id()"
|
|
26566
26902
|
[name]="name()"
|
|
26567
26903
|
[column]="column()"
|
|
@@ -26588,6 +26924,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
26588
26924
|
}
|
|
26589
26925
|
@default {
|
|
26590
26926
|
<AggregationList
|
|
26927
|
+
class="min-h-0 flex-1"
|
|
26591
26928
|
[id]="id()"
|
|
26592
26929
|
[name]="name()"
|
|
26593
26930
|
[column]="column()"
|
|
@@ -26613,7 +26950,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
26613
26950
|
}
|
|
26614
26951
|
}
|
|
26615
26952
|
`,
|
|
26616
|
-
host: { "[class]": "cn(\"
|
|
26953
|
+
host: { "[class]": "cn(\"flex h-[inherit] max-h-[inherit] flex-col\",class(), (isMissing() || (hideWhenEmpty() && isEmpty())) && \"hidden\")" }
|
|
26617
26954
|
}]
|
|
26618
26955
|
}],
|
|
26619
26956
|
propDecorators: {
|
|
@@ -27473,6 +27810,10 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27473
27810
|
...ngDevMode ? { debugName: "expandedLevel" } : /* istanbul ignore next */ {},
|
|
27474
27811
|
transform: numberAttribute
|
|
27475
27812
|
});
|
|
27813
|
+
overflowed = input(false, {
|
|
27814
|
+
...ngDevMode ? { debugName: "overflowed" } : /* istanbul ignore next */ {},
|
|
27815
|
+
transform: booleanAttribute
|
|
27816
|
+
});
|
|
27476
27817
|
variant = signal("tertiary", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
|
|
27477
27818
|
filter = signal({
|
|
27478
27819
|
name: "",
|
|
@@ -27487,6 +27828,7 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27487
27828
|
popoverId = `filter-popover-${popoverUid++}`;
|
|
27488
27829
|
popoverRef = viewChild(PopoverDirective, ...ngDevMode ? [{ debugName: "popoverRef" }] : /* istanbul ignore next */ []);
|
|
27489
27830
|
isOpen = computed(() => this.popoverRef()?.state() === "open", ...ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []);
|
|
27831
|
+
toolbar = inject(Toolbar, { optional: true });
|
|
27490
27832
|
nativeElement = inject(ElementRef).nativeElement;
|
|
27491
27833
|
aggregationsStore = inject(AggregationsStore);
|
|
27492
27834
|
queryParamsStore = inject(QueryParamsStore);
|
|
@@ -27599,6 +27941,13 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27599
27941
|
isSignal: true,
|
|
27600
27942
|
isRequired: false,
|
|
27601
27943
|
transformFunction: null
|
|
27944
|
+
},
|
|
27945
|
+
overflowed: {
|
|
27946
|
+
classPropertyName: "overflowed",
|
|
27947
|
+
publicName: "overflowed",
|
|
27948
|
+
isSignal: true,
|
|
27949
|
+
isRequired: false,
|
|
27950
|
+
transformFunction: null
|
|
27602
27951
|
}
|
|
27603
27952
|
},
|
|
27604
27953
|
host: {
|
|
@@ -27620,13 +27969,7 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27620
27969
|
}],
|
|
27621
27970
|
ngImport: i0,
|
|
27622
27971
|
template: `
|
|
27623
|
-
<
|
|
27624
|
-
[variant]="variant()"
|
|
27625
|
-
[attr.popovertarget]="popoverId"
|
|
27626
|
-
[class]="isOpen() ? 'border border-(--stroke-neutral-dark)/50' : ''"
|
|
27627
|
-
[attr.data-disabled]="filter().disabled"
|
|
27628
|
-
[disabled]="filter().disabled || null"
|
|
27629
|
-
>
|
|
27972
|
+
<ng-template #label>
|
|
27630
27973
|
<!-- display the filter icon if set -->
|
|
27631
27974
|
@let icon = filter().icon;
|
|
27632
27975
|
@if (icon) {
|
|
@@ -27646,7 +27989,35 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27646
27989
|
@if (filter().count > 1) {
|
|
27647
27990
|
<Badge variant="number" fill="secondary" scheme="sage" size="xs">+{{ filter().count - 1 }}</Badge>
|
|
27648
27991
|
}
|
|
27649
|
-
</
|
|
27992
|
+
</ng-template>
|
|
27993
|
+
|
|
27994
|
+
@if (toolbar) {
|
|
27995
|
+
<!-- Inside a toolbar the BUTTON is the roving widget, not the host: the host is an element with
|
|
27996
|
+
no role of its own, so making it the widget gave two tab stops — an inert host that the
|
|
27997
|
+
roving focused, then this button with its own stop. A native disabled attribute would also make a
|
|
27998
|
+
widget unfocusable, so the toolbar's own disabled input (soft: still focusable, aria-disabled)
|
|
27999
|
+
takes over and the popover trigger is simply not wired. The same disabled state removes a filter
|
|
28000
|
+
hidden by the overflow manager (display: none) from the roving: arrow keys must not spend
|
|
28001
|
+
presses on filters nobody can see. -->
|
|
28002
|
+
<button
|
|
28003
|
+
ngToolbarWidget
|
|
28004
|
+
[variant]="variant()"
|
|
28005
|
+
[attr.popovertarget]="filter().disabled ? null : popoverId"
|
|
28006
|
+
[class]="isOpen() ? 'border border-(--stroke-neutral-dark)/50' : ''"
|
|
28007
|
+
[attr.data-disabled]="filter().disabled"
|
|
28008
|
+
[disabled]="filter().disabled || overflowed()">
|
|
28009
|
+
<ng-container *ngTemplateOutlet="label" />
|
|
28010
|
+
</button>
|
|
28011
|
+
} @else {
|
|
28012
|
+
<button
|
|
28013
|
+
[variant]="variant()"
|
|
28014
|
+
[attr.popovertarget]="popoverId"
|
|
28015
|
+
[class]="isOpen() ? 'border border-(--stroke-neutral-dark)/50' : ''"
|
|
28016
|
+
[attr.data-disabled]="filter().disabled"
|
|
28017
|
+
[disabled]="filter().disabled || null">
|
|
28018
|
+
<ng-container *ngTemplateOutlet="label" />
|
|
28019
|
+
</button>
|
|
28020
|
+
}
|
|
27650
28021
|
|
|
27651
28022
|
<!-- Native HTML Popover (top-layer). The popover content stays a DOM
|
|
27652
28023
|
descendant of the surrounding @angular/aria toolbar, so pointer/click
|
|
@@ -27660,8 +28031,10 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27660
28031
|
trigger-width matching so the panel sizes to its content. overflow-hidden
|
|
27661
28032
|
resets the browser's default overflow:auto on [popover] elements, which
|
|
27662
28033
|
would otherwise scroll on its own in addition to Aggregation's own
|
|
27663
|
-
|
|
27664
|
-
|
|
28034
|
+
facet list (a double scrollbar) once its fit-content height would
|
|
28035
|
+
otherwise exceed the viewport. The facet list is the only thing that
|
|
28036
|
+
scrolls: the facet itself is capped by the room the popover has (see
|
|
28037
|
+
below). -->
|
|
27665
28038
|
<div
|
|
27666
28039
|
popover
|
|
27667
28040
|
[id]="popoverId"
|
|
@@ -27679,21 +28052,23 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27679
28052
|
rings (2px outlines) of the facet header and its buttons sit flush against the wrapper's edges —
|
|
27680
28053
|
they were cut off on three sides. The 4px of padding gives them room, the matching negative
|
|
27681
28054
|
margin leaves the layout unchanged. Width and max-height grow by the 0.5rem of padding
|
|
27682
|
-
(15.5rem = the former w-60 + 0.5rem
|
|
27683
|
-
|
|
27684
|
-
|
|
27685
|
-
|
|
27686
|
-
|
|
27687
|
-
|
|
27688
|
-
|
|
27689
|
-
1.5rem subtracted is this popover's own vertical padding (p-3), which
|
|
27690
|
-
same available space
|
|
27691
|
-
|
|
28055
|
+
(15.5rem = the former w-60 + 0.5rem) because box-sizing is border-box here: the facet keeps
|
|
28056
|
+
its 15rem and the popover its size. The wrapper no longer scrolls (and no longer clips the
|
|
28057
|
+
rings): the facet's own list is the one scrollbar. -->
|
|
28058
|
+
<!-- The facet is capped by the smaller of two heights: its comfortable size (19 lines of list +
|
|
28059
|
+
7rem of header, search box and paddings), and the room the popover really has.
|
|
28060
|
+
size() (added to injectPopover) exposes that room, in the chosen direction, as the
|
|
28061
|
+
--popover-available-height CSS var — flip()/shift() alone only reposition the popover, they
|
|
28062
|
+
never shrink it. The 1.5rem subtracted is this popover's own vertical padding (p-3), which
|
|
28063
|
+
eats into that same available space (this wrapper's p-1 / -m-1 cancel out). The facet is a
|
|
28064
|
+
flex column whose list is min-h-0 flex-1, so it is the list that shrinks and scrolls — a
|
|
28065
|
+
capped wrapper with overflow-y-auto around it would add a second, outer scrollbar. -->
|
|
28066
|
+
<div class="-m-1 w-[15.5rem] p-1">
|
|
27692
28067
|
@let name = filter().name;
|
|
27693
28068
|
@let column = filter().column;
|
|
27694
28069
|
@if (name) {
|
|
27695
28070
|
<Aggregation
|
|
27696
|
-
class="
|
|
28071
|
+
class="w-full max-h-[min(calc(19lh+7rem),calc(var(--popover-available-height,55vh)_-_1.5rem))]"
|
|
27697
28072
|
id="filter-{{ filter().column }}"
|
|
27698
28073
|
[name]="name"
|
|
27699
28074
|
[column]="column"
|
|
@@ -27712,6 +28087,23 @@ var FilterButtonComponent = class FilterButtonComponent {
|
|
|
27712
28087
|
`,
|
|
27713
28088
|
isInline: true,
|
|
27714
28089
|
dependencies: [
|
|
28090
|
+
{
|
|
28091
|
+
kind: "directive",
|
|
28092
|
+
type: NgTemplateOutlet,
|
|
28093
|
+
selector: "[ngTemplateOutlet]",
|
|
28094
|
+
inputs: [
|
|
28095
|
+
"ngTemplateOutletContext",
|
|
28096
|
+
"ngTemplateOutlet",
|
|
28097
|
+
"ngTemplateOutletInjector"
|
|
28098
|
+
]
|
|
28099
|
+
},
|
|
28100
|
+
{
|
|
28101
|
+
kind: "directive",
|
|
28102
|
+
type: ToolbarWidget,
|
|
28103
|
+
selector: "[ngToolbarWidget]",
|
|
28104
|
+
inputs: ["id", "disabled"],
|
|
28105
|
+
exportAs: ["ngToolbarWidget"]
|
|
28106
|
+
},
|
|
27715
28107
|
{
|
|
27716
28108
|
kind: "directive",
|
|
27717
28109
|
type: ButtonComponent,
|
|
@@ -27819,6 +28211,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
27819
28211
|
args: [{
|
|
27820
28212
|
selector: "filter-button, FilterButton",
|
|
27821
28213
|
imports: [
|
|
28214
|
+
NgTemplateOutlet,
|
|
28215
|
+
ToolbarWidget,
|
|
27822
28216
|
ButtonComponent,
|
|
27823
28217
|
PopoverDirective,
|
|
27824
28218
|
OperatorPipe,
|
|
@@ -27829,13 +28223,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
27829
28223
|
FaIconComponent
|
|
27830
28224
|
],
|
|
27831
28225
|
template: `
|
|
27832
|
-
<
|
|
27833
|
-
[variant]="variant()"
|
|
27834
|
-
[attr.popovertarget]="popoverId"
|
|
27835
|
-
[class]="isOpen() ? 'border border-(--stroke-neutral-dark)/50' : ''"
|
|
27836
|
-
[attr.data-disabled]="filter().disabled"
|
|
27837
|
-
[disabled]="filter().disabled || null"
|
|
27838
|
-
>
|
|
28226
|
+
<ng-template #label>
|
|
27839
28227
|
<!-- display the filter icon if set -->
|
|
27840
28228
|
@let icon = filter().icon;
|
|
27841
28229
|
@if (icon) {
|
|
@@ -27855,7 +28243,35 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
27855
28243
|
@if (filter().count > 1) {
|
|
27856
28244
|
<Badge variant="number" fill="secondary" scheme="sage" size="xs">+{{ filter().count - 1 }}</Badge>
|
|
27857
28245
|
}
|
|
27858
|
-
</
|
|
28246
|
+
</ng-template>
|
|
28247
|
+
|
|
28248
|
+
@if (toolbar) {
|
|
28249
|
+
<!-- Inside a toolbar the BUTTON is the roving widget, not the host: the host is an element with
|
|
28250
|
+
no role of its own, so making it the widget gave two tab stops — an inert host that the
|
|
28251
|
+
roving focused, then this button with its own stop. A native disabled attribute would also make a
|
|
28252
|
+
widget unfocusable, so the toolbar's own disabled input (soft: still focusable, aria-disabled)
|
|
28253
|
+
takes over and the popover trigger is simply not wired. The same disabled state removes a filter
|
|
28254
|
+
hidden by the overflow manager (display: none) from the roving: arrow keys must not spend
|
|
28255
|
+
presses on filters nobody can see. -->
|
|
28256
|
+
<button
|
|
28257
|
+
ngToolbarWidget
|
|
28258
|
+
[variant]="variant()"
|
|
28259
|
+
[attr.popovertarget]="filter().disabled ? null : popoverId"
|
|
28260
|
+
[class]="isOpen() ? 'border border-(--stroke-neutral-dark)/50' : ''"
|
|
28261
|
+
[attr.data-disabled]="filter().disabled"
|
|
28262
|
+
[disabled]="filter().disabled || overflowed()">
|
|
28263
|
+
<ng-container *ngTemplateOutlet="label" />
|
|
28264
|
+
</button>
|
|
28265
|
+
} @else {
|
|
28266
|
+
<button
|
|
28267
|
+
[variant]="variant()"
|
|
28268
|
+
[attr.popovertarget]="popoverId"
|
|
28269
|
+
[class]="isOpen() ? 'border border-(--stroke-neutral-dark)/50' : ''"
|
|
28270
|
+
[attr.data-disabled]="filter().disabled"
|
|
28271
|
+
[disabled]="filter().disabled || null">
|
|
28272
|
+
<ng-container *ngTemplateOutlet="label" />
|
|
28273
|
+
</button>
|
|
28274
|
+
}
|
|
27859
28275
|
|
|
27860
28276
|
<!-- Native HTML Popover (top-layer). The popover content stays a DOM
|
|
27861
28277
|
descendant of the surrounding @angular/aria toolbar, so pointer/click
|
|
@@ -27869,8 +28285,10 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
27869
28285
|
trigger-width matching so the panel sizes to its content. overflow-hidden
|
|
27870
28286
|
resets the browser's default overflow:auto on [popover] elements, which
|
|
27871
28287
|
would otherwise scroll on its own in addition to Aggregation's own
|
|
27872
|
-
|
|
27873
|
-
|
|
28288
|
+
facet list (a double scrollbar) once its fit-content height would
|
|
28289
|
+
otherwise exceed the viewport. The facet list is the only thing that
|
|
28290
|
+
scrolls: the facet itself is capped by the room the popover has (see
|
|
28291
|
+
below). -->
|
|
27874
28292
|
<div
|
|
27875
28293
|
popover
|
|
27876
28294
|
[id]="popoverId"
|
|
@@ -27888,21 +28306,23 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
27888
28306
|
rings (2px outlines) of the facet header and its buttons sit flush against the wrapper's edges —
|
|
27889
28307
|
they were cut off on three sides. The 4px of padding gives them room, the matching negative
|
|
27890
28308
|
margin leaves the layout unchanged. Width and max-height grow by the 0.5rem of padding
|
|
27891
|
-
(15.5rem = the former w-60 + 0.5rem
|
|
27892
|
-
|
|
27893
|
-
|
|
27894
|
-
|
|
27895
|
-
|
|
27896
|
-
|
|
27897
|
-
|
|
27898
|
-
1.5rem subtracted is this popover's own vertical padding (p-3), which
|
|
27899
|
-
same available space
|
|
27900
|
-
|
|
28309
|
+
(15.5rem = the former w-60 + 0.5rem) because box-sizing is border-box here: the facet keeps
|
|
28310
|
+
its 15rem and the popover its size. The wrapper no longer scrolls (and no longer clips the
|
|
28311
|
+
rings): the facet's own list is the one scrollbar. -->
|
|
28312
|
+
<!-- The facet is capped by the smaller of two heights: its comfortable size (19 lines of list +
|
|
28313
|
+
7rem of header, search box and paddings), and the room the popover really has.
|
|
28314
|
+
size() (added to injectPopover) exposes that room, in the chosen direction, as the
|
|
28315
|
+
--popover-available-height CSS var — flip()/shift() alone only reposition the popover, they
|
|
28316
|
+
never shrink it. The 1.5rem subtracted is this popover's own vertical padding (p-3), which
|
|
28317
|
+
eats into that same available space (this wrapper's p-1 / -m-1 cancel out). The facet is a
|
|
28318
|
+
flex column whose list is min-h-0 flex-1, so it is the list that shrinks and scrolls — a
|
|
28319
|
+
capped wrapper with overflow-y-auto around it would add a second, outer scrollbar. -->
|
|
28320
|
+
<div class="-m-1 w-[15.5rem] p-1">
|
|
27901
28321
|
@let name = filter().name;
|
|
27902
28322
|
@let column = filter().column;
|
|
27903
28323
|
@if (name) {
|
|
27904
28324
|
<Aggregation
|
|
27905
|
-
class="
|
|
28325
|
+
class="w-full max-h-[min(calc(19lh+7rem),calc(var(--popover-available-height,55vh)_-_1.5rem))]"
|
|
27906
28326
|
id="filter-{{ filter().column }}"
|
|
27907
28327
|
[name]="name"
|
|
27908
28328
|
[column]="column"
|
|
@@ -27979,6 +28399,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
27979
28399
|
required: false
|
|
27980
28400
|
}]
|
|
27981
28401
|
}],
|
|
28402
|
+
overflowed: [{
|
|
28403
|
+
type: i0.Input,
|
|
28404
|
+
args: [{
|
|
28405
|
+
isSignal: true,
|
|
28406
|
+
alias: "overflowed",
|
|
28407
|
+
required: false
|
|
28408
|
+
}]
|
|
28409
|
+
}],
|
|
27982
28410
|
popoverRef: [{
|
|
27983
28411
|
type: i0.ViewChild,
|
|
27984
28412
|
args: [i0.forwardRef(() => PopoverDirective), { isSignal: true }]
|
|
@@ -28102,7 +28530,7 @@ var MoreComponent = class MoreComponent {
|
|
|
28102
28530
|
<div role="group" [attr.aria-label]="'filters.moreFilters' | transloco" class="divide-y divide-(--font-neutral-muted)/18 pt-1 pb-1">
|
|
28103
28531
|
@for (filter of filteredFilters(); track filter.name) {
|
|
28104
28532
|
<Aggregation
|
|
28105
|
-
class="w-full px-1 [
|
|
28533
|
+
class="w-full px-1 max-h-[calc(15lh+7rem)]"
|
|
28106
28534
|
id="more-filters"
|
|
28107
28535
|
[attr.title]="'filters.openFilter' | transloco: { filter: filter.name }"
|
|
28108
28536
|
showFiltersCount
|
|
@@ -28205,7 +28633,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
28205
28633
|
<div role="group" [attr.aria-label]="'filters.moreFilters' | transloco" class="divide-y divide-(--font-neutral-muted)/18 pt-1 pb-1">
|
|
28206
28634
|
@for (filter of filteredFilters(); track filter.name) {
|
|
28207
28635
|
<Aggregation
|
|
28208
|
-
class="w-full px-1 [
|
|
28636
|
+
class="w-full px-1 max-h-[calc(15lh+7rem)]"
|
|
28209
28637
|
id="more-filters"
|
|
28210
28638
|
[attr.title]="'filters.openFilter' | transloco: { filter: filter.name }"
|
|
28211
28639
|
showFiltersCount
|
|
@@ -28293,6 +28721,15 @@ var MoreButtonComponent = class MoreButtonComponent {
|
|
|
28293
28721
|
nativeElement = inject(ElementRef).nativeElement;
|
|
28294
28722
|
breakpointObserver = inject(BreakpointObserverService);
|
|
28295
28723
|
aggregationsService = inject(AggregationsService);
|
|
28724
|
+
toolbar = inject(Toolbar, { optional: true });
|
|
28725
|
+
disabled = input(false, {
|
|
28726
|
+
...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
|
|
28727
|
+
transform: booleanAttribute
|
|
28728
|
+
});
|
|
28729
|
+
triggerClass = "gap-1 truncate font-semibold";
|
|
28730
|
+
openTriggerClass = "gap-1 truncate font-semibold border border-(--stroke-neutral-dark)/18";
|
|
28731
|
+
openSheet = () => this.sheetRef()?.open();
|
|
28732
|
+
openDialog = () => this.dialogRef()?.showModal();
|
|
28296
28733
|
count = input(2, {
|
|
28297
28734
|
...ngDevMode ? { debugName: "count" } : /* istanbul ignore next */ {},
|
|
28298
28735
|
transform: numberAttribute
|
|
@@ -28346,6 +28783,13 @@ var MoreButtonComponent = class MoreButtonComponent {
|
|
|
28346
28783
|
isStandalone: true,
|
|
28347
28784
|
selector: "more-button, MoreButton",
|
|
28348
28785
|
inputs: {
|
|
28786
|
+
disabled: {
|
|
28787
|
+
classPropertyName: "disabled",
|
|
28788
|
+
publicName: "disabled",
|
|
28789
|
+
isSignal: true,
|
|
28790
|
+
isRequired: false,
|
|
28791
|
+
transformFunction: null
|
|
28792
|
+
},
|
|
28349
28793
|
count: {
|
|
28350
28794
|
classPropertyName: "count",
|
|
28351
28795
|
publicName: "count",
|
|
@@ -28447,10 +28891,24 @@ var MoreButtonComponent = class MoreButtonComponent {
|
|
|
28447
28891
|
}
|
|
28448
28892
|
</ng-template>
|
|
28449
28893
|
|
|
28894
|
+
<!-- The trigger button, shared by the three variants below. Inside a toolbar the BUTTON is the
|
|
28895
|
+
roving widget and not the host: the host is an element with no role of its own and no key
|
|
28896
|
+
handler, so an arrow key landed on a dead element, then the button was a second tab stop.
|
|
28897
|
+
Outside a toolbar it is a plain button. -->
|
|
28898
|
+
<ng-template #button let-onClick="onClick" let-popoverTarget="popoverTarget" let-cls="cls">
|
|
28899
|
+
@if (toolbar) {
|
|
28900
|
+
<button ngToolbarWidget variant="tertiary" [attr.popovertarget]="popoverTarget" [class]="cls" aria-label="more filters" [disabled]="disabled()" (click)="onClick?.()">
|
|
28901
|
+
<ng-container *ngTemplateOutlet="trigger" />
|
|
28902
|
+
</button>
|
|
28903
|
+
} @else {
|
|
28904
|
+
<button variant="tertiary" [attr.popovertarget]="popoverTarget" [class]="cls" aria-label="more filters" [disabled]="disabled() || null" (click)="onClick?.()">
|
|
28905
|
+
<ng-container *ngTemplateOutlet="trigger" />
|
|
28906
|
+
</button>
|
|
28907
|
+
}
|
|
28908
|
+
</ng-template>
|
|
28909
|
+
|
|
28450
28910
|
@if (breakpointObserver.isMobile()) {
|
|
28451
|
-
<
|
|
28452
|
-
<ng-container *ngTemplateOutlet="trigger" />
|
|
28453
|
-
</button>
|
|
28911
|
+
<ng-container *ngTemplateOutlet="button; context: { onClick: openSheet, cls: triggerClass }" />
|
|
28454
28912
|
|
|
28455
28913
|
<Sheet side="bottom" size="lg">
|
|
28456
28914
|
<SheetHeader [closeLabel]="'filters.close' | transloco">
|
|
@@ -28470,9 +28928,7 @@ var MoreButtonComponent = class MoreButtonComponent {
|
|
|
28470
28928
|
</SheetBody>
|
|
28471
28929
|
</Sheet>
|
|
28472
28930
|
} @else if (isEnriched()) {
|
|
28473
|
-
<
|
|
28474
|
-
<ng-container *ngTemplateOutlet="trigger" />
|
|
28475
|
-
</button>
|
|
28931
|
+
<ng-container *ngTemplateOutlet="button; context: { onClick: openDialog, cls: triggerClass }" />
|
|
28476
28932
|
|
|
28477
28933
|
<dialog>
|
|
28478
28934
|
<DialogContent size="md">
|
|
@@ -28492,13 +28948,7 @@ var MoreButtonComponent = class MoreButtonComponent {
|
|
|
28492
28948
|
</DialogContent>
|
|
28493
28949
|
</dialog>
|
|
28494
28950
|
} @else {
|
|
28495
|
-
<button
|
|
28496
|
-
variant="tertiary"
|
|
28497
|
-
[attr.popovertarget]="popoverId"
|
|
28498
|
-
[class]="isOpen() ? 'gap-1 truncate font-semibold border border-(--stroke-neutral-dark)/18' : 'gap-1 truncate font-semibold'"
|
|
28499
|
-
aria-label="more filters">
|
|
28500
|
-
<ng-container *ngTemplateOutlet="trigger" />
|
|
28501
|
-
</button>
|
|
28951
|
+
<ng-container *ngTemplateOutlet="button; context: { popoverTarget: popoverId, cls: isOpen() ? openTriggerClass : triggerClass }" />
|
|
28502
28952
|
|
|
28503
28953
|
<!-- Native HTML Popover (top-layer). Fully isolate pointer/click events from
|
|
28504
28954
|
the surrounding @angular/aria toolbar (see FilterButton for the rationale:
|
|
@@ -28548,6 +28998,13 @@ var MoreButtonComponent = class MoreButtonComponent {
|
|
|
28548
28998
|
"ngTemplateOutletInjector"
|
|
28549
28999
|
]
|
|
28550
29000
|
},
|
|
29001
|
+
{
|
|
29002
|
+
kind: "directive",
|
|
29003
|
+
type: ToolbarWidget,
|
|
29004
|
+
selector: "[ngToolbarWidget]",
|
|
29005
|
+
inputs: ["id", "disabled"],
|
|
29006
|
+
exportAs: ["ngToolbarWidget"]
|
|
29007
|
+
},
|
|
28551
29008
|
{
|
|
28552
29009
|
kind: "directive",
|
|
28553
29010
|
type: ButtonComponent,
|
|
@@ -28693,6 +29150,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
28693
29150
|
selector: "more-button, MoreButton",
|
|
28694
29151
|
imports: [
|
|
28695
29152
|
NgTemplateOutlet,
|
|
29153
|
+
ToolbarWidget,
|
|
28696
29154
|
ButtonComponent,
|
|
28697
29155
|
PopoverDirective,
|
|
28698
29156
|
TranslocoPipe,
|
|
@@ -28720,10 +29178,24 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
28720
29178
|
}
|
|
28721
29179
|
</ng-template>
|
|
28722
29180
|
|
|
29181
|
+
<!-- The trigger button, shared by the three variants below. Inside a toolbar the BUTTON is the
|
|
29182
|
+
roving widget and not the host: the host is an element with no role of its own and no key
|
|
29183
|
+
handler, so an arrow key landed on a dead element, then the button was a second tab stop.
|
|
29184
|
+
Outside a toolbar it is a plain button. -->
|
|
29185
|
+
<ng-template #button let-onClick="onClick" let-popoverTarget="popoverTarget" let-cls="cls">
|
|
29186
|
+
@if (toolbar) {
|
|
29187
|
+
<button ngToolbarWidget variant="tertiary" [attr.popovertarget]="popoverTarget" [class]="cls" aria-label="more filters" [disabled]="disabled()" (click)="onClick?.()">
|
|
29188
|
+
<ng-container *ngTemplateOutlet="trigger" />
|
|
29189
|
+
</button>
|
|
29190
|
+
} @else {
|
|
29191
|
+
<button variant="tertiary" [attr.popovertarget]="popoverTarget" [class]="cls" aria-label="more filters" [disabled]="disabled() || null" (click)="onClick?.()">
|
|
29192
|
+
<ng-container *ngTemplateOutlet="trigger" />
|
|
29193
|
+
</button>
|
|
29194
|
+
}
|
|
29195
|
+
</ng-template>
|
|
29196
|
+
|
|
28723
29197
|
@if (breakpointObserver.isMobile()) {
|
|
28724
|
-
<
|
|
28725
|
-
<ng-container *ngTemplateOutlet="trigger" />
|
|
28726
|
-
</button>
|
|
29198
|
+
<ng-container *ngTemplateOutlet="button; context: { onClick: openSheet, cls: triggerClass }" />
|
|
28727
29199
|
|
|
28728
29200
|
<Sheet side="bottom" size="lg">
|
|
28729
29201
|
<SheetHeader [closeLabel]="'filters.close' | transloco">
|
|
@@ -28743,9 +29215,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
28743
29215
|
</SheetBody>
|
|
28744
29216
|
</Sheet>
|
|
28745
29217
|
} @else if (isEnriched()) {
|
|
28746
|
-
<
|
|
28747
|
-
<ng-container *ngTemplateOutlet="trigger" />
|
|
28748
|
-
</button>
|
|
29218
|
+
<ng-container *ngTemplateOutlet="button; context: { onClick: openDialog, cls: triggerClass }" />
|
|
28749
29219
|
|
|
28750
29220
|
<dialog>
|
|
28751
29221
|
<DialogContent size="md">
|
|
@@ -28765,13 +29235,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
28765
29235
|
</DialogContent>
|
|
28766
29236
|
</dialog>
|
|
28767
29237
|
} @else {
|
|
28768
|
-
<button
|
|
28769
|
-
variant="tertiary"
|
|
28770
|
-
[attr.popovertarget]="popoverId"
|
|
28771
|
-
[class]="isOpen() ? 'gap-1 truncate font-semibold border border-(--stroke-neutral-dark)/18' : 'gap-1 truncate font-semibold'"
|
|
28772
|
-
aria-label="more filters">
|
|
28773
|
-
<ng-container *ngTemplateOutlet="trigger" />
|
|
28774
|
-
</button>
|
|
29238
|
+
<ng-container *ngTemplateOutlet="button; context: { popoverTarget: popoverId, cls: isOpen() ? openTriggerClass : triggerClass }" />
|
|
28775
29239
|
|
|
28776
29240
|
<!-- Native HTML Popover (top-layer). Fully isolate pointer/click events from
|
|
28777
29241
|
the surrounding @angular/aria toolbar (see FilterButton for the rationale:
|
|
@@ -28813,6 +29277,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
28813
29277
|
}]
|
|
28814
29278
|
}],
|
|
28815
29279
|
propDecorators: {
|
|
29280
|
+
disabled: [{
|
|
29281
|
+
type: i0.Input,
|
|
29282
|
+
args: [{
|
|
29283
|
+
isSignal: true,
|
|
29284
|
+
alias: "disabled",
|
|
29285
|
+
required: false
|
|
29286
|
+
}]
|
|
29287
|
+
}],
|
|
28816
29288
|
count: [{
|
|
28817
29289
|
type: i0.Input,
|
|
28818
29290
|
args: [{
|
|
@@ -29127,7 +29599,7 @@ var FiltersBarComponent = class FiltersBarComponent {
|
|
|
29127
29599
|
tabindex with it: the keyboard stopped on an invisible strip of zero height, announced
|
|
29128
29600
|
"Filter controls" and disabled at once. -->
|
|
29129
29601
|
@if (hasFilters() || currentBasket() || hasAggregations()) {
|
|
29130
|
-
<div ngToolbar [attr.aria-label]="ariaLabel() ?? ('filters.filterControls' | transloco)" overflowManager [direction]="direction()" [reserveStop]="hasCappedFilters()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
29602
|
+
<div ngToolbar [softDisabled]="false" [attr.aria-label]="ariaLabel() ?? ('filters.filterControls' | transloco)" overflowManager [direction]="direction()" [reserveStop]="hasCappedFilters()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
29131
29603
|
@if (hasFilters()) {
|
|
29132
29604
|
<button
|
|
29133
29605
|
ngToolbarWidget
|
|
@@ -29165,10 +29637,13 @@ var FiltersBarComponent = class FiltersBarComponent {
|
|
|
29165
29637
|
: 'flex-row'
|
|
29166
29638
|
)">
|
|
29167
29639
|
|
|
29168
|
-
@for (filter of authorizedFilters(); track filter.name) {
|
|
29640
|
+
@for (filter of authorizedFilters(); track filter.name; let i = $index) {
|
|
29641
|
+
<!-- No ngToolbarWidget here: FilterButton makes its own inner button the roving widget, so the
|
|
29642
|
+
bar has one tab stop per filter and not two (host, then button). A filter hidden by the
|
|
29643
|
+
overflow manager is disabled, hence skipped by the roving (the toolbar is not soft-disabled). -->
|
|
29169
29644
|
<FilterButton
|
|
29170
|
-
ngToolbarWidget
|
|
29171
29645
|
overflowItem
|
|
29646
|
+
[overflowed]="i >= visibleFiltersCount()"
|
|
29172
29647
|
[name]="filter.name"
|
|
29173
29648
|
[column]="filter.column"
|
|
29174
29649
|
[position]="position()"
|
|
@@ -29184,8 +29659,8 @@ var FiltersBarComponent = class FiltersBarComponent {
|
|
|
29184
29659
|
forbids the attribute. The name belongs to the <button> inside MoreButton, which
|
|
29185
29660
|
already carries it. -->
|
|
29186
29661
|
<MoreButton
|
|
29187
|
-
ngToolbarWidget
|
|
29188
29662
|
overflowStop
|
|
29663
|
+
[disabled]="hasMoreFilters().length === 0"
|
|
29189
29664
|
[class]="cn('shrink-0', hasMoreFilters().length === 0 && 'invisible pointer-events-none')"
|
|
29190
29665
|
[count]="visibleFiltersCount()"
|
|
29191
29666
|
[position]="morePosition()"
|
|
@@ -29218,6 +29693,7 @@ var FiltersBarComponent = class FiltersBarComponent {
|
|
|
29218
29693
|
type: MoreButtonComponent,
|
|
29219
29694
|
selector: "more-button, MoreButton",
|
|
29220
29695
|
inputs: [
|
|
29696
|
+
"disabled",
|
|
29221
29697
|
"count",
|
|
29222
29698
|
"position",
|
|
29223
29699
|
"lockPosition",
|
|
@@ -29239,7 +29715,8 @@ var FiltersBarComponent = class FiltersBarComponent {
|
|
|
29239
29715
|
"position",
|
|
29240
29716
|
"offset",
|
|
29241
29717
|
"lockPosition",
|
|
29242
|
-
"expandedLevel"
|
|
29718
|
+
"expandedLevel",
|
|
29719
|
+
"overflowed"
|
|
29243
29720
|
]
|
|
29244
29721
|
},
|
|
29245
29722
|
{
|
|
@@ -29331,7 +29808,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
29331
29808
|
tabindex with it: the keyboard stopped on an invisible strip of zero height, announced
|
|
29332
29809
|
"Filter controls" and disabled at once. -->
|
|
29333
29810
|
@if (hasFilters() || currentBasket() || hasAggregations()) {
|
|
29334
|
-
<div ngToolbar [attr.aria-label]="ariaLabel() ?? ('filters.filterControls' | transloco)" overflowManager [direction]="direction()" [reserveStop]="hasCappedFilters()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
29811
|
+
<div ngToolbar [softDisabled]="false" [attr.aria-label]="ariaLabel() ?? ('filters.filterControls' | transloco)" overflowManager [direction]="direction()" [reserveStop]="hasCappedFilters()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
29335
29812
|
@if (hasFilters()) {
|
|
29336
29813
|
<button
|
|
29337
29814
|
ngToolbarWidget
|
|
@@ -29369,10 +29846,13 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
29369
29846
|
: 'flex-row'
|
|
29370
29847
|
)">
|
|
29371
29848
|
|
|
29372
|
-
@for (filter of authorizedFilters(); track filter.name) {
|
|
29849
|
+
@for (filter of authorizedFilters(); track filter.name; let i = $index) {
|
|
29850
|
+
<!-- No ngToolbarWidget here: FilterButton makes its own inner button the roving widget, so the
|
|
29851
|
+
bar has one tab stop per filter and not two (host, then button). A filter hidden by the
|
|
29852
|
+
overflow manager is disabled, hence skipped by the roving (the toolbar is not soft-disabled). -->
|
|
29373
29853
|
<FilterButton
|
|
29374
|
-
ngToolbarWidget
|
|
29375
29854
|
overflowItem
|
|
29855
|
+
[overflowed]="i >= visibleFiltersCount()"
|
|
29376
29856
|
[name]="filter.name"
|
|
29377
29857
|
[column]="filter.column"
|
|
29378
29858
|
[position]="position()"
|
|
@@ -29388,8 +29868,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
29388
29868
|
forbids the attribute. The name belongs to the <button> inside MoreButton, which
|
|
29389
29869
|
already carries it. -->
|
|
29390
29870
|
<MoreButton
|
|
29391
|
-
ngToolbarWidget
|
|
29392
29871
|
overflowStop
|
|
29872
|
+
[disabled]="hasMoreFilters().length === 0"
|
|
29393
29873
|
[class]="cn('shrink-0', hasMoreFilters().length === 0 && 'invisible pointer-events-none')"
|
|
29394
29874
|
[count]="visibleFiltersCount()"
|
|
29395
29875
|
[position]="morePosition()"
|
|
@@ -30211,7 +30691,7 @@ var RecentSearchesComponent = class RecentSearchesComponent {
|
|
|
30211
30691
|
template: `
|
|
30212
30692
|
<ListPanelHeader [label]="'searches.recent.label' | transloco" [floating]="!!floating" />
|
|
30213
30693
|
|
|
30214
|
-
<ListPanel
|
|
30694
|
+
<ListPanel #panel
|
|
30215
30695
|
[items]="paginatedRecentSearches()"
|
|
30216
30696
|
[getValue]="urlOf"
|
|
30217
30697
|
[getLabel]="labelOf"
|
|
@@ -30243,7 +30723,7 @@ var RecentSearchesComponent = class RecentSearchesComponent {
|
|
|
30243
30723
|
</ListPanel>
|
|
30244
30724
|
|
|
30245
30725
|
@if (paginatedRecentSearches().length > 0) {
|
|
30246
|
-
<ListPanelFooter
|
|
30726
|
+
<ListPanelFooter [navigationHint]="panel.keyboardFocused()"
|
|
30247
30727
|
[hasMore]="hasMore()"
|
|
30248
30728
|
[config]="config"
|
|
30249
30729
|
(loadMore)="loadMore()" />
|
|
@@ -30320,6 +30800,7 @@ var RecentSearchesComponent = class RecentSearchesComponent {
|
|
|
30320
30800
|
"getValue",
|
|
30321
30801
|
"getLabel",
|
|
30322
30802
|
"deleteButtonTitle",
|
|
30803
|
+
"deletable",
|
|
30323
30804
|
"ariaLabel",
|
|
30324
30805
|
"itemClass"
|
|
30325
30806
|
],
|
|
@@ -30332,7 +30813,8 @@ var RecentSearchesComponent = class RecentSearchesComponent {
|
|
|
30332
30813
|
inputs: [
|
|
30333
30814
|
"class",
|
|
30334
30815
|
"hasMore",
|
|
30335
|
-
"config"
|
|
30816
|
+
"config",
|
|
30817
|
+
"navigationHint"
|
|
30336
30818
|
],
|
|
30337
30819
|
outputs: ["loadMore"]
|
|
30338
30820
|
},
|
|
@@ -30370,7 +30852,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
30370
30852
|
template: `
|
|
30371
30853
|
<ListPanelHeader [label]="'searches.recent.label' | transloco" [floating]="!!floating" />
|
|
30372
30854
|
|
|
30373
|
-
<ListPanel
|
|
30855
|
+
<ListPanel #panel
|
|
30374
30856
|
[items]="paginatedRecentSearches()"
|
|
30375
30857
|
[getValue]="urlOf"
|
|
30376
30858
|
[getLabel]="labelOf"
|
|
@@ -30402,7 +30884,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
30402
30884
|
</ListPanel>
|
|
30403
30885
|
|
|
30404
30886
|
@if (paginatedRecentSearches().length > 0) {
|
|
30405
|
-
<ListPanelFooter
|
|
30887
|
+
<ListPanelFooter [navigationHint]="panel.keyboardFocused()"
|
|
30406
30888
|
[hasMore]="hasMore()"
|
|
30407
30889
|
[config]="config"
|
|
30408
30890
|
(loadMore)="loadMore()" />
|
|
@@ -30487,7 +30969,7 @@ var SavedSearchDialog = class SavedSearchDialog {
|
|
|
30487
30969
|
[formField]="nameField"
|
|
30488
30970
|
[attr.aria-label]="'searches.saved.saveName' | transloco"
|
|
30489
30971
|
[attr.placeholder]="'searches.saved.saveName' | transloco"
|
|
30490
|
-
(keydown.enter)="saveName().trim() && confirm()" />
|
|
30972
|
+
(keydown.enter)="$event.preventDefault(); saveName().trim() && confirm()" />
|
|
30491
30973
|
</input-group>
|
|
30492
30974
|
</DialogBody>
|
|
30493
30975
|
|
|
@@ -30634,7 +31116,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
30634
31116
|
[formField]="nameField"
|
|
30635
31117
|
[attr.aria-label]="'searches.saved.saveName' | transloco"
|
|
30636
31118
|
[attr.placeholder]="'searches.saved.saveName' | transloco"
|
|
30637
|
-
(keydown.enter)="saveName().trim() && confirm()" />
|
|
31119
|
+
(keydown.enter)="$event.preventDefault(); saveName().trim() && confirm()" />
|
|
30638
31120
|
</input-group>
|
|
30639
31121
|
</DialogBody>
|
|
30640
31122
|
|
|
@@ -30932,7 +31414,7 @@ var SavedSearchesComponent = class SavedSearchesComponent {
|
|
|
30932
31414
|
template: `
|
|
30933
31415
|
<ListPanelHeader [label]="'searches.saved.label' | transloco" [floating]="!!floating" />
|
|
30934
31416
|
|
|
30935
|
-
<ListPanel
|
|
31417
|
+
<ListPanel #panel
|
|
30936
31418
|
[items]="paginatedSearches()"
|
|
30937
31419
|
[getValue]="urlOf"
|
|
30938
31420
|
[getLabel]="labelOf"
|
|
@@ -30964,7 +31446,7 @@ var SavedSearchesComponent = class SavedSearchesComponent {
|
|
|
30964
31446
|
</ListPanel>
|
|
30965
31447
|
|
|
30966
31448
|
@if(paginatedSearches().length > 0) {
|
|
30967
|
-
<ListPanelFooter [hasMore]="hasMore()" [config]="config" (loadMore)="loadMore()" />
|
|
31449
|
+
<ListPanelFooter [navigationHint]="panel.keyboardFocused()" [hasMore]="hasMore()" [config]="config" (loadMore)="loadMore()" />
|
|
30968
31450
|
}
|
|
30969
31451
|
`,
|
|
30970
31452
|
isInline: true,
|
|
@@ -31038,6 +31520,7 @@ var SavedSearchesComponent = class SavedSearchesComponent {
|
|
|
31038
31520
|
"getValue",
|
|
31039
31521
|
"getLabel",
|
|
31040
31522
|
"deleteButtonTitle",
|
|
31523
|
+
"deletable",
|
|
31041
31524
|
"ariaLabel",
|
|
31042
31525
|
"itemClass"
|
|
31043
31526
|
],
|
|
@@ -31050,7 +31533,8 @@ var SavedSearchesComponent = class SavedSearchesComponent {
|
|
|
31050
31533
|
inputs: [
|
|
31051
31534
|
"class",
|
|
31052
31535
|
"hasMore",
|
|
31053
|
-
"config"
|
|
31536
|
+
"config",
|
|
31537
|
+
"navigationHint"
|
|
31054
31538
|
],
|
|
31055
31539
|
outputs: ["loadMore"]
|
|
31056
31540
|
},
|
|
@@ -31088,7 +31572,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
31088
31572
|
template: `
|
|
31089
31573
|
<ListPanelHeader [label]="'searches.saved.label' | transloco" [floating]="!!floating" />
|
|
31090
31574
|
|
|
31091
|
-
<ListPanel
|
|
31575
|
+
<ListPanel #panel
|
|
31092
31576
|
[items]="paginatedSearches()"
|
|
31093
31577
|
[getValue]="urlOf"
|
|
31094
31578
|
[getLabel]="labelOf"
|
|
@@ -31120,7 +31604,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
31120
31604
|
</ListPanel>
|
|
31121
31605
|
|
|
31122
31606
|
@if(paginatedSearches().length > 0) {
|
|
31123
|
-
<ListPanelFooter [hasMore]="hasMore()" [config]="config" (loadMore)="loadMore()" />
|
|
31607
|
+
<ListPanelFooter [navigationHint]="panel.keyboardFocused()" [hasMore]="hasMore()" [config]="config" (loadMore)="loadMore()" />
|
|
31124
31608
|
}
|
|
31125
31609
|
`
|
|
31126
31610
|
}]
|
|
@@ -31555,7 +32039,11 @@ function splitPropertyId(id) {
|
|
|
31555
32039
|
key: id.slice(separator + 1)
|
|
31556
32040
|
};
|
|
31557
32041
|
}
|
|
32042
|
+
const FIRST_CONTROL = "button:not(:disabled), textarea, input:not([type='file']), a[href]";
|
|
31558
32043
|
var SettingsAccountPanelComponent = class SettingsAccountPanelComponent {
|
|
32044
|
+
focusOnOpen = input(false, ...ngDevMode ? [{ debugName: "focusOnOpen" }] : /* istanbul ignore next */ []);
|
|
32045
|
+
host = inject(ElementRef);
|
|
32046
|
+
destroyRef = inject(DestroyRef);
|
|
31559
32047
|
principalStore = inject(PrincipalStore);
|
|
31560
32048
|
appStore = inject(AppStore);
|
|
31561
32049
|
client = inject(ATOMIC_CLIENT);
|
|
@@ -31568,6 +32056,13 @@ var SettingsAccountPanelComponent = class SettingsAccountPanelComponent {
|
|
|
31568
32056
|
const { allowChangePassword = false } = this.appStore.general()?.features || {};
|
|
31569
32057
|
return allowChangePassword && useCredentials && (this.principalStore.editablePartition?.() || false);
|
|
31570
32058
|
}, ...ngDevMode ? [{ debugName: "allowChangePassword" }] : /* istanbul ignore next */ []);
|
|
32059
|
+
constructor() {
|
|
32060
|
+
afterNextRender(() => {
|
|
32061
|
+
if (!this.focusOnOpen()) return;
|
|
32062
|
+
const frame = requestAnimationFrame(() => focusWhenReady(() => this.host.nativeElement.querySelector(FIRST_CONTROL), "settings-account-panel", { destroyRef: this.destroyRef }));
|
|
32063
|
+
this.destroyRef.onDestroy(() => cancelAnimationFrame(frame));
|
|
32064
|
+
});
|
|
32065
|
+
}
|
|
31571
32066
|
resetSettings() {
|
|
31572
32067
|
ResetUserSettings.call(void 0, { injector: this.injector });
|
|
31573
32068
|
}
|
|
@@ -31591,6 +32086,13 @@ var SettingsAccountPanelComponent = class SettingsAccountPanelComponent {
|
|
|
31591
32086
|
type: SettingsAccountPanelComponent,
|
|
31592
32087
|
isStandalone: true,
|
|
31593
32088
|
selector: "settings-account-panel",
|
|
32089
|
+
inputs: { focusOnOpen: {
|
|
32090
|
+
classPropertyName: "focusOnOpen",
|
|
32091
|
+
publicName: "focusOnOpen",
|
|
32092
|
+
isSignal: true,
|
|
32093
|
+
isRequired: false,
|
|
32094
|
+
transformFunction: null
|
|
32095
|
+
} },
|
|
31594
32096
|
providers: [provideTranslocoScope("settings")],
|
|
31595
32097
|
ngImport: i0,
|
|
31596
32098
|
template: `
|
|
@@ -31773,7 +32275,16 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
31773
32275
|
</div>
|
|
31774
32276
|
`
|
|
31775
32277
|
}]
|
|
31776
|
-
}]
|
|
32278
|
+
}],
|
|
32279
|
+
ctorParameters: () => [],
|
|
32280
|
+
propDecorators: { focusOnOpen: [{
|
|
32281
|
+
type: i0.Input,
|
|
32282
|
+
args: [{
|
|
32283
|
+
isSignal: true,
|
|
32284
|
+
alias: "focusOnOpen",
|
|
32285
|
+
required: false
|
|
32286
|
+
}]
|
|
32287
|
+
}] }
|
|
31777
32288
|
});
|
|
31778
32289
|
const THEMES$1 = [
|
|
31779
32290
|
"light",
|
|
@@ -32117,6 +32628,11 @@ var SettingsDialogComponent = class SettingsDialogComponent {
|
|
|
32117
32628
|
}
|
|
32118
32629
|
];
|
|
32119
32630
|
panel = signal(this.call.props()?.panel ?? "account", ...ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []);
|
|
32631
|
+
navigated = signal(false, ...ngDevMode ? [{ debugName: "navigated" }] : /* istanbul ignore next */ []);
|
|
32632
|
+
navigate(id) {
|
|
32633
|
+
this.navigated.set(true);
|
|
32634
|
+
this.panel.set(id);
|
|
32635
|
+
}
|
|
32120
32636
|
duplicate = active !== void 0;
|
|
32121
32637
|
constructor() {
|
|
32122
32638
|
if (active) {
|
|
@@ -32176,7 +32692,7 @@ var SettingsDialogComponent = class SettingsDialogComponent {
|
|
|
32176
32692
|
variant="none"
|
|
32177
32693
|
class="flex h-(--row-height-md) w-full cursor-pointer items-center justify-start gap-(--spacing-xs) rounded-(--radius-sm) border-0 bg-transparent px-(--spacing-xs) text-left text-(--layer-page-font) transition-colors hover:bg-(--bg-primary-light) focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:outline-(--stroke-focus) aria-[current=page]:bg-(--bg-primary-base) aria-[current=page]:text-(--font-neutral-white) aria-[current=page]:hover:bg-(--bg-primary-base)"
|
|
32178
32694
|
[attr.aria-current]="panel() === item.id ? 'page' : null"
|
|
32179
|
-
(click)="
|
|
32695
|
+
(click)="navigate(item.id)">
|
|
32180
32696
|
@switch (item.id) {
|
|
32181
32697
|
@case ("account") {
|
|
32182
32698
|
<user-icon aria-hidden="true" />
|
|
@@ -32197,7 +32713,7 @@ var SettingsDialogComponent = class SettingsDialogComponent {
|
|
|
32197
32713
|
<div class="m-(--spacing-xs) flex min-w-0 flex-1 flex-col overflow-y-auto rounded-(--radius-lg) bg-(--layer-page-layer) p-(--spacing-xl)">
|
|
32198
32714
|
@switch (panel()) {
|
|
32199
32715
|
@case ("account") {
|
|
32200
|
-
<settings-account-panel class="flex min-h-0 flex-1 flex-col" />
|
|
32716
|
+
<settings-account-panel class="flex min-h-0 flex-1 flex-col" [focusOnOpen]="!navigated()" />
|
|
32201
32717
|
}
|
|
32202
32718
|
@case ("appearance") {
|
|
32203
32719
|
<settings-appearance-panel />
|
|
@@ -32270,7 +32786,8 @@ var SettingsDialogComponent = class SettingsDialogComponent {
|
|
|
32270
32786
|
{
|
|
32271
32787
|
kind: "component",
|
|
32272
32788
|
type: SettingsAccountPanelComponent,
|
|
32273
|
-
selector: "settings-account-panel"
|
|
32789
|
+
selector: "settings-account-panel",
|
|
32790
|
+
inputs: ["focusOnOpen"]
|
|
32274
32791
|
},
|
|
32275
32792
|
{
|
|
32276
32793
|
kind: "component",
|
|
@@ -32336,7 +32853,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
32336
32853
|
variant="none"
|
|
32337
32854
|
class="flex h-(--row-height-md) w-full cursor-pointer items-center justify-start gap-(--spacing-xs) rounded-(--radius-sm) border-0 bg-transparent px-(--spacing-xs) text-left text-(--layer-page-font) transition-colors hover:bg-(--bg-primary-light) focus-visible:outline-2 focus-visible:outline-offset-0 focus-visible:outline-(--stroke-focus) aria-[current=page]:bg-(--bg-primary-base) aria-[current=page]:text-(--font-neutral-white) aria-[current=page]:hover:bg-(--bg-primary-base)"
|
|
32338
32855
|
[attr.aria-current]="panel() === item.id ? 'page' : null"
|
|
32339
|
-
(click)="
|
|
32856
|
+
(click)="navigate(item.id)">
|
|
32340
32857
|
@switch (item.id) {
|
|
32341
32858
|
@case ("account") {
|
|
32342
32859
|
<user-icon aria-hidden="true" />
|
|
@@ -32357,7 +32874,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
32357
32874
|
<div class="m-(--spacing-xs) flex min-w-0 flex-1 flex-col overflow-y-auto rounded-(--radius-lg) bg-(--layer-page-layer) p-(--spacing-xl)">
|
|
32358
32875
|
@switch (panel()) {
|
|
32359
32876
|
@case ("account") {
|
|
32360
|
-
<settings-account-panel class="flex min-h-0 flex-1 flex-col" />
|
|
32877
|
+
<settings-account-panel class="flex min-h-0 flex-1 flex-col" [focusOnOpen]="!navigated()" />
|
|
32361
32878
|
}
|
|
32362
32879
|
@case ("appearance") {
|
|
32363
32880
|
<settings-appearance-panel />
|
|
@@ -32712,10 +33229,12 @@ const SCOPE = "session-expiry";
|
|
|
32712
33229
|
const SCOPE_ALIAS = "sessionExpiry";
|
|
32713
33230
|
const FALLBACK = {
|
|
32714
33231
|
expiringTitle: "Your session is about to expire",
|
|
32715
|
-
expiringDescription: "It expires in about {{minutes}} min.
|
|
33232
|
+
expiringDescription: "It expires in about {{minutes}} min. Extend your session to keep it open.",
|
|
32716
33233
|
expiredTitle: "Your session has expired",
|
|
32717
33234
|
expiredDescription: "Sign in again to continue.",
|
|
32718
|
-
reload: "Sign in again"
|
|
33235
|
+
reload: "Sign in again",
|
|
33236
|
+
extend: "Extend session",
|
|
33237
|
+
extendedTitle: "Your session has been extended"
|
|
32719
33238
|
};
|
|
32720
33239
|
function provideSessionExpiry(options = {}) {
|
|
32721
33240
|
const warnBeforeMs = options.warnBeforeMs ?? DEFAULT_WARN_BEFORE_MS;
|
|
@@ -32753,14 +33272,36 @@ function provideSessionExpiry(options = {}) {
|
|
|
32753
33272
|
await settled;
|
|
32754
33273
|
if (!stillDue()) return;
|
|
32755
33274
|
const minutes = Math.max(1, Math.ceil((expiresAt - Date.now()) / 6e4));
|
|
32756
|
-
const [title, description] = await Promise.all([
|
|
33275
|
+
const [title, description, extendLabel] = await Promise.all([
|
|
33276
|
+
translate("expiringTitle"),
|
|
33277
|
+
translate("expiringDescription", { minutes }),
|
|
33278
|
+
translate("extend")
|
|
33279
|
+
]);
|
|
32757
33280
|
if (!stillDue()) return;
|
|
32758
33281
|
notify.warning(title, {
|
|
32759
33282
|
description,
|
|
32760
33283
|
closeButton: true,
|
|
32761
|
-
important: true
|
|
33284
|
+
important: true,
|
|
33285
|
+
action: {
|
|
33286
|
+
label: extendLabel,
|
|
33287
|
+
onClick: () => void extend()
|
|
33288
|
+
}
|
|
32762
33289
|
});
|
|
32763
33290
|
};
|
|
33291
|
+
const extend = async () => {
|
|
33292
|
+
if (options.onExtend) return options.onExtend();
|
|
33293
|
+
const before = expiresAt;
|
|
33294
|
+
try {
|
|
33295
|
+
await client.api.principal.get();
|
|
33296
|
+
} catch {
|
|
33297
|
+
return;
|
|
33298
|
+
}
|
|
33299
|
+
if (before !== null && expiresAt !== null && expiresAt > before) {
|
|
33300
|
+
notify.success(await translate("extendedTitle"), { closeButton: true });
|
|
33301
|
+
return;
|
|
33302
|
+
}
|
|
33303
|
+
onReconnect();
|
|
33304
|
+
};
|
|
32764
33305
|
const check = () => {
|
|
32765
33306
|
if (expiresAt === null || warned) return;
|
|
32766
33307
|
const delay = expiresAt - warnBeforeMs - Date.now();
|
|
@@ -32830,6 +33371,6 @@ function provideSessionExpiry(options = {}) {
|
|
|
32830
33371
|
const queryNameResolver = () => {
|
|
32831
33372
|
return inject(AppStore).getDefaultQuery()?.name || "";
|
|
32832
33373
|
};
|
|
32833
|
-
export { AGGREGATIONS_NAMES, AGGREGATIONS_NAMES_PRESET_DEFAULT, APP_FEATURES, ATOMIC_CLIENT, ATOMIC_SCOPED_PROVIDERS, AddToCollection, AdvancedFiltersBodyComponent, AdvancedFiltersComponent, AdvancedSearch, AdvancedSearchTabs, AggregationComponent, AggregationDateComponent, AggregationDateRange, AggregationItemDirective, AggregationListComponent, AggregationPanelComponent, AggregationTreeComponent, AggregationsService, AggregationsStore, Alert, AlertDialog, AlertForm, AlertsComponent, AppService, AppStore, ApplicationService, ApplicationStore, AppliedFiltersComponent, ArticleEntities, ArticleEntitiesTabPanel, ArticleExtracts, ArticleExtractsTabPanel, ArticleHighlights, ArticleLabels, ArticleLabelsTabPanel, ArticleMatchLocations, ArticleMatchLocationsTabPanel, ArticleSimilarDocuments, ArticleSimilarDocumentsTabPanel, AsideFiltersComponent, AuditFeedbackType, AuditService, AuthGuard, AuthPageComponent, AutocompleteService, BOOKMARKS_CONFIG, BOOKMARKS_OPTIONS, BackdropComponent, BackdropService, BookmarkButtonComponent, BookmarksComponent, COLLECTIONS_CONFIG, COLLECTIONS_OPTIONS, COMPONENTS_FOR_DOCUMENT_TYPE, ChangePasswordComponent, ChildMarkerDirective, CollectionsComponent, CollectionsDialog, ConverterSelectComponent, DeleteCollection, DeleteCollectionDialog, DidYouMeanComponent, DocumentLocatorComponent, EditLabels, ErrorComponent, Export, ExportDialog, ExportService, FILTERS_BREAKPOINT, FILTER_DATE_ALLOW_CUSTOM_RANGE, FORM_ALERT_CLASS, FORM_BARE_CLASS, FORM_ERROR_CLASS, FORM_FIELD_CLASS, FORM_FOOTER_CLASS, FORM_LABEL_CLASS, FORM_SURFACE_CLASS, FaIconComponent, FeatureFlags, FeatureFlagsDialogComponent, Feedback, FeedbackDialogComponent, FileSizePipe, FilterButtonComponent, FiltersBarComponent, FloatingToolbarComponent, ForgotPasswordComponent, HIGHLIGHTS, HeatmapComponent, HighlightWordPipe, InfinityScrollDirective, InlineWorker, JsonMethodPluginService, KeyboardShortcutsDialog, KeyboardShortcutsDialogComponent, KeyboardShortcutsListComponent, KeyboardShortcutsService, LabelService, LabelsEditDialog, ListPanelItemDirective, LoadingComponent, MarkdownPipe, MarkdownRendererService, MetadataComponent, MissingTermsComponent, MoreButtonComponent, MoreComponent, MultiSelectLabelsComponent, MultiSelectionToolbarComponent, NON_SEARCHABLE_COLUMNS, NON_SEARCHABLE_DEFAULTS, NavbarTabsComponent, NavigationService, NoResultComponent, OpenArticleOnCtrlEnterDirective, OperatorPipe, OverflowItemDirective, OverflowManagerDirective, OverflowStopDirective, OverrideUser, OverrideUserDialogComponent, PREVIEW_ASSISTANT_COMPONENT, PREVIEW_CONFIG, PagerComponent, PreviewActionsComponent, PreviewContentComponent, PreviewHeaderComponent, PreviewNavigator, PreviewService, PrincipalService, PrincipalStore, QueryParamsStore, QueryService, RECENT_SEARCHES_CONFIG, RECENT_SEARCHES_OPTIONS, ROUTE_COMPONENTS, RecentSearchesComponent, ResetUserSettings, ResetUserSettingsDialogComponent, SAVED_SEARCHES_CONFIG, SAVED_SEARCHES_OPTIONS, SavedSearch, SavedSearchDialog, SavedSearchPopover, SavedSearchesComponent, SavedSearchesService, SearchFeedbackComponent, SearchInputFooter, SearchService, SelectArticleDirective, SelectionService, SelectionStore, Settings, SettingsAccountPanelComponent, SettingsAppearancePanelComponent, SettingsDialogComponent, SettingsShortcutsPanelComponent, ShortcutDirective, ShowBookmarkDirective, SignInComponent, SignedOutComponent, SortSelectorComponent, SourceComponent, SourceIconPipe, SponsoredResultsComponent, SyslangPipe, THEMES, TagCloudComponent, TextChunkService, ThemeProviderDirective, ThemeSelectorComponent, ThemeStore, ThemeToggleComponent, TranslocoDateImpurePipe, UserOverrideService, UserProfileFormComponent, UserProfileService, UserSettingsPersistence, UserSettingsStore, WEIGHT_STEPS, WordCloudComponent, ZoomControlsComponent, __resetSignInMutexForTests, activateShortcutTarget, applyThemeToNativeElement, atomicClientProvider, auditInterceptorFn, authInterceptorFn, bodyInterceptorFn, bootstrapApp, buildHeatmap, buildQuery, buildTagCloud, candidatesFor, canonicalize, debouncedSignal, errorInterceptorFn, fieldErrorKey, fieldShowsError, filterKey, filterLeaves, filterValues, findAggregation, flagsFromWeekdays, focusWhenReady, galactikPrimitive, galactikSemantic, getCurrentPath, getCurrentQueryName, getQueryNameFromRoute, injectAdvancedFilters, injectAtomicClient, injectRouteNavigation, injectUserSettingsPatch, isAuthRoute, isSignInInFlight, itemLabel, layoutWordCloud, legacyFilterToFilter, makeWeightScale, multiSelectionToolbarVariants, paletteColor, processCssVars, provideAtomicClient, provideAtomicNotifications, provideAtomicScope, provideDocumentLang, provideKeyboardShortcuts, provideSessionExpiry, quantileScale, queryNameResolver, rebuildWithout, seriesPalette, signIn, themeColorNameToCssVariable, themeColorsToCssVariables, timelinePalette, toAriaKeyshortcuts, toDisplayParts, toPercentages, toSeries, toastInterceptorFn, weekdaysFromFlags, withAggregationsFeatures, withAlertsFeatures, withAlpha, withAppFeatures, withApplicationFeatures, withAssistantFeatures, withBasketsFeatures, withBookmarkFeatures, withBootstrapApp, withExtractsFeatures, withFetch, withMultiSelectionFeatures, withQueryParamsFeatures, withRecentSearchesFeatures, withSavedSearchesFeatures, withSelectionFeatures, withThemeBodyHook, withThemes, withThemesFeatures, withUserSettingsFeatures };
|
|
33374
|
+
export { AGGREGATIONS_NAMES, AGGREGATIONS_NAMES_PRESET_DEFAULT, APP_FEATURES, ATOMIC_CLIENT, ATOMIC_SCOPED_PROVIDERS, AddToCollection, AdvancedFiltersBodyComponent, AdvancedFiltersComponent, AdvancedSearch, AdvancedSearchTabs, AggregationComponent, AggregationDateComponent, AggregationDateRange, AggregationItemDirective, AggregationListComponent, AggregationPanelComponent, AggregationTreeComponent, AggregationsService, AggregationsStore, Alert, AlertDialog, AlertForm, AlertsComponent, AppService, AppStore, ApplicationService, ApplicationStore, AppliedFiltersComponent, ArticleEntities, ArticleEntitiesTabPanel, ArticleExtracts, ArticleExtractsTabPanel, ArticleHighlights, ArticleLabels, ArticleLabelsTabPanel, ArticleMatchLocations, ArticleMatchLocationsTabPanel, ArticleSimilarDocuments, ArticleSimilarDocumentsTabPanel, AsideFiltersComponent, AuditFeedbackType, AuditService, AuthGuard, AuthPageComponent, AutocompleteService, BOOKMARKS_CONFIG, BOOKMARKS_OPTIONS, BackdropComponent, BackdropService, BookmarkButtonComponent, BookmarksComponent, COLLECTIONS_CONFIG, COLLECTIONS_OPTIONS, COMPONENTS_FOR_DOCUMENT_TYPE, ChangePasswordComponent, ChildMarkerDirective, CollectionsComponent, CollectionsDialog, ConverterSelectComponent, DeleteCollection, DeleteCollectionDialog, DidYouMeanComponent, DocumentLocatorComponent, EditLabels, ErrorComponent, Export, ExportDialog, ExportService, FILTERS_BREAKPOINT, FILTER_DATE_ALLOW_CUSTOM_RANGE, FORM_ALERT_CLASS, FORM_BARE_CLASS, FORM_ERROR_CLASS, FORM_FIELD_CLASS, FORM_FOOTER_CLASS, FORM_LABEL_CLASS, FORM_SURFACE_CLASS, FaIconComponent, FeatureFlags, FeatureFlagsDialogComponent, Feedback, FeedbackDialogComponent, FileSizePipe, FilterButtonComponent, FiltersBarComponent, FloatingToolbarComponent, ForgotPasswordComponent, HIGHLIGHTS, HeatmapComponent, HighlightWordPipe, InfinityScrollDirective, InlineWorker, JsonMethodPluginService, KeyboardShortcutsDialog, KeyboardShortcutsDialogComponent, KeyboardShortcutsListComponent, KeyboardShortcutsService, LabelService, LabelsEditDialog, ListPanelItemDirective, LoadingComponent, MarkdownPipe, MarkdownRendererService, MetadataComponent, MissingTermsComponent, MoreButtonComponent, MoreComponent, MultiSelectLabelsComponent, MultiSelectionToolbarComponent, NON_SEARCHABLE_COLUMNS, NON_SEARCHABLE_DEFAULTS, NavbarTabsComponent, NavigationService, NoResultComponent, OpenArticleOnCtrlEnterDirective, OperatorPipe, OverflowItemDirective, OverflowManagerDirective, OverflowStopDirective, OverrideUser, OverrideUserDialogComponent, PREVIEW_ASSISTANT_COMPONENT, PREVIEW_CONFIG, PagerComponent, PreviewActionsComponent, PreviewContentComponent, PreviewHeaderComponent, PreviewNavigator, PreviewService, PrincipalService, PrincipalStore, QueryParamsStore, QueryService, RECENT_SEARCHES_CONFIG, RECENT_SEARCHES_OPTIONS, ROUTE_COMPONENTS, RecentSearchesComponent, ResetUserSettings, ResetUserSettingsDialogComponent, SAVED_SEARCHES_CONFIG, SAVED_SEARCHES_OPTIONS, STARTUP_DATA_SOURCE, SavedSearch, SavedSearchDialog, SavedSearchPopover, SavedSearchesComponent, SavedSearchesService, SearchFeedbackComponent, SearchInputFooter, SearchService, SelectArticleDirective, SelectionService, SelectionStore, Settings, SettingsAccountPanelComponent, SettingsAppearancePanelComponent, SettingsDialogComponent, SettingsShortcutsPanelComponent, ShortcutDirective, ShowBookmarkDirective, SignInComponent, SignedOutComponent, SortSelectorComponent, SourceComponent, SourceIconPipe, SponsoredResultsComponent, SyslangPipe, THEMES, TagCloudComponent, TextChunkService, ThemeProviderDirective, ThemeSelectorComponent, ThemeStore, ThemeToggleComponent, TranslocoDateImpurePipe, UserOverrideService, UserProfileFormComponent, UserProfileService, UserSettingsPersistence, UserSettingsStore, WEIGHT_STEPS, WordCloudComponent, ZoomControlsComponent, __resetSignInMutexForTests, activateShortcutTarget, applyThemeToNativeElement, atomicClientProvider, auditInterceptorFn, authInterceptorFn, bodyInterceptorFn, bootstrapApp, buildHeatmap, buildQuery, buildTagCloud, candidatesFor, canonicalize, debouncedSignal, errorInterceptorFn, fieldErrorKey, fieldShowsError, filterKey, filterLeaves, filterValues, findAggregation, flagsFromWeekdays, focusWhenReady, galactikPrimitive, galactikSemantic, getCurrentPath, getCurrentQueryName, getQueryNameFromRoute, injectAdvancedFilters, injectAtomicClient, injectRouteNavigation, injectUserSettingsPatch, isAuthRoute, isSignInInFlight, itemLabel, layoutWordCloud, legacyFilterToFilter, makeWeightScale, multiSelectionToolbarVariants, paletteColor, processCssVars, provideAtomicClient, provideAtomicNotifications, provideAtomicScope, provideDocumentLang, provideKeyboardShortcuts, provideSessionExpiry, provideStartupAggregation, quantileScale, queryNameResolver, rebuildWithout, seriesPalette, signIn, themeColorNameToCssVariable, themeColorsToCssVariables, timelinePalette, toAriaKeyshortcuts, toDisplayParts, toPercentages, toSeries, toastInterceptorFn, weekdaysFromFlags, withAggregationsFeatures, withAlertsFeatures, withAlpha, withAppFeatures, withApplicationFeatures, withAssistantFeatures, withBasketsFeatures, withBookmarkFeatures, withBootstrapApp, withExtractsFeatures, withFetch, withMultiSelectionFeatures, withQueryParamsFeatures, withRecentSearchesFeatures, withSavedSearchesFeatures, withSelectionFeatures, withThemeBodyHook, withThemes, withThemesFeatures, withUserSettingsFeatures };
|
|
32834
33375
|
|
|
32835
33376
|
//# sourceMappingURL=sinequa-atomic-angular.mjs.map
|