@sinequa/atomic-angular 1.0.9 → 1.0.11
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/fesm2022/sinequa-atomic-angular.mjs +154 -62
- package/fesm2022/sinequa-atomic-angular.mjs.map +1 -1
- package/index.d.ts +212 -179
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject, HostBinding, Component, Pipe, InjectionToken, computed, ChangeDetectorRef, DestroyRef, LOCALE_ID, Inject, Optional, input, output, signal, effect, assertInInjectionContext, runInInjectionContext, Injector, EventEmitter, Directive, viewChild, ElementRef, afterNextRender, untracked, linkedSignal, model, TemplateRef, HostListener, Renderer2, contentChildren, contentChild, booleanAttribute, ChangeDetectionStrategy, resource, ViewContainerRef, viewChildren, numberAttribute, afterEveryRender } from '@angular/core';
|
|
2
|
+
import { Injectable, inject, HostBinding, Component, Pipe, InjectionToken, computed, ChangeDetectorRef, DestroyRef, LOCALE_ID, Inject, Optional, input, output, signal, effect, assertInInjectionContext, runInInjectionContext, Injector, EventEmitter, Directive, viewChild, ElementRef, afterNextRender, untracked, linkedSignal, model, TemplateRef, HostListener, Renderer2, contentChildren, contentChild, booleanAttribute, ChangeDetectionStrategy, resource, ViewContainerRef, viewChildren, numberAttribute, afterRenderEffect, afterEveryRender } from '@angular/core';
|
|
3
3
|
import { BehaviorSubject, Subscription, catchError, EMPTY, firstValueFrom, map, Subject, of, tap, throwError, filter, shareReplay, fromEvent, debounceTime, from, switchMap } from 'rxjs';
|
|
4
4
|
import { TranslocoService, TranslocoPipe, provideTranslocoScope } from '@jsverse/transloco';
|
|
5
5
|
import { DropdownComponent, DropdownContentComponent, InputComponent, ButtonComponent, cn, FaIconComponent, EllipsisIcon, ChevronRightIcon, MenuComponent, MenuContentComponent, MenuItemComponent, BadgeComponent, DialogComponent, DialogHeaderComponent, DialogTitleComponent, DialogContentComponent, DialogFooterComponent, ListItemComponent, SwitchComponent, SelectOptionDirective, DialogService, TabsComponent, TabsListComponent, TabComponent, ChevronLeftIconComponent, ChevronsLeftIconComponent, ChevronsRightIconComponent, Separator, SheetCloseDirective, SheetService, DateRangePickerDirective, DatepickerDirective, ButtonGroup, InputGroupInput, InputGroupComponent, InputGroupAddonComponent, SearchIcon, FilterIcon, LoadingCircleIconComponent, CircleCheckIconComponent, PopoverComponent, CardComponent, CardHeaderComponent, CardContentComponent, CardFooterComponent, BookmarkIcon, PopoverContentComponent, UserIcon, TrashIcon, FolderIcon, VerticalDividerComponent, BreakpointObserverService, HorizontalDividerComponent, FlagEnglishIconComponent, FlagFrenchIconComponent, EditIcon, UndoIcon, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent } from '@sinequa/ui';
|
|
@@ -2809,19 +2809,45 @@ function withSavedSearchesFeatures() {
|
|
|
2809
2809
|
})));
|
|
2810
2810
|
}
|
|
2811
2811
|
|
|
2812
|
+
/**
|
|
2813
|
+
* Canonical default shape of the user settings state.
|
|
2814
|
+
*
|
|
2815
|
+
* Shared between `initialize()` (overlaid under the fetched settings) and `reset()`
|
|
2816
|
+
* (used as the replacement state) so the two cannot drift apart. Keep in sync with
|
|
2817
|
+
* the `UserSettingsState` type.
|
|
2818
|
+
*/
|
|
2819
|
+
const USER_SETTINGS_DEFAULTS = {
|
|
2820
|
+
bookmarks: [],
|
|
2821
|
+
recentSearches: [],
|
|
2822
|
+
savedSearches: [],
|
|
2823
|
+
baskets: [],
|
|
2824
|
+
alerts: [],
|
|
2825
|
+
assistants: {},
|
|
2826
|
+
language: undefined,
|
|
2827
|
+
collapseAssistant: undefined,
|
|
2828
|
+
userTheme: undefined,
|
|
2829
|
+
agents: { isDebugMode: false }
|
|
2830
|
+
};
|
|
2812
2831
|
function withUserSettingsFeatures() {
|
|
2813
2832
|
return signalStoreFeature(withState({ language: undefined, collapseAssistant: undefined }), withMethods(store => ({
|
|
2814
2833
|
/**
|
|
2815
2834
|
* Initializes the user settings store by fetching the user settings from the backend API
|
|
2816
2835
|
* and patching the store with the retrieved settings.
|
|
2817
2836
|
*
|
|
2837
|
+
* The fetched settings are overlaid on top of {@link USER_SETTINGS_DEFAULTS} so that any
|
|
2838
|
+
* key absent from the new user's settings resets to its default instead of retaining the
|
|
2839
|
+
* previous user's in-memory value. This is required because `initialize()` runs both on
|
|
2840
|
+
* first login and on every user override (impersonation): a plain merge would leak the
|
|
2841
|
+
* previous user's data (e.g. `recentSearches`) into the new user's session and backend.
|
|
2842
|
+
*
|
|
2818
2843
|
* @returns {Promise<void>} A promise that resolves when the initialization is complete.
|
|
2819
2844
|
*/
|
|
2820
2845
|
async initialize() {
|
|
2821
|
-
// Fetch the user settings from the backend API and
|
|
2846
|
+
// Fetch the user settings from the backend API and overlay them on the defaults,
|
|
2847
|
+
// so missing keys reset rather than keep the previous user's values.
|
|
2822
2848
|
try {
|
|
2823
2849
|
const settings = await fetchUserSettings();
|
|
2824
|
-
patchState(store, settings);
|
|
2850
|
+
patchState(store, { ...USER_SETTINGS_DEFAULTS, ...settings });
|
|
2825
2851
|
}
|
|
2826
2852
|
catch (err) {
|
|
2827
2853
|
error('Error fetching user settings:', err);
|
|
@@ -2839,17 +2865,7 @@ function withUserSettingsFeatures() {
|
|
|
2839
2865
|
async reset() {
|
|
2840
2866
|
// Reset the user settings to the initial state
|
|
2841
2867
|
await deleteUserSettings();
|
|
2842
|
-
patchState(store,
|
|
2843
|
-
bookmarks: [],
|
|
2844
|
-
recentSearches: [],
|
|
2845
|
-
savedSearches: [],
|
|
2846
|
-
baskets: [],
|
|
2847
|
-
alerts: [],
|
|
2848
|
-
assistants: {},
|
|
2849
|
-
language: undefined,
|
|
2850
|
-
collapseAssistant: undefined,
|
|
2851
|
-
agents: { isDebugMode: false }
|
|
2852
|
-
});
|
|
2868
|
+
patchState(store, USER_SETTINGS_DEFAULTS);
|
|
2853
2869
|
}
|
|
2854
2870
|
})));
|
|
2855
2871
|
}
|
|
@@ -6909,8 +6925,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
6909
6925
|
}]
|
|
6910
6926
|
}] });
|
|
6911
6927
|
/**
|
|
6912
|
-
* Directive to be used on the
|
|
6913
|
-
*
|
|
6928
|
+
* Directive to be used on the "more" trigger element. The overflow manager
|
|
6929
|
+
* reserves this element's size when not all items fit, so the last visible
|
|
6930
|
+
* item never overlaps it. Its position is not used for measurement.
|
|
6914
6931
|
*/
|
|
6915
6932
|
class OverflowStopDirective {
|
|
6916
6933
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OverflowStopDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -6924,10 +6941,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
6924
6941
|
}]
|
|
6925
6942
|
}] });
|
|
6926
6943
|
/**
|
|
6927
|
-
* Directive that
|
|
6928
|
-
*
|
|
6929
|
-
*
|
|
6930
|
-
*
|
|
6944
|
+
* Directive that counts how many items fit inside the container and hides the
|
|
6945
|
+
* overflowing ones. The boundary is the container's own content edge, which
|
|
6946
|
+
* keeps the measurement correct even when the host lives inside a flex layout
|
|
6947
|
+
* (we never depend on a sibling's position). The stop element is used only to
|
|
6948
|
+
* reserve space for the "more" trigger when not all items fit.
|
|
6949
|
+
*
|
|
6950
|
+
* The directive applies `display: none` on the items that do not fit.
|
|
6931
6951
|
*
|
|
6932
6952
|
* You can specify a target element to observe for resize events, otherwise the
|
|
6933
6953
|
* directive will observe the element itself.
|
|
@@ -6966,10 +6986,26 @@ class OverflowManagerDirective {
|
|
|
6966
6986
|
target = input(...(ngDevMode ? [undefined, { debugName: "target" }] : []));
|
|
6967
6987
|
margin = input(4, ...(ngDevMode ? [{ debugName: "margin" }] : []));
|
|
6968
6988
|
direction = input("horizontal", ...(ngDevMode ? [{ debugName: "direction" }] : []));
|
|
6989
|
+
/**
|
|
6990
|
+
* Always reserve the stop element's size, even when every item fits inside
|
|
6991
|
+
* the container. Use it when the stop trigger is permanently visible (e.g.
|
|
6992
|
+
* the "more" button also gives access to items that are never rendered in
|
|
6993
|
+
* the container), so the last item never overlaps it.
|
|
6994
|
+
*/
|
|
6995
|
+
reserveStop = input(false, ...(ngDevMode ? [{ debugName: "reserveStop", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
6969
6996
|
count = output();
|
|
6970
6997
|
el = inject(ElementRef).nativeElement;
|
|
6971
6998
|
destroyRef = inject(DestroyRef);
|
|
6972
6999
|
resizeObserver = new ResizeObserver(() => this.countItems());
|
|
7000
|
+
// Recompute when an individual item's size changes (label update, async
|
|
7001
|
+
// translation, font load…), not only when the container resizes. Items we
|
|
7002
|
+
// hid with `display: none` report a 0×0 size; ignore those notifications so
|
|
7003
|
+
// our own show/hide toggling doesn't trigger redundant recounts.
|
|
7004
|
+
itemsResizeObserver = new ResizeObserver((entries) => {
|
|
7005
|
+
const visibleItemResized = entries.some((entry) => entry.target.style.display !== "none");
|
|
7006
|
+
if (visibleItemResized)
|
|
7007
|
+
this.countItems();
|
|
7008
|
+
});
|
|
6973
7009
|
countSub;
|
|
6974
7010
|
_lastCount;
|
|
6975
7011
|
constructor() {
|
|
@@ -6981,21 +7017,37 @@ class OverflowManagerDirective {
|
|
|
6981
7017
|
this.countItems();
|
|
6982
7018
|
}
|
|
6983
7019
|
});
|
|
7020
|
+
// (re)observe every item whenever the projected list changes, so that
|
|
7021
|
+
// added/removed items and per-item size changes both trigger a recount
|
|
7022
|
+
effect(() => {
|
|
7023
|
+
const items = this.items();
|
|
7024
|
+
this.itemsResizeObserver.disconnect();
|
|
7025
|
+
items.forEach((item) => this.itemsResizeObserver.observe(item.nativeElement));
|
|
7026
|
+
});
|
|
6984
7027
|
// listens to the count output and toggles the visibility of the items
|
|
6985
7028
|
this.countSub = this.count.subscribe((count) => this.toggleToCount(count));
|
|
6986
7029
|
this.destroyRef.onDestroy(() => {
|
|
6987
7030
|
this.resizeObserver.disconnect();
|
|
7031
|
+
this.itemsResizeObserver.disconnect();
|
|
6988
7032
|
this.countSub?.unsubscribe();
|
|
6989
7033
|
this.countSub = undefined;
|
|
6990
7034
|
});
|
|
6991
7035
|
}
|
|
6992
7036
|
/**
|
|
6993
|
-
* Counts the number of items that can fit
|
|
7037
|
+
* Counts the number of items that can fit inside the container.
|
|
7038
|
+
*
|
|
7039
|
+
* The boundary is the container's own content edge (not the position of the
|
|
7040
|
+
* stop element). This is what makes the measurement robust when the host is
|
|
7041
|
+
* placed inside a flex layout: we never rely on a sibling staying where we
|
|
7042
|
+
* expect it. The stop element is only used for its *size*, to reserve space
|
|
7043
|
+
* for the "more" trigger when not all items fit.
|
|
7044
|
+
*
|
|
6994
7045
|
* Emits the count if it has changed.
|
|
6995
7046
|
*/
|
|
6996
7047
|
countItems() {
|
|
6997
7048
|
if (!this.items() || this.items().length === 0 || !this.stop())
|
|
6998
7049
|
return;
|
|
7050
|
+
const horizontal = this.direction() === "horizontal";
|
|
6999
7051
|
// Reset all items to their natural size before measuring so that previously
|
|
7000
7052
|
// hidden items (display: none) don't corrupt the layout and position of
|
|
7001
7053
|
// their siblings.
|
|
@@ -7003,19 +7055,33 @@ class OverflowManagerDirective {
|
|
|
7003
7055
|
item.nativeElement.style.display = "";
|
|
7004
7056
|
});
|
|
7005
7057
|
// getBoundingClientRect() forces a synchronous reflow, so positions are
|
|
7006
|
-
// accurate after the reset above.
|
|
7058
|
+
// accurate after the reset above. Using rects (not offsetWidth) means the
|
|
7059
|
+
// inter-item gap is accounted for automatically.
|
|
7060
|
+
const containerRect = this.el.getBoundingClientRect();
|
|
7007
7061
|
const stopRect = this.stop().nativeElement.getBoundingClientRect();
|
|
7008
7062
|
const itemsRects = this.items().map((item) => item.nativeElement.getBoundingClientRect());
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7063
|
+
// The container's content edge, with a small slack margin.
|
|
7064
|
+
const containerEnd = (horizontal ? containerRect.right : containerRect.bottom) - this.margin();
|
|
7065
|
+
const itemEnd = (rect) => (horizontal ? rect.right : rect.bottom);
|
|
7066
|
+
let count;
|
|
7067
|
+
// If every item fits within the container, no "more" trigger is needed and
|
|
7068
|
+
// we don't reserve any space for it — unless the trigger is permanently
|
|
7069
|
+
// visible (reserveStop), in which case its space is always reserved.
|
|
7070
|
+
if (!this.reserveStop() && itemEnd(itemsRects[itemsRects.length - 1]) <= containerEnd) {
|
|
7071
|
+
count = itemsRects.length;
|
|
7072
|
+
}
|
|
7073
|
+
else {
|
|
7074
|
+
// Otherwise reserve the stop element's own size so the last visible item
|
|
7075
|
+
// never overlaps the "more" trigger.
|
|
7076
|
+
const reserve = horizontal ? stopRect.width : stopRect.height;
|
|
7077
|
+
const limit = containerEnd - reserve;
|
|
7078
|
+
count = 0;
|
|
7079
|
+
for (const rect of itemsRects) {
|
|
7080
|
+
if (itemEnd(rect) <= limit)
|
|
7081
|
+
count++;
|
|
7082
|
+
else
|
|
7083
|
+
break;
|
|
7084
|
+
}
|
|
7019
7085
|
}
|
|
7020
7086
|
if (this._lastCount !== count) {
|
|
7021
7087
|
this._lastCount = count;
|
|
@@ -7038,7 +7104,7 @@ class OverflowManagerDirective {
|
|
|
7038
7104
|
});
|
|
7039
7105
|
}
|
|
7040
7106
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OverflowManagerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
7041
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.18", type: OverflowManagerDirective, isStandalone: true, selector: "[overflowManager]", inputs: { target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, margin: { classPropertyName: "margin", publicName: "margin", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { count: "count" }, queries: [{ propertyName: "items", predicate: OverflowItemDirective, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "stop", first: true, predicate: OverflowStopDirective, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0 });
|
|
7107
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.3.18", type: OverflowManagerDirective, isStandalone: true, selector: "[overflowManager]", inputs: { target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, margin: { classPropertyName: "margin", publicName: "margin", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, reserveStop: { classPropertyName: "reserveStop", publicName: "reserveStop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { count: "count" }, queries: [{ propertyName: "items", predicate: OverflowItemDirective, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "stop", first: true, predicate: OverflowStopDirective, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0 });
|
|
7042
7108
|
}
|
|
7043
7109
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OverflowManagerDirective, decorators: [{
|
|
7044
7110
|
type: Directive,
|
|
@@ -7046,7 +7112,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
7046
7112
|
selector: "[overflowManager]",
|
|
7047
7113
|
standalone: true
|
|
7048
7114
|
}]
|
|
7049
|
-
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => OverflowItemDirective), { ...{ descendants: true, read: ElementRef }, isSignal: true }] }], stop: [{ type: i0.ContentChild, args: [i0.forwardRef(() => OverflowStopDirective), { ...{ descendants: true, read: ElementRef }, isSignal: true }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], margin: [{ type: i0.Input, args: [{ isSignal: true, alias: "margin", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], count: [{ type: i0.Output, args: ["count"] }] } });
|
|
7115
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => OverflowItemDirective), { ...{ descendants: true, read: ElementRef }, isSignal: true }] }], stop: [{ type: i0.ContentChild, args: [i0.forwardRef(() => OverflowStopDirective), { ...{ descendants: true, read: ElementRef }, isSignal: true }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], margin: [{ type: i0.Input, args: [{ isSignal: true, alias: "margin", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], reserveStop: [{ type: i0.Input, args: [{ isSignal: true, alias: "reserveStop", required: false }] }], count: [{ type: i0.Output, args: ["count"] }] } });
|
|
7050
7116
|
|
|
7051
7117
|
/**
|
|
7052
7118
|
* Directive that selects an article on click.
|
|
@@ -7283,7 +7349,7 @@ class NavbarTabsComponent {
|
|
|
7283
7349
|
</Menu>
|
|
7284
7350
|
</div>
|
|
7285
7351
|
}
|
|
7286
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "noTruncate", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: EllipsisIcon, selector: "ellipsis-icon, EllipsisIcon, ellipsisicon", inputs: ["class", "orientation"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
|
|
7352
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MenuComponent, selector: "menu, Menu", inputs: ["disabled"] }, { kind: "directive", type: MenuItemComponent, selector: "menu-item, menuitem, MenuItem", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: MenuContentComponent, selector: "MenuContent, menucontent, menu-content", inputs: ["class", "position"] }, { kind: "directive", type: TabsComponent, selector: "tabs, Tabs", inputs: ["class"] }, { kind: "directive", type: TabsListComponent, selector: "tabs-list, TabsList", inputs: ["class", "variant", "size"] }, { kind: "directive", type: TabComponent, selector: "tab, Tab", inputs: ["class", "variant", "size", "noTruncate", "value", "active"], outputs: ["clicked"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction", "reserveStop"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "component", type: EllipsisIcon, selector: "ellipsis-icon, EllipsisIcon, ellipsisicon", inputs: ["class", "orientation"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon, FaIcon", inputs: ["faClass"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: SyslangPipe, name: "syslang" }] });
|
|
7287
7353
|
}
|
|
7288
7354
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: NavbarTabsComponent, decorators: [{
|
|
7289
7355
|
type: Component,
|
|
@@ -14594,50 +14660,76 @@ class FiltersBarComponent {
|
|
|
14594
14660
|
return this.aggregationsStore.aggregations().length > 0;
|
|
14595
14661
|
return false;
|
|
14596
14662
|
}, ...(ngDevMode ? [{ debugName: "hasAggregations" }] : []));
|
|
14663
|
+
/**
|
|
14664
|
+
* The full list of authorized filters, NOT capped by `filtersCount`.
|
|
14665
|
+
*
|
|
14666
|
+
* This computed signal performs the following operations:
|
|
14667
|
+
* 1. Retrieves aggregations from either the component's aggregations input or the app store
|
|
14668
|
+
* 2. Filters aggregations based on the route's filter criteria configuration
|
|
14669
|
+
* 3. Excludes filters specified in the `excludeFilters` list
|
|
14670
|
+
* 4. If `includeFilters` is not empty, only includes filters present in that list
|
|
14671
|
+
* 5. Maps the filtered aggregations to objects containing only `name` and `column` properties
|
|
14672
|
+
*/
|
|
14673
|
+
allAuthorizedFilters = computed(() => {
|
|
14674
|
+
return this.aggregationsService
|
|
14675
|
+
.getAuthorizedFilters(this.aggregations(), this.includeFilters(), this.excludeFilters(), this.homepage())
|
|
14676
|
+
.map((f) => ({ name: f.name, column: f.column }));
|
|
14677
|
+
}, ...(ngDevMode ? [{ debugName: "allAuthorizedFilters" }] : []));
|
|
14597
14678
|
/**
|
|
14598
14679
|
* Computes the list of additional filters that can be displayed in the "more filters" popover.
|
|
14599
14680
|
*
|
|
14600
|
-
*
|
|
14601
|
-
*
|
|
14602
|
-
*
|
|
14681
|
+
* Derived from the FULL authorized list (not the one capped by `filtersCount`), so the
|
|
14682
|
+
* filters beyond `filtersCount` — which are never rendered in the bar — are still counted.
|
|
14683
|
+
* Otherwise, when every rendered filter fits in the container, this list would be empty and
|
|
14684
|
+
* the "more" button would be hidden even though more filters exist beyond the cap.
|
|
14603
14685
|
*
|
|
14604
|
-
* This property manages the visibility
|
|
14686
|
+
* This property manages the visibility of the "more filters" button in the UI.
|
|
14605
14687
|
*
|
|
14606
14688
|
* @returns An array of Aggregation objects representing the additional filters available.
|
|
14607
14689
|
*/
|
|
14608
14690
|
hasMoreFilters = computed(() => {
|
|
14609
|
-
const moreFiltersAggregations = this.
|
|
14610
|
-
.filter((f) => !this.excludeFilters().includes(f.name)) // filter out the excluded filters
|
|
14611
|
-
.filter((f) => !this.includeFilters().length || this.includeFilters().includes(f.name)) // exclude filters not included in includeFilters if not empty
|
|
14612
|
-
.map((f) => ({ column: f.column, name: f.name }))
|
|
14691
|
+
const moreFiltersAggregations = this.allAuthorizedFilters()
|
|
14613
14692
|
.toSpliced(0, this.visibleFiltersCount())
|
|
14614
14693
|
.map((f) => this.aggregationsStore.getAggregation(f.column, "column"));
|
|
14615
14694
|
return moreFiltersAggregations;
|
|
14616
14695
|
}, ...(ngDevMode ? [{ debugName: "hasMoreFilters" }] : []));
|
|
14617
14696
|
/**
|
|
14618
|
-
*
|
|
14619
|
-
*
|
|
14620
|
-
* This computed signal performs the following operations:
|
|
14621
|
-
* 1. Retrieves aggregations from either the component's aggregations input or the app store
|
|
14622
|
-
* 2. Filters aggregations based on the route's filter criteria configuration
|
|
14623
|
-
* 3. Excludes filters specified in the `excludeFilters` list
|
|
14624
|
-
* 4. If `includeFilters` is not empty, only includes filters present in that list
|
|
14625
|
-
* 5. Maps the filtered aggregations to objects containing only `name` and `column` properties
|
|
14626
|
-
* 6. Limits the result to the number specified by `filtersCount`
|
|
14697
|
+
* The authorized filters rendered as buttons in the bar, limited to the number
|
|
14698
|
+
* specified by `filtersCount`.
|
|
14627
14699
|
*
|
|
14628
14700
|
* @returns An array of authorized filter objects, each containing `name` and `column` properties
|
|
14629
14701
|
*/
|
|
14630
14702
|
authorizedFilters = computed(() => {
|
|
14631
|
-
|
|
14632
|
-
.getAuthorizedFilters(this.aggregations(), this.includeFilters(), this.excludeFilters(), this.homepage())
|
|
14633
|
-
.map((f) => ({ name: f.name, column: f.column }))
|
|
14634
|
-
.toSpliced(this.filtersCount());
|
|
14635
|
-
return authorizedFilters;
|
|
14703
|
+
return this.allAuthorizedFilters().toSpliced(this.filtersCount());
|
|
14636
14704
|
}, ...(ngDevMode ? [{ debugName: "authorizedFilters" }] : []));
|
|
14705
|
+
/**
|
|
14706
|
+
* Whether some authorized filters exist beyond the `filtersCount` cap.
|
|
14707
|
+
*
|
|
14708
|
+
* Those filters are never rendered in the bar and are only reachable through
|
|
14709
|
+
* the "more" button, which is therefore permanently visible: the overflow
|
|
14710
|
+
* manager must always reserve its space so the last filter button never
|
|
14711
|
+
* overlaps it (`reserveStop`).
|
|
14712
|
+
*/
|
|
14713
|
+
hasCappedFilters = computed(() => this.allAuthorizedFilters().length > this.filtersCount(), ...(ngDevMode ? [{ debugName: "hasCappedFilters" }] : []));
|
|
14637
14714
|
constructor() {
|
|
14638
14715
|
this.transloco.events$
|
|
14639
14716
|
.pipe(takeUntilDestroyed(this.destroyRef), debounceTime(100))
|
|
14640
14717
|
.subscribe(() => this.overflowManagerRef()?.countItems());
|
|
14718
|
+
// Recount the overflow whenever the applied filters or basket change (e.g.
|
|
14719
|
+
// a filter modified or removed from the "more filters" popover). A
|
|
14720
|
+
// FilterButton hidden by the overflow manager (display: none) emits no
|
|
14721
|
+
// resize notification when its natural width changes, so it could fit in
|
|
14722
|
+
// the bar again without the manager knowing. afterRenderEffect guarantees
|
|
14723
|
+
// the DOM already reflects the new state when we measure.
|
|
14724
|
+
afterRenderEffect({
|
|
14725
|
+
read: () => {
|
|
14726
|
+
// track filters and basket changes (getState is reactive here)
|
|
14727
|
+
const { filters, basket } = getState(this.queryParamsStore);
|
|
14728
|
+
void filters;
|
|
14729
|
+
void basket;
|
|
14730
|
+
this.overflowManagerRef()?.countItems();
|
|
14731
|
+
}
|
|
14732
|
+
});
|
|
14641
14733
|
}
|
|
14642
14734
|
/**
|
|
14643
14735
|
* Clears all filters (included baskets) by invoking the clearFilters method on the queryParamsStore.
|
|
@@ -14686,8 +14778,8 @@ class FiltersBarComponent {
|
|
|
14686
14778
|
});
|
|
14687
14779
|
}
|
|
14688
14780
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FiltersBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14689
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: FiltersBarComponent, isStandalone: true, selector: "filters-bar, FiltersBar, filtersbar", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, morePosition: { classPropertyName: "morePosition", publicName: "morePosition", isSignal: true, isRequired: false, transformFunction: null }, aggregations: { classPropertyName: "aggregations", publicName: "aggregations", isSignal: true, isRequired: false, transformFunction: null }, includeFilters: { classPropertyName: "includeFilters", publicName: "includeFilters", isSignal: true, isRequired: false, transformFunction: null }, excludeFilters: { classPropertyName: "excludeFilters", publicName: "excludeFilters", isSignal: true, isRequired: false, transformFunction: null }, filtersCount: { classPropertyName: "filtersCount", publicName: "filtersCount", isSignal: true, isRequired: false, transformFunction: null }, showMoreFiltersButton: { classPropertyName: "showMoreFiltersButton", publicName: "showMoreFiltersButton", isSignal: true, isRequired: false, transformFunction: null }, homepage: { classPropertyName: "homepage", publicName: "homepage", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClearFilters: "onClearFilters", onClearBasket: "onClearBasket" }, host: { listeners: { "click": "handleClick($event)" }, properties: { "class": "cn('block relative', class())" } }, providers: [provideTranslocoScope("filters")], viewQueries: [{ propertyName: "moreButtonRef", first: true, predicate: MoreButtonComponent, descendants: true, isSignal: true }, { propertyName: "filterButtonRefs", predicate: FilterButtonComponent, descendants: true, isSignal: true }, { propertyName: "overflowManagerRef", first: true, predicate: OverflowManagerDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
14690
|
-
<div overflowManager [direction]="direction()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
14781
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: FiltersBarComponent, isStandalone: true, selector: "filters-bar, FiltersBar, filtersbar", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, morePosition: { classPropertyName: "morePosition", publicName: "morePosition", isSignal: true, isRequired: false, transformFunction: null }, aggregations: { classPropertyName: "aggregations", publicName: "aggregations", isSignal: true, isRequired: false, transformFunction: null }, includeFilters: { classPropertyName: "includeFilters", publicName: "includeFilters", isSignal: true, isRequired: false, transformFunction: null }, excludeFilters: { classPropertyName: "excludeFilters", publicName: "excludeFilters", isSignal: true, isRequired: false, transformFunction: null }, filtersCount: { classPropertyName: "filtersCount", publicName: "filtersCount", isSignal: true, isRequired: false, transformFunction: null }, showMoreFiltersButton: { classPropertyName: "showMoreFiltersButton", publicName: "showMoreFiltersButton", isSignal: true, isRequired: false, transformFunction: null }, homepage: { classPropertyName: "homepage", publicName: "homepage", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, expandedLevel: { classPropertyName: "expandedLevel", publicName: "expandedLevel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClearFilters: "onClearFilters", onClearBasket: "onClearBasket" }, host: { listeners: { "click": "handleClick($event)" }, properties: { "class": "cn('block relative min-w-0', class())" } }, providers: [provideTranslocoScope("filters")], viewQueries: [{ propertyName: "moreButtonRef", first: true, predicate: MoreButtonComponent, descendants: true, isSignal: true }, { propertyName: "filterButtonRefs", predicate: FilterButtonComponent, descendants: true, isSignal: true }, { propertyName: "overflowManagerRef", first: true, predicate: OverflowManagerDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
14782
|
+
<div overflowManager [direction]="direction()" [reserveStop]="hasCappedFilters()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
14691
14783
|
@if (hasFilters()) {
|
|
14692
14784
|
<button
|
|
14693
14785
|
variant="destructive"
|
|
@@ -14739,7 +14831,7 @@ class FiltersBarComponent {
|
|
|
14739
14831
|
}
|
|
14740
14832
|
}
|
|
14741
14833
|
</div>
|
|
14742
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MoreButtonComponent, selector: "more-button, MoreButton", inputs: ["count", "position", "includedFilters", "excludedFilters", "aggregations", "homepage"] }, { kind: "component", type: FilterButtonComponent, selector: "filter-button, FilterButton", inputs: ["name", "column", "position", "offset", "expandedLevel"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
14834
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "scheme", "iconOnly", "size"] }, { kind: "component", type: MoreButtonComponent, selector: "more-button, MoreButton", inputs: ["count", "position", "includedFilters", "excludedFilters", "aggregations", "homepage"] }, { kind: "component", type: FilterButtonComponent, selector: "filter-button, FilterButton", inputs: ["name", "column", "position", "offset", "expandedLevel"] }, { kind: "directive", type: OverflowManagerDirective, selector: "[overflowManager]", inputs: ["target", "margin", "direction", "reserveStop"], outputs: ["count"] }, { kind: "directive", type: OverflowItemDirective, selector: "[overflowItem]" }, { kind: "directive", type: OverflowStopDirective, selector: "[overflowStop]" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
14743
14835
|
}
|
|
14744
14836
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FiltersBarComponent, decorators: [{
|
|
14745
14837
|
type: Component,
|
|
@@ -14757,7 +14849,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
14757
14849
|
],
|
|
14758
14850
|
providers: [provideTranslocoScope("filters")],
|
|
14759
14851
|
template: `
|
|
14760
|
-
<div overflowManager [direction]="direction()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
14852
|
+
<div overflowManager [direction]="direction()" [reserveStop]="hasCappedFilters()" (count)="adjustFiltersCount($event)" class="flex items-end gap-2 rounded-[inherit] bg-inherit">
|
|
14761
14853
|
@if (hasFilters()) {
|
|
14762
14854
|
<button
|
|
14763
14855
|
variant="destructive"
|
|
@@ -14811,7 +14903,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
14811
14903
|
</div>
|
|
14812
14904
|
`,
|
|
14813
14905
|
host: {
|
|
14814
|
-
"[class]": "cn('block relative', class())",
|
|
14906
|
+
"[class]": "cn('block relative min-w-0', class())",
|
|
14815
14907
|
"(click)": "handleClick($event)"
|
|
14816
14908
|
}
|
|
14817
14909
|
}]
|