@sinequa/atomic-angular 2.14.0 → 2.16.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.
@@ -2,7 +2,7 @@ import * as i0 from "@angular/core";
2
2
  import { ApplicationRef, ChangeDetectorRef, DestroyRef, ElementRef, EnvironmentProviders, InjectionToken, Injector, OnDestroy, OnInit, PipeTransform, Provider, ResourceRef, Signal, TemplateRef, Type, WritableSignal } from "@angular/core";
3
3
  import { TranslocoService } from "@jsverse/transloco";
4
4
  import { Aggregation, AggregationItem, Article, AtomicClient, AtomicClientConfig, AuditEventType, AuditEventTypeValues, AuditEvents, CCApp, CCColumn, CCQuery, CCSortingChoice, CCWebService, Conversion, Credentials, CustomHighlights, DidYouMeanAction, ExportOutputFormat, ExportQueryModel, Filter as Filter$1, FilterOperator, KeyOf, LegacyFilter, LinkResult, PreviewData, Principal, Query, QueryParams, RequestOptions, Result, SpellingCorrectionMode, Suggestion, TextChunk, TextLocation, TreeAggregation, TreeAggregationNode, UserProfile } from "@sinequa/atomic";
5
- import { CanActivateFn, NavigationEnd, Params, ResolveFn, Route, Router } from "@angular/router";
5
+ import { CanActivateFn, CanMatchFn, NavigationEnd, Params, ResolveFn, Route, Router } from "@angular/router";
6
6
  import { VariantProps } from "class-variance-authority";
7
7
  import { BreakpointObserverService, DialogComponent, DialogEvent, DialogResult, DropdownDirective, PopoverDirective, SheetComponent, SwitchComponent, TooltipDirective } from "@sinequa/galactik";
8
8
  import { DomSanitizer, SafeHtml, Title } from "@angular/platform-browser";
@@ -246,7 +246,7 @@ export type CJ = {
246
246
  };
247
247
  };
248
248
  /**
249
- * An entry of `features.userProfile.customData`: a property name (`"nickname"`) or an object whose
249
+ * An entry of `features.userProfile.customData` or `features.userProfile.privateCustomData`: a property name (`"nickname"`) or an object whose
250
250
  * keys are property names and whose values are their default (`{ "nickname": "none" }`). A default can
251
251
  * be any JSON value, an object included (`{ "theme": { "mode": "dark" } }`).
252
252
  */
@@ -274,6 +274,7 @@ type CFeatures = {
274
274
  enabled?: boolean;
275
275
  data?: string[];
276
276
  customData?: CustomDataEntry[];
277
+ privateCustomData?: CustomDataEntry[];
277
278
  };
278
279
  previewMultiConversion?: boolean;
279
280
  persistFiltersAcrossTabs?: boolean;
@@ -492,6 +493,7 @@ export declare class ConverterSelectComponent {
492
493
  enabled?: boolean;
493
494
  data?: string[];
494
495
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
496
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
495
497
  };
496
498
  previewMultiConversion?: boolean;
497
499
  persistFiltersAcrossTabs?: boolean;
@@ -534,6 +536,7 @@ export declare class ConverterSelectComponent {
534
536
  enabled?: boolean;
535
537
  data?: string[];
536
538
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
539
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
537
540
  };
538
541
  previewMultiConversion?: boolean;
539
542
  persistFiltersAcrossTabs?: boolean;
@@ -598,6 +601,7 @@ export declare class ConverterSelectComponent {
598
601
  enabled?: boolean;
599
602
  data?: string[];
600
603
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
604
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
601
605
  };
602
606
  previewMultiConversion?: boolean;
603
607
  persistFiltersAcrossTabs?: boolean;
@@ -692,6 +696,7 @@ export declare class ConverterSelectComponent {
692
696
  enabled?: boolean;
693
697
  data?: string[];
694
698
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
699
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
695
700
  };
696
701
  previewMultiConversion?: boolean;
697
702
  persistFiltersAcrossTabs?: boolean;
@@ -734,6 +739,7 @@ export declare class ConverterSelectComponent {
734
739
  enabled?: boolean;
735
740
  data?: string[];
736
741
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
742
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
737
743
  };
738
744
  previewMultiConversion?: boolean;
739
745
  persistFiltersAcrossTabs?: boolean;
@@ -891,7 +897,7 @@ export declare class DocumentLocatorComponent implements OnDestroy {
891
897
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
892
898
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
893
899
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
894
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
900
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
895
901
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
896
902
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
897
903
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -1152,7 +1158,7 @@ export declare class MissingTermsComponent {
1152
1158
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
1153
1159
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
1154
1160
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
1155
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
1161
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
1156
1162
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
1157
1163
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
1158
1164
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -1252,7 +1258,7 @@ export declare class MissingTermsComponent {
1252
1258
  }, {}, never, never, true, never>;
1253
1259
  }
1254
1260
  export declare const multiSelectionToolbarVariants: (props?: ({
1255
- variant?: "dark" | "light" | "glassy" | null | undefined;
1261
+ variant?: "dark" | "light" | "glassy" | "floating" | null | undefined;
1256
1262
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
1257
1263
  export type MultiSelectionToolbarVariants = VariantProps<typeof multiSelectionToolbarVariants>;
1258
1264
  export declare class MultiSelectionToolbarComponent {
@@ -1307,6 +1313,7 @@ export declare class MultiSelectionToolbarComponent {
1307
1313
  enabled?: boolean;
1308
1314
  data?: string[];
1309
1315
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1316
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1310
1317
  };
1311
1318
  previewMultiConversion?: boolean;
1312
1319
  persistFiltersAcrossTabs?: boolean;
@@ -1349,6 +1356,7 @@ export declare class MultiSelectionToolbarComponent {
1349
1356
  enabled?: boolean;
1350
1357
  data?: string[];
1351
1358
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1359
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1352
1360
  };
1353
1361
  previewMultiConversion?: boolean;
1354
1362
  persistFiltersAcrossTabs?: boolean;
@@ -1413,6 +1421,7 @@ export declare class MultiSelectionToolbarComponent {
1413
1421
  enabled?: boolean;
1414
1422
  data?: string[];
1415
1423
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1424
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1416
1425
  };
1417
1426
  previewMultiConversion?: boolean;
1418
1427
  persistFiltersAcrossTabs?: boolean;
@@ -1507,6 +1516,7 @@ export declare class MultiSelectionToolbarComponent {
1507
1516
  enabled?: boolean;
1508
1517
  data?: string[];
1509
1518
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1519
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1510
1520
  };
1511
1521
  previewMultiConversion?: boolean;
1512
1522
  persistFiltersAcrossTabs?: boolean;
@@ -1549,6 +1559,7 @@ export declare class MultiSelectionToolbarComponent {
1549
1559
  enabled?: boolean;
1550
1560
  data?: string[];
1551
1561
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1562
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1552
1563
  };
1553
1564
  previewMultiConversion?: boolean;
1554
1565
  persistFiltersAcrossTabs?: boolean;
@@ -1575,27 +1586,27 @@ export declare class MultiSelectionToolbarComponent {
1575
1586
  columnMap?: Record<string, import("@sinequa/atomic").CCColumn> | undefined;
1576
1587
  }>;
1577
1588
  readonly selection: {
1578
- article?: import("@angular/core").Signal<undefined> | import("@ngrx/signals").DeepSignal<import("@sinequa/atomic").Article> | undefined;
1589
+ article?: import("@angular/core").Signal<undefined> | import("@ngrx/signals").DeepSignal<Article> | undefined;
1579
1590
  id?: import("@angular/core").Signal<string | undefined> | undefined;
1580
1591
  queryText?: import("@angular/core").Signal<string | undefined> | undefined;
1581
1592
  queryName?: import("@angular/core").Signal<string | undefined> | undefined;
1582
1593
  previewHighlights?: import("@angular/core").Signal<undefined> | import("@ngrx/signals").DeepSignal<import("@sinequa/atomic-angular").PreviewHighlights> | undefined;
1583
1594
  assistantIdsToAttach: import("@angular/core").Signal<string[]>;
1584
- multiSelection: import("@angular/core").Signal<import("@sinequa/atomic").Article[]>;
1595
+ multiSelection: import("@angular/core").Signal<Article[]>;
1585
1596
  multiSelectCount: import("@angular/core").Signal<number>;
1586
1597
  update: (newState: Partial<import("@sinequa/atomic-angular").SelectionState>) => void;
1587
1598
  clear: () => void;
1588
- addArticleToMultiSelection: (article: import("@sinequa/atomic").Article) => void;
1589
- removeArticleFromMultiSelection: (article: import("@sinequa/atomic").Article) => void;
1599
+ addArticleToMultiSelection: (article: Article) => void;
1600
+ removeArticleFromMultiSelection: (article: Article) => void;
1590
1601
  clearMultiSelection: () => void;
1591
1602
  } & import("@ngrx/signals").StateSource<{
1592
- article?: import("@sinequa/atomic").Article | undefined;
1603
+ article?: Article | undefined;
1593
1604
  id?: string | undefined;
1594
1605
  queryText?: string | undefined;
1595
1606
  queryName?: string | undefined;
1596
1607
  previewHighlights?: import("@sinequa/atomic-angular").PreviewHighlights | undefined;
1597
1608
  assistantIdsToAttach: string[];
1598
- multiSelection: import("@sinequa/atomic").Article[];
1609
+ multiSelection: Article[];
1599
1610
  }>;
1600
1611
  private readonly injector;
1601
1612
  readonly appFeatures: {
@@ -1635,6 +1646,7 @@ export declare class MultiSelectionToolbarComponent {
1635
1646
  enabled?: boolean;
1636
1647
  data?: string[];
1637
1648
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1649
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1638
1650
  };
1639
1651
  previewMultiConversion?: boolean;
1640
1652
  persistFiltersAcrossTabs?: boolean;
@@ -1643,7 +1655,11 @@ export declare class MultiSelectionToolbarComponent {
1643
1655
  feedback?: import("@sinequa/atomic-angular").CFeedback;
1644
1656
  } | undefined;
1645
1657
  readonly class: import("@angular/core").InputSignal<string>;
1646
- readonly variant: import("@angular/core").InputSignal<"dark" | "light" | "glassy" | null | undefined>;
1658
+ /**
1659
+ * `dark`, `light`, `glassy`: one bar at the bottom centre of the window. `floating`: detached buttons
1660
+ * in the bottom-right corner of the window, as in lexiQ.
1661
+ */
1662
+ readonly variant: import("@angular/core").InputSignal<"dark" | "light" | "glassy" | "floating" | null | undefined>;
1647
1663
  /**
1648
1664
  * Texte ajouté à l'annonce lecteur d'écran lors de la **première** sélection (ex. « F6 pour accéder
1649
1665
  * aux actions »). Il est fourni par l'application : seule elle sait par quel raccourci elle rend la
@@ -1653,6 +1669,12 @@ export declare class MultiSelectionToolbarComponent {
1653
1669
  readonly updatedCollections: import("@angular/core").OutputEmitterRef<void>;
1654
1670
  /** La sélection vient d'être vidée (bouton, Échap) : l'application replace le focus, la barre devient inerte. */
1655
1671
  readonly cleared: import("@angular/core").OutputEmitterRef<void>;
1672
+ /**
1673
+ * `floating` only: the selection has just been filed in a collection (its name). The panel has
1674
+ * closed and the selection has been emptied (`cleared` fired first); an application with a
1675
+ * "selection mode" leaves it here.
1676
+ */
1677
+ readonly addedToCollection: import("@angular/core").OutputEmitterRef<string>;
1656
1678
  readonly count: import("@angular/core").Signal<number>;
1657
1679
  readonly variants: import("@angular/core").Signal<string>;
1658
1680
  readonly ids: import("@angular/core").Signal<string[]>;
@@ -1669,11 +1691,36 @@ export declare class MultiSelectionToolbarComponent {
1669
1691
  /** Vrai uniquement à la première sélection : ensuite, seul le décompte est annoncé. */
1670
1692
  protected readonly showHint: import("@angular/core").WritableSignal<boolean>;
1671
1693
  private armed;
1694
+ protected readonly floatingButton = "shadow-(--shadow-2) pointer-coarse:h-11";
1695
+ protected readonly hostClass: import("@angular/core").Signal<string>;
1696
+ protected readonly toolbarClass: import("@angular/core").Signal<string>;
1697
+ private static nextId;
1698
+ protected readonly panelId: string;
1699
+ protected readonly panelOpen: import("@angular/core").WritableSignal<boolean>;
1700
+ /** The documents the panel files: the selection at the moment it was opened. */
1701
+ protected readonly panelArticles: import("@angular/core").WritableSignal<Article[]>;
1702
+ /** Read by the status region once the selection is emptied after filing. */
1703
+ protected readonly lastFiled: import("@angular/core").WritableSignal<{
1704
+ count: number;
1705
+ name: string;
1706
+ } | null>;
1707
+ protected collectionsChanged: boolean;
1708
+ private readonly collectionTrigger;
1709
+ private readonly panel;
1710
+ private lastFiledTimer;
1672
1711
  constructor();
1673
1712
  clearSelection: () => void;
1674
1713
  openCollectionDialog: () => Promise<void>;
1675
1714
  openExportDialog: () => void;
1676
1715
  attachToAssistant: () => void;
1716
+ protected togglePanel(): void;
1717
+ /** Close button, emptied selection: hides the popover; its `toggle` event does the rest. */
1718
+ protected closePanel(): void;
1719
+ /** The popover closed — by Escape, a click outside, the close button or after filing. */
1720
+ protected onPanelToggle(event: Event): void;
1721
+ /** Filed: the panel's confirmation has been seen; the selection is done with. */
1722
+ protected onFiled(name: string): void;
1723
+ private panelClosed;
1677
1724
  static ɵfac: i0.ɵɵFactoryDeclaration<MultiSelectionToolbarComponent, never>;
1678
1725
  static ɵcmp: i0.ɵɵComponentDeclaration<MultiSelectionToolbarComponent, "MultiSelectionToolbar, multi-selection-toolbar", never, {
1679
1726
  "class": {
@@ -1699,6 +1746,7 @@ export declare class MultiSelectionToolbarComponent {
1699
1746
  }, {
1700
1747
  "updatedCollections": "updatedCollections";
1701
1748
  "cleared": "cleared";
1749
+ "addedToCollection": "addedToCollection";
1702
1750
  }, never, never, true, never>;
1703
1751
  }
1704
1752
  export interface NavRouteTab {
@@ -1771,6 +1819,7 @@ export declare class NavbarTabsComponent {
1771
1819
  enabled?: boolean;
1772
1820
  data?: string[];
1773
1821
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1822
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1774
1823
  };
1775
1824
  previewMultiConversion?: boolean;
1776
1825
  persistFiltersAcrossTabs?: boolean;
@@ -1813,6 +1862,7 @@ export declare class NavbarTabsComponent {
1813
1862
  enabled?: boolean;
1814
1863
  data?: string[];
1815
1864
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1865
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1816
1866
  };
1817
1867
  previewMultiConversion?: boolean;
1818
1868
  persistFiltersAcrossTabs?: boolean;
@@ -1877,6 +1927,7 @@ export declare class NavbarTabsComponent {
1877
1927
  enabled?: boolean;
1878
1928
  data?: string[];
1879
1929
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1930
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1880
1931
  };
1881
1932
  previewMultiConversion?: boolean;
1882
1933
  persistFiltersAcrossTabs?: boolean;
@@ -1971,6 +2022,7 @@ export declare class NavbarTabsComponent {
1971
2022
  enabled?: boolean;
1972
2023
  data?: string[];
1973
2024
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2025
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
1974
2026
  };
1975
2027
  previewMultiConversion?: boolean;
1976
2028
  persistFiltersAcrossTabs?: boolean;
@@ -2013,6 +2065,7 @@ export declare class NavbarTabsComponent {
2013
2065
  enabled?: boolean;
2014
2066
  data?: string[];
2015
2067
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2068
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2016
2069
  };
2017
2070
  previewMultiConversion?: boolean;
2018
2071
  persistFiltersAcrossTabs?: boolean;
@@ -2225,6 +2278,11 @@ export declare class OverflowActionsComponent {
2225
2278
  private readonly appConfig;
2226
2279
  /** The document the actions are about. Without one there is no bookmark and no link to copy. */
2227
2280
  readonly article: import("@angular/core").InputSignal<Article | undefined>;
2281
+ /**
2282
+ * Where the bookmark button files the document: `bookmarks` (default, the historical behaviour) or `collections`,
2283
+ * where a click opens the "add to collection" panel. Same input as `<bookmark-button [target]>`.
2284
+ */
2285
+ readonly bookmarkTarget: import("@angular/core").InputSignal<"bookmarks" | "collections">;
2228
2286
  /** Which built-in buttons to bring, merged over `OVERFLOW_ACTIONS_CONFIG` and the defaults (all on). */
2229
2287
  readonly config: import("@angular/core").InputSignal<Partial<OverflowActionsConfig>>;
2230
2288
  /** `false` where there is no bigger container to grow into (a full-screen sheet): the expand button goes. */
@@ -2273,6 +2331,11 @@ export declare class OverflowActionsComponent {
2273
2331
  "required": false;
2274
2332
  "isSignal": true;
2275
2333
  };
2334
+ "bookmarkTarget": {
2335
+ "alias": "bookmarkTarget";
2336
+ "required": false;
2337
+ "isSignal": true;
2338
+ };
2276
2339
  "config": {
2277
2340
  "alias": "config";
2278
2341
  "required": false;
@@ -2670,6 +2733,7 @@ export declare const AppStore: import("@angular/core").Type<{
2670
2733
  enabled?: boolean;
2671
2734
  data?: string[];
2672
2735
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2736
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2673
2737
  };
2674
2738
  previewMultiConversion?: boolean;
2675
2739
  persistFiltersAcrossTabs?: boolean;
@@ -2712,6 +2776,7 @@ export declare const AppStore: import("@angular/core").Type<{
2712
2776
  enabled?: boolean;
2713
2777
  data?: string[];
2714
2778
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2779
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2715
2780
  };
2716
2781
  previewMultiConversion?: boolean;
2717
2782
  persistFiltersAcrossTabs?: boolean;
@@ -2776,6 +2841,7 @@ export declare const AppStore: import("@angular/core").Type<{
2776
2841
  enabled?: boolean;
2777
2842
  data?: string[];
2778
2843
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2844
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2779
2845
  };
2780
2846
  previewMultiConversion?: boolean;
2781
2847
  persistFiltersAcrossTabs?: boolean;
@@ -2864,6 +2930,7 @@ export declare const AppStore: import("@angular/core").Type<{
2864
2930
  enabled?: boolean;
2865
2931
  data?: string[];
2866
2932
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2933
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2867
2934
  };
2868
2935
  previewMultiConversion?: boolean;
2869
2936
  persistFiltersAcrossTabs?: boolean;
@@ -2906,6 +2973,7 @@ export declare const AppStore: import("@angular/core").Type<{
2906
2973
  enabled?: boolean;
2907
2974
  data?: string[];
2908
2975
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2976
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2909
2977
  };
2910
2978
  previewMultiConversion?: boolean;
2911
2979
  persistFiltersAcrossTabs?: boolean;
@@ -2985,6 +3053,7 @@ export declare function withAppFeatures(): import("@ngrx/signals").SignalStoreFe
2985
3053
  enabled?: boolean;
2986
3054
  data?: string[];
2987
3055
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3056
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
2988
3057
  };
2989
3058
  previewMultiConversion?: boolean;
2990
3059
  persistFiltersAcrossTabs?: boolean;
@@ -3027,6 +3096,7 @@ export declare function withAppFeatures(): import("@ngrx/signals").SignalStoreFe
3027
3096
  enabled?: boolean;
3028
3097
  data?: string[];
3029
3098
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3099
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3030
3100
  };
3031
3101
  previewMultiConversion?: boolean;
3032
3102
  persistFiltersAcrossTabs?: boolean;
@@ -3093,6 +3163,7 @@ export declare function withAppFeatures(): import("@ngrx/signals").SignalStoreFe
3093
3163
  enabled?: boolean;
3094
3164
  data?: string[];
3095
3165
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3166
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3096
3167
  };
3097
3168
  previewMultiConversion?: boolean;
3098
3169
  persistFiltersAcrossTabs?: boolean;
@@ -3319,7 +3390,7 @@ export declare const QueryParamsStore: import("@angular/core").Type<{
3319
3390
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
3320
3391
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
3321
3392
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
3322
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
3393
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
3323
3394
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
3324
3395
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
3325
3396
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -3643,6 +3714,7 @@ export declare const UserSettingsStore: import("@angular/core").Type<{
3643
3714
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
3644
3715
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
3645
3716
  unbookmark: (id: string) => Promise<void>;
3717
+ unbookmarkMany: (ids: string[]) => Promise<void>;
3646
3718
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
3647
3719
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
3648
3720
  isFavoriteSearch: (search: Pick<import("@sinequa/atomic-angular").SearchItem, "label" | "display">) => boolean;
@@ -3741,6 +3813,7 @@ export declare function withBookmarkFeatures(): import("@ngrx/signals").SignalSt
3741
3813
  updateBookmarks: (bookmarks: UserSettingsState["bookmarks"], auditEvents?: AuditEvents) => Promise<void>;
3742
3814
  bookmark: (article: Article, queryName?: string) => Promise<void>;
3743
3815
  unbookmark: (id: string) => Promise<void>;
3816
+ unbookmarkMany: (ids: string[]) => Promise<void>;
3744
3817
  isBookmarked: (article: Partial<Article>) => boolean;
3745
3818
  toggleBookmark: (article: Article) => Promise<void>;
3746
3819
  };
@@ -3859,6 +3932,12 @@ export declare class PreviewContentComponent {
3859
3932
  #private;
3860
3933
  cn: import("cn").CnFunction;
3861
3934
  iframe: import("@angular/core").Signal<ElementRef<HTMLIFrameElement> | undefined>;
3935
+ /**
3936
+ * The box that holds the rendered Markdown (there is no iframe, hence no `ready` message, in that branch). It is
3937
+ * not necessarily the element that scrolls: depending on the host layout it can be an ancestor, so scrolling
3938
+ * and scroll tracking never assume it.
3939
+ */
3940
+ private readonly markdownScroller;
3862
3941
  private readonly findPanelTemplate;
3863
3942
  breakpointService: BreakpointObserverService;
3864
3943
  protected readonly appStore: {
@@ -3911,6 +3990,7 @@ export declare class PreviewContentComponent {
3911
3990
  enabled?: boolean;
3912
3991
  data?: string[];
3913
3992
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3993
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3914
3994
  };
3915
3995
  previewMultiConversion?: boolean;
3916
3996
  persistFiltersAcrossTabs?: boolean;
@@ -3953,6 +4033,7 @@ export declare class PreviewContentComponent {
3953
4033
  enabled?: boolean;
3954
4034
  data?: string[];
3955
4035
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4036
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
3956
4037
  };
3957
4038
  previewMultiConversion?: boolean;
3958
4039
  persistFiltersAcrossTabs?: boolean;
@@ -4017,6 +4098,7 @@ export declare class PreviewContentComponent {
4017
4098
  enabled?: boolean;
4018
4099
  data?: string[];
4019
4100
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4101
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4020
4102
  };
4021
4103
  previewMultiConversion?: boolean;
4022
4104
  persistFiltersAcrossTabs?: boolean;
@@ -4111,6 +4193,7 @@ export declare class PreviewContentComponent {
4111
4193
  enabled?: boolean;
4112
4194
  data?: string[];
4113
4195
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4196
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4114
4197
  };
4115
4198
  previewMultiConversion?: boolean;
4116
4199
  persistFiltersAcrossTabs?: boolean;
@@ -4153,6 +4236,7 @@ export declare class PreviewContentComponent {
4153
4236
  enabled?: boolean;
4154
4237
  data?: string[];
4155
4238
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4239
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4156
4240
  };
4157
4241
  previewMultiConversion?: boolean;
4158
4242
  persistFiltersAcrossTabs?: boolean;
@@ -4246,6 +4330,12 @@ export declare class PreviewContentComponent {
4246
4330
  /** `false` hides `<preview-actions>`'s search-in-document trigger/popover (e.g. a narrower host
4247
4331
  * with no room for it, like `/chat`'s ResizablePanel). Zoom/highlights stay unaffected. */
4248
4332
  showSearchActions: import("@angular/core").InputSignal<boolean>;
4333
+ /**
4334
+ * `false` hides the whole action bar above the document (search, converter, highlights, zoom, page navigation), for a
4335
+ * host that only wants to show the document — a shortlist's preview, a narrow side panel. The document itself, and the
4336
+ * page navigation the iframe content offers, are unaffected.
4337
+ */
4338
+ showActions: import("@angular/core").InputSignal<boolean>;
4249
4339
  /**
4250
4340
  * Where the results of the find field show: `"popover"` (the default) under the field, as it takes the focus;
4251
4341
  * `"pinned"` in a panel beside the document, for a preview that has room for it (the expanded one). The panel is
@@ -4365,6 +4455,15 @@ export declare class PreviewContentComponent {
4365
4455
  * reveal it anyway after a short delay so the spinner overlay cannot stay stuck.
4366
4456
  */
4367
4457
  onLoaded(): void;
4458
+ /** Scrolls so that the page anchor `anchorId` sits at the top edge of whichever ancestor scrolls the Markdown. */
4459
+ private scrollMarkdownTo;
4460
+ private markdownScrollFrame;
4461
+ /**
4462
+ * Keeps `currentPage` in sync with the page the reader is on in the Markdown branch (the iframe branch gets it
4463
+ * from preview.js's `current-page` message), so that switching to another conversion lands on the same page.
4464
+ * Throttled to one measure per frame.
4465
+ */
4466
+ private onMarkdownScroll;
4368
4467
  protected zoomInMarkdown(): void;
4369
4468
  protected zoomOutMarkdown(): void;
4370
4469
  protected zoomFitMarkdown(): void;
@@ -4414,6 +4513,11 @@ export declare class PreviewContentComponent {
4414
4513
  "required": false;
4415
4514
  "isSignal": true;
4416
4515
  };
4516
+ "showActions": {
4517
+ "alias": "showActions";
4518
+ "required": false;
4519
+ "isSignal": true;
4520
+ };
4417
4521
  "findPanel": {
4418
4522
  "alias": "findPanel";
4419
4523
  "required": false;
@@ -4620,13 +4724,6 @@ export declare function getCurrentQueryName(): string | undefined;
4620
4724
  * `gap-4` (CardContent) → `--spacing-md` (16px) · `shadow-sm` → `--shadow-2`, avec un liseré `--layer-page-edge`
4621
4725
  */
4622
4726
  export declare const FORM_SURFACE_CLASS = "flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)";
4623
- /**
4624
- * Same layout, no card: no background, no padding, no shadow.
4625
- *
4626
- * Used when the form is embedded in a container that already provides the surface — a dialog body,
4627
- * a settings panel — where the card would otherwise nest inside another card.
4628
- */
4629
- export declare const FORM_BARE_CLASS = "flex w-full flex-col gap-(--spacing-md)";
4630
4727
  /** Groupe « label + contrôle + message d'erreur » — ex-`<div class="grid gap-2">`. */
4631
4728
  export declare const FORM_FIELD_CLASS = "flex flex-col gap-(--spacing-2xs)";
4632
4729
  /**
@@ -4638,6 +4735,11 @@ export declare const FORM_FIELD_CLASS = "flex flex-col gap-(--spacing-2xs)";
4638
4735
  * reprend son rayon.
4639
4736
  */
4640
4737
  export declare const FORM_FOOTER_CLASS = "flex justify-end gap-(--spacing-2xs) -mx-(--spacing-md) -mb-(--spacing-md) rounded-b-(--radius-md) bg-(--layer-page-on-layer) px-(--spacing-md) py-(--spacing-sm)";
4738
+ /**
4739
+ * Rangée de boutons d'un formulaire affiché hors dialogue (inline, carte). Rien de plus qu'une ligne
4740
+ * alignée à droite : dans un dialogue, ce sont les boutons du `DialogFooter` standard qui s'en chargent.
4741
+ */
4742
+ export declare const FORM_ACTIONS_CLASS = "flex justify-end gap-(--spacing-2xs)";
4641
4743
  /**
4642
4744
  * Libellé d'un champ — ex-`text-sm font-medium`.
4643
4745
  *
@@ -4835,6 +4937,7 @@ export declare class AuditService {
4835
4937
  enabled?: boolean;
4836
4938
  data?: string[];
4837
4939
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4940
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4838
4941
  };
4839
4942
  previewMultiConversion?: boolean;
4840
4943
  persistFiltersAcrossTabs?: boolean;
@@ -4877,6 +4980,7 @@ export declare class AuditService {
4877
4980
  enabled?: boolean;
4878
4981
  data?: string[];
4879
4982
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4983
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4880
4984
  };
4881
4985
  previewMultiConversion?: boolean;
4882
4986
  persistFiltersAcrossTabs?: boolean;
@@ -4941,6 +5045,7 @@ export declare class AuditService {
4941
5045
  enabled?: boolean;
4942
5046
  data?: string[];
4943
5047
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5048
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
4944
5049
  };
4945
5050
  previewMultiConversion?: boolean;
4946
5051
  persistFiltersAcrossTabs?: boolean;
@@ -5035,6 +5140,7 @@ export declare class AuditService {
5035
5140
  enabled?: boolean;
5036
5141
  data?: string[];
5037
5142
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5143
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5038
5144
  };
5039
5145
  previewMultiConversion?: boolean;
5040
5146
  persistFiltersAcrossTabs?: boolean;
@@ -5077,6 +5183,7 @@ export declare class AuditService {
5077
5183
  enabled?: boolean;
5078
5184
  data?: string[];
5079
5185
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5186
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5080
5187
  };
5081
5188
  previewMultiConversion?: boolean;
5082
5189
  persistFiltersAcrossTabs?: boolean;
@@ -5293,7 +5400,7 @@ export declare class PreviewService {
5293
5400
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
5294
5401
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
5295
5402
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
5296
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
5403
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
5297
5404
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
5298
5405
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
5299
5406
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -5426,6 +5533,7 @@ export declare class PreviewService {
5426
5533
  enabled?: boolean;
5427
5534
  data?: string[];
5428
5535
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5536
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5429
5537
  };
5430
5538
  previewMultiConversion?: boolean;
5431
5539
  persistFiltersAcrossTabs?: boolean;
@@ -5468,6 +5576,7 @@ export declare class PreviewService {
5468
5576
  enabled?: boolean;
5469
5577
  data?: string[];
5470
5578
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5579
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5471
5580
  };
5472
5581
  previewMultiConversion?: boolean;
5473
5582
  persistFiltersAcrossTabs?: boolean;
@@ -5532,6 +5641,7 @@ export declare class PreviewService {
5532
5641
  enabled?: boolean;
5533
5642
  data?: string[];
5534
5643
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5644
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5535
5645
  };
5536
5646
  previewMultiConversion?: boolean;
5537
5647
  persistFiltersAcrossTabs?: boolean;
@@ -5626,6 +5736,7 @@ export declare class PreviewService {
5626
5736
  enabled?: boolean;
5627
5737
  data?: string[];
5628
5738
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5739
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5629
5740
  };
5630
5741
  previewMultiConversion?: boolean;
5631
5742
  persistFiltersAcrossTabs?: boolean;
@@ -5668,6 +5779,7 @@ export declare class PreviewService {
5668
5779
  enabled?: boolean;
5669
5780
  data?: string[];
5670
5781
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5782
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
5671
5783
  };
5672
5784
  previewMultiConversion?: boolean;
5673
5785
  persistFiltersAcrossTabs?: boolean;
@@ -6040,6 +6152,7 @@ export declare class AggregationsService {
6040
6152
  enabled?: boolean;
6041
6153
  data?: string[];
6042
6154
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6155
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6043
6156
  };
6044
6157
  previewMultiConversion?: boolean;
6045
6158
  persistFiltersAcrossTabs?: boolean;
@@ -6082,6 +6195,7 @@ export declare class AggregationsService {
6082
6195
  enabled?: boolean;
6083
6196
  data?: string[];
6084
6197
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6198
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6085
6199
  };
6086
6200
  previewMultiConversion?: boolean;
6087
6201
  persistFiltersAcrossTabs?: boolean;
@@ -6146,6 +6260,7 @@ export declare class AggregationsService {
6146
6260
  enabled?: boolean;
6147
6261
  data?: string[];
6148
6262
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6263
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6149
6264
  };
6150
6265
  previewMultiConversion?: boolean;
6151
6266
  persistFiltersAcrossTabs?: boolean;
@@ -6240,6 +6355,7 @@ export declare class AggregationsService {
6240
6355
  enabled?: boolean;
6241
6356
  data?: string[];
6242
6357
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6358
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6243
6359
  };
6244
6360
  previewMultiConversion?: boolean;
6245
6361
  persistFiltersAcrossTabs?: boolean;
@@ -6282,6 +6398,7 @@ export declare class AggregationsService {
6282
6398
  enabled?: boolean;
6283
6399
  data?: string[];
6284
6400
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6401
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6285
6402
  };
6286
6403
  previewMultiConversion?: boolean;
6287
6404
  persistFiltersAcrossTabs?: boolean;
@@ -6343,7 +6460,7 @@ export declare class AggregationsService {
6343
6460
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
6344
6461
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
6345
6462
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
6346
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
6463
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
6347
6464
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
6348
6465
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
6349
6466
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -6599,6 +6716,7 @@ export declare class ApplicationService {
6599
6716
  updateBookmarks: (bookmarks: UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
6600
6717
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
6601
6718
  unbookmark: (id: string) => Promise<void>;
6719
+ unbookmarkMany: (ids: string[]) => Promise<void>;
6602
6720
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
6603
6721
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
6604
6722
  isFavoriteSearch: (search: Pick<import("@sinequa/atomic-angular").SearchItem, "label" | "display">) => boolean;
@@ -6765,6 +6883,7 @@ export declare class ApplicationService {
6765
6883
  enabled?: boolean;
6766
6884
  data?: string[];
6767
6885
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6886
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6768
6887
  };
6769
6888
  previewMultiConversion?: boolean;
6770
6889
  persistFiltersAcrossTabs?: boolean;
@@ -6807,6 +6926,7 @@ export declare class ApplicationService {
6807
6926
  enabled?: boolean;
6808
6927
  data?: string[];
6809
6928
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6929
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6810
6930
  };
6811
6931
  previewMultiConversion?: boolean;
6812
6932
  persistFiltersAcrossTabs?: boolean;
@@ -6871,6 +6991,7 @@ export declare class ApplicationService {
6871
6991
  enabled?: boolean;
6872
6992
  data?: string[];
6873
6993
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6994
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6874
6995
  };
6875
6996
  previewMultiConversion?: boolean;
6876
6997
  persistFiltersAcrossTabs?: boolean;
@@ -6965,6 +7086,7 @@ export declare class ApplicationService {
6965
7086
  enabled?: boolean;
6966
7087
  data?: string[];
6967
7088
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7089
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
6968
7090
  };
6969
7091
  previewMultiConversion?: boolean;
6970
7092
  persistFiltersAcrossTabs?: boolean;
@@ -7007,6 +7129,7 @@ export declare class ApplicationService {
7007
7129
  enabled?: boolean;
7008
7130
  data?: string[];
7009
7131
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7132
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7010
7133
  };
7011
7134
  previewMultiConversion?: boolean;
7012
7135
  persistFiltersAcrossTabs?: boolean;
@@ -7059,7 +7182,7 @@ export declare class ApplicationService {
7059
7182
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
7060
7183
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
7061
7184
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
7062
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
7185
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
7063
7186
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
7064
7187
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
7065
7188
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -7293,6 +7416,7 @@ export declare class AutocompleteService {
7293
7416
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
7294
7417
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
7295
7418
  unbookmark: (id: string) => Promise<void>;
7419
+ unbookmarkMany: (ids: string[]) => Promise<void>;
7296
7420
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
7297
7421
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
7298
7422
  isFavoriteSearch: (search: Pick<import("@sinequa/atomic-angular").SearchItem, "label" | "display">) => boolean;
@@ -7395,6 +7519,7 @@ export declare class AutocompleteService {
7395
7519
  enabled?: boolean;
7396
7520
  data?: string[];
7397
7521
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7522
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7398
7523
  };
7399
7524
  previewMultiConversion?: boolean;
7400
7525
  persistFiltersAcrossTabs?: boolean;
@@ -7437,6 +7562,7 @@ export declare class AutocompleteService {
7437
7562
  enabled?: boolean;
7438
7563
  data?: string[];
7439
7564
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7565
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7440
7566
  };
7441
7567
  previewMultiConversion?: boolean;
7442
7568
  persistFiltersAcrossTabs?: boolean;
@@ -7501,6 +7627,7 @@ export declare class AutocompleteService {
7501
7627
  enabled?: boolean;
7502
7628
  data?: string[];
7503
7629
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7630
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7504
7631
  };
7505
7632
  previewMultiConversion?: boolean;
7506
7633
  persistFiltersAcrossTabs?: boolean;
@@ -7595,6 +7722,7 @@ export declare class AutocompleteService {
7595
7722
  enabled?: boolean;
7596
7723
  data?: string[];
7597
7724
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7725
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7598
7726
  };
7599
7727
  previewMultiConversion?: boolean;
7600
7728
  persistFiltersAcrossTabs?: boolean;
@@ -7637,6 +7765,7 @@ export declare class AutocompleteService {
7637
7765
  enabled?: boolean;
7638
7766
  data?: string[];
7639
7767
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7768
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
7640
7769
  };
7641
7770
  previewMultiConversion?: boolean;
7642
7771
  persistFiltersAcrossTabs?: boolean;
@@ -7828,6 +7957,43 @@ export declare class KeyboardShortcutsService {
7828
7957
  static ɵfac: i0.ɵɵFactoryDeclaration<KeyboardShortcutsService, never>;
7829
7958
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
7830
7959
  }
7960
+ /**
7961
+ * The license-driven capabilities of the grid, as reported by `GET /api/v2/version`.
7962
+ *
7963
+ * Only the capabilities in `features.isAvailable` are read — neither the raw `license.featureFlags`
7964
+ * nor `features.beta`: the server already combines the flags with the Beta option, and says so in one
7965
+ * place. A capability is `true` only when the server says exactly `true`.
7966
+ *
7967
+ * The Agent Builder has no capability of its own: it relies on `agentStore`, which is `true` when the
7968
+ * license grants `FeatureFlag_AgentHub` or `FeatureFlag_AgentBuilder` and the Beta option is on.
7969
+ *
7970
+ * Every failure reads as "not available" — an older server without `features.isAvailable`, a missing
7971
+ * field, a failing request — so that what depends on a capability is hidden instead of the application
7972
+ * being blocked.
7973
+ *
7974
+ * Call {@link load} once the application is bootstrapped (the request needs the `backendUrl` and the
7975
+ * sign-in), typically from the same application initializer as `bootstrapApp`. Until then every
7976
+ * capability is `false`.
7977
+ */
7978
+ export declare class LicenseCapabilitiesService {
7979
+ private readonly client;
7980
+ private readonly _agentStoreAvailable;
7981
+ /**
7982
+ * Whether the Agent store is available (`features.isAvailable.agentStore === true`): the license
7983
+ * grants `FeatureFlag_AgentHub` or `FeatureFlag_AgentBuilder` and the Beta option is on.
7984
+ * Use it to show or hide the Agent Builder.
7985
+ */
7986
+ readonly agentStoreAvailable: import("@angular/core").Signal<boolean>;
7987
+ /**
7988
+ * Reads the capabilities from `GET /api/v2/version`.
7989
+ *
7990
+ * Never rejects: it is meant to run inside an application initializer, where a rejection would stop
7991
+ * the application from starting. On failure the capabilities are reset to `false`.
7992
+ */
7993
+ load(): Promise<void>;
7994
+ static ɵfac: i0.ɵɵFactoryDeclaration<LicenseCapabilitiesService, never>;
7995
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
7996
+ }
7831
7997
  export declare class NavigationService {
7832
7998
  private readonly router;
7833
7999
  private readonly auditService;
@@ -7937,6 +8103,7 @@ export declare class SavedSearchesService {
7937
8103
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
7938
8104
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
7939
8105
  unbookmark: (id: string) => Promise<void>;
8106
+ unbookmarkMany: (ids: string[]) => Promise<void>;
7940
8107
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
7941
8108
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
7942
8109
  isFavoriteSearch: (search: Pick<SearchItem, "label" | "display">) => boolean;
@@ -8016,7 +8183,7 @@ export declare class SavedSearchesService {
8016
8183
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
8017
8184
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
8018
8185
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
8019
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
8186
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
8020
8187
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
8021
8188
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
8022
8189
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -8201,7 +8368,7 @@ export declare class SearchService {
8201
8368
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
8202
8369
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
8203
8370
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
8204
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
8371
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
8205
8372
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
8206
8373
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
8207
8374
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -8303,6 +8470,7 @@ export declare class SearchService {
8303
8470
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: AuditEvents) => Promise<void>;
8304
8471
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
8305
8472
  unbookmark: (id: string) => Promise<void>;
8473
+ unbookmarkMany: (ids: string[]) => Promise<void>;
8306
8474
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
8307
8475
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
8308
8476
  isFavoriteSearch: (search: Pick<import("@sinequa/atomic-angular").SearchItem, "label" | "display">) => boolean;
@@ -8430,7 +8598,7 @@ export declare class SelectionService {
8430
8598
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
8431
8599
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
8432
8600
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
8433
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
8601
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
8434
8602
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
8435
8603
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
8436
8604
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -8575,6 +8743,8 @@ export declare class TextChunkService {
8575
8743
  export declare class UserProfileService {
8576
8744
  private readonly client;
8577
8745
  private readonly injector;
8746
+ private readonly appStore;
8747
+ private readonly principal;
8578
8748
  private readonly resources;
8579
8749
  /**
8580
8750
  * Retrieves the user profile by user ID.
@@ -8588,6 +8758,24 @@ export declare class UserProfileService {
8588
8758
  * @returns A resource exposing the UserProfile.
8589
8759
  */
8590
8760
  getUserProfile(userId: Signal<string | undefined>): ResourceRef<UserProfile | undefined>;
8761
+ /**
8762
+ * The id of the signed-in user, once known, and only when the `userProfile` feature is on; `undefined` otherwise,
8763
+ * which leaves the profile resource idle (no request).
8764
+ */
8765
+ readonly currentUserId: Signal<string | undefined>;
8766
+ /**
8767
+ * The profile of the signed-in user, fetched once for the whole application: the sidebar (avatar), the home page
8768
+ * (greeting) and the profile form all read this same resource, so a value set by one shows up in the others.
8769
+ */
8770
+ readonly current: ResourceRef<UserProfile | undefined>;
8771
+ /** The loaded profile of the signed-in user, `undefined` while it loads, when it failed to load, or when the feature is off. */
8772
+ readonly profile: Signal<UserProfile | undefined>;
8773
+ /**
8774
+ * The profile of the signed-in user is about to be, or is being, fetched. `idle` with an id to fetch is the instant
8775
+ * between the id being known and the resource starting: still pending. A failed fetch is not pending: it gives way
8776
+ * to the next source of a name.
8777
+ */
8778
+ readonly pending: Signal<boolean>;
8591
8779
  static ɵfac: i0.ɵɵFactoryDeclaration<UserProfileService, never>;
8592
8780
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
8593
8781
  }
@@ -8722,6 +8910,7 @@ export declare class SortSelectorComponent {
8722
8910
  enabled?: boolean;
8723
8911
  data?: string[];
8724
8912
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8913
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8725
8914
  };
8726
8915
  previewMultiConversion?: boolean;
8727
8916
  persistFiltersAcrossTabs?: boolean;
@@ -8764,6 +8953,7 @@ export declare class SortSelectorComponent {
8764
8953
  enabled?: boolean;
8765
8954
  data?: string[];
8766
8955
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8956
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8767
8957
  };
8768
8958
  previewMultiConversion?: boolean;
8769
8959
  persistFiltersAcrossTabs?: boolean;
@@ -8828,6 +9018,7 @@ export declare class SortSelectorComponent {
8828
9018
  enabled?: boolean;
8829
9019
  data?: string[];
8830
9020
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9021
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8831
9022
  };
8832
9023
  previewMultiConversion?: boolean;
8833
9024
  persistFiltersAcrossTabs?: boolean;
@@ -8922,6 +9113,7 @@ export declare class SortSelectorComponent {
8922
9113
  enabled?: boolean;
8923
9114
  data?: string[];
8924
9115
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9116
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8925
9117
  };
8926
9118
  previewMultiConversion?: boolean;
8927
9119
  persistFiltersAcrossTabs?: boolean;
@@ -8964,6 +9156,7 @@ export declare class SortSelectorComponent {
8964
9156
  enabled?: boolean;
8965
9157
  data?: string[];
8966
9158
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9159
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
8967
9160
  };
8968
9161
  previewMultiConversion?: boolean;
8969
9162
  persistFiltersAcrossTabs?: boolean;
@@ -9183,6 +9376,7 @@ export declare class ShowBookmarkDirective {
9183
9376
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
9184
9377
  bookmark: (article: Article, queryName?: string) => Promise<void>;
9185
9378
  unbookmark: (id: string) => Promise<void>;
9379
+ unbookmarkMany: (ids: string[]) => Promise<void>;
9186
9380
  isBookmarked: (article: Partial<Article>) => boolean;
9187
9381
  toggleBookmark: (article: Article) => Promise<void>;
9188
9382
  isFavoriteSearch: (search: Pick<import("@sinequa/atomic-angular").SearchItem, "label" | "display">) => boolean;
@@ -9399,6 +9593,14 @@ export declare class OverflowManagerDirective {
9399
9593
  readonly stop: import("@angular/core").Signal<ElementRef<any> | undefined>;
9400
9594
  readonly target: import("@angular/core").InputSignal<HTMLElement | undefined>;
9401
9595
  readonly margin: import("@angular/core").InputSignal<number>;
9596
+ /**
9597
+ * Margin used only by the "does every item fit?" test, instead of `margin`.
9598
+ * Defaults to `margin`. A container that is exactly as wide as its content
9599
+ * (a centered bar, say) has no spare room, so `margin` would always report an
9600
+ * overflow there: pass a value <= 0 (a negative one is a sub-pixel tolerance).
9601
+ * `margin` still applies to the space reserved for the stop element.
9602
+ */
9603
+ readonly fitMargin: import("@angular/core").InputSignal<number | undefined>;
9402
9604
  readonly direction: import("@angular/core").InputSignal<"horizontal" | "vertical">;
9403
9605
  /**
9404
9606
  * Always reserve the stop element's size, even when every item fits inside
@@ -9407,11 +9609,18 @@ export declare class OverflowManagerDirective {
9407
9609
  * the container), so the last item never overlaps it.
9408
9610
  */
9409
9611
  readonly reserveStop: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
9612
+ /**
9613
+ * Fade an item in when it comes back into view (it was hidden by the previous
9614
+ * count), instead of popping in. Skipped when the user prefers reduced motion.
9615
+ */
9616
+ readonly animate: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
9410
9617
  readonly count: import("@angular/core").OutputEmitterRef<number>;
9411
9618
  private readonly el;
9412
9619
  private readonly destroyRef;
9413
9620
  private readonly resizeObserver;
9414
9621
  private readonly itemsResizeObserver;
9622
+ /** Items hidden by the last committed count, to tell a reveal from an item that stayed visible. */
9623
+ private readonly hiddenItems;
9415
9624
  private countSub;
9416
9625
  private _lastCount;
9417
9626
  constructor();
@@ -9432,6 +9641,7 @@ export declare class OverflowManagerDirective {
9432
9641
  * @param count - The number of items to keep visible.
9433
9642
  */
9434
9643
  toggleToCount(count: number): void;
9644
+ private fadeIn;
9435
9645
  static ɵfac: i0.ɵɵFactoryDeclaration<OverflowManagerDirective, never>;
9436
9646
  static ɵdir: i0.ɵɵDirectiveDeclaration<OverflowManagerDirective, "[overflowManager]", never, {
9437
9647
  "target": {
@@ -9444,6 +9654,11 @@ export declare class OverflowManagerDirective {
9444
9654
  "required": false;
9445
9655
  "isSignal": true;
9446
9656
  };
9657
+ "fitMargin": {
9658
+ "alias": "fitMargin";
9659
+ "required": false;
9660
+ "isSignal": true;
9661
+ };
9447
9662
  "direction": {
9448
9663
  "alias": "direction";
9449
9664
  "required": false;
@@ -9454,6 +9669,11 @@ export declare class OverflowManagerDirective {
9454
9669
  "required": false;
9455
9670
  "isSignal": true;
9456
9671
  };
9672
+ "animate": {
9673
+ "alias": "animate";
9674
+ "required": false;
9675
+ "isSignal": true;
9676
+ };
9457
9677
  }, {
9458
9678
  "count": "count";
9459
9679
  }, ["items", "stop"], never, true, never>;
@@ -9658,6 +9878,7 @@ export declare class SponsoredResultsComponent {
9658
9878
  enabled?: boolean;
9659
9879
  data?: string[];
9660
9880
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9881
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9661
9882
  };
9662
9883
  previewMultiConversion?: boolean;
9663
9884
  persistFiltersAcrossTabs?: boolean;
@@ -9700,6 +9921,7 @@ export declare class SponsoredResultsComponent {
9700
9921
  enabled?: boolean;
9701
9922
  data?: string[];
9702
9923
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9924
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9703
9925
  };
9704
9926
  previewMultiConversion?: boolean;
9705
9927
  persistFiltersAcrossTabs?: boolean;
@@ -9764,6 +9986,7 @@ export declare class SponsoredResultsComponent {
9764
9986
  enabled?: boolean;
9765
9987
  data?: string[];
9766
9988
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9989
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9767
9990
  };
9768
9991
  previewMultiConversion?: boolean;
9769
9992
  persistFiltersAcrossTabs?: boolean;
@@ -9858,6 +10081,7 @@ export declare class SponsoredResultsComponent {
9858
10081
  enabled?: boolean;
9859
10082
  data?: string[];
9860
10083
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
10084
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9861
10085
  };
9862
10086
  previewMultiConversion?: boolean;
9863
10087
  persistFiltersAcrossTabs?: boolean;
@@ -9900,6 +10124,7 @@ export declare class SponsoredResultsComponent {
9900
10124
  enabled?: boolean;
9901
10125
  data?: string[];
9902
10126
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
10127
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
9903
10128
  };
9904
10129
  previewMultiConversion?: boolean;
9905
10130
  persistFiltersAcrossTabs?: boolean;
@@ -9952,7 +10177,7 @@ export declare class SponsoredResultsComponent {
9952
10177
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
9953
10178
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
9954
10179
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
9955
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
10180
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
9956
10181
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
9957
10182
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
9958
10183
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -11040,7 +11265,7 @@ export declare class AdvancedSearch {
11040
11265
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
11041
11266
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
11042
11267
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
11043
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
11268
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
11044
11269
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
11045
11270
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
11046
11271
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -12083,25 +12308,75 @@ export declare class AuthPageComponent {
12083
12308
  };
12084
12309
  }, {}, never, never, true, never>;
12085
12310
  }
12311
+ /**
12312
+ * The change-password form dressed as an auth page block: the product logo above the form, inside a card.
12313
+ *
12314
+ * It only adds the dressing — every behaviour lives in {@link ChangePasswordFormComponent}, which is
12315
+ * what to use anywhere the logo has no place (a settings panel, a dialog body).
12316
+ */
12317
+ export declare class ChangePasswordComponent {
12318
+ readonly success: import("@angular/core").OutputEmitterRef<void>;
12319
+ readonly cancel: import("@angular/core").OutputEmitterRef<void>;
12320
+ readonly username: import("@angular/core").InputSignal<string | null>;
12321
+ readonly alert: import("@angular/core").InputSignal<string | undefined>;
12322
+ readonly redirectAfterSuccess: import("@angular/core").InputSignal<boolean>;
12323
+ readonly redirectAfterCancel: import("@angular/core").InputSignal<boolean>;
12324
+ protected readonly surfaceClass = "flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)";
12325
+ static ɵfac: i0.ɵɵFactoryDeclaration<ChangePasswordComponent, never>;
12326
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChangePasswordComponent, "change-password, ChangePassword, changepassword", never, {
12327
+ "username": {
12328
+ "alias": "username";
12329
+ "required": false;
12330
+ "isSignal": true;
12331
+ };
12332
+ "alert": {
12333
+ "alias": "alert";
12334
+ "required": false;
12335
+ "isSignal": true;
12336
+ };
12337
+ "redirectAfterSuccess": {
12338
+ "alias": "redirectAfterSuccess";
12339
+ "required": false;
12340
+ "isSignal": true;
12341
+ };
12342
+ "redirectAfterCancel": {
12343
+ "alias": "redirectAfterCancel";
12344
+ "required": false;
12345
+ "isSignal": true;
12346
+ };
12347
+ }, {
12348
+ "success": "success";
12349
+ "cancel": "cancel";
12350
+ }, never, never, true, never>;
12351
+ }
12086
12352
  /** Model of the change-password form. */
12087
12353
  export interface PasswordChange {
12088
12354
  currentPassword: string;
12089
12355
  newPassword: string;
12090
12356
  confirmPassword: string;
12091
12357
  }
12092
- type PasswordFieldType = "password" | "text";
12093
- export declare class ChangePasswordComponent {
12358
+ /**
12359
+ * The change-password form, and nothing else: no logo, no card, no surface of its own.
12360
+ *
12361
+ * It lays out like any block of content, so it can be dropped anywhere — inline in a settings panel,
12362
+ * in the body of a dialog, or inside the card of an auth page (`<change-password>`).
12363
+ *
12364
+ * Buttons: by default the form renders its own Cancel / Confirm row. A container that already owns
12365
+ * the buttons (a dialog's footer) sets `[showActions]="false"` and drives the form through
12366
+ * {@link changePassword}, {@link canSubmit} and {@link pending}.
12367
+ */
12368
+ export declare class ChangePasswordFormComponent {
12094
12369
  readonly success: import("@angular/core").OutputEmitterRef<void>;
12095
12370
  readonly cancel: import("@angular/core").OutputEmitterRef<void>;
12096
- username: import("@angular/core").InputSignal<string | null>;
12097
- alert: import("@angular/core").InputSignal<string | undefined>;
12098
- redirectAfterSuccess: import("@angular/core").InputSignal<boolean>;
12099
- redirectAfterCancel: import("@angular/core").InputSignal<boolean>;
12371
+ readonly username: import("@angular/core").InputSignal<string | null>;
12372
+ readonly alert: import("@angular/core").InputSignal<string | undefined>;
12373
+ readonly redirectAfterSuccess: import("@angular/core").InputSignal<boolean>;
12374
+ readonly redirectAfterCancel: import("@angular/core").InputSignal<boolean>;
12100
12375
  /**
12101
- * Renders the form as a card (background, padding, shadow). Set `false` when the container
12102
- * already provides the surface — a dialog body, a settings panel — to avoid nesting cards.
12376
+ * Renders the Cancel / Confirm row. Set `false` when the container owns the buttons — a dialog
12377
+ * footer — and drive the form through `changePassword()` / `canSubmit()`.
12103
12378
  */
12104
- surface: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12379
+ readonly showActions: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12105
12380
  private readonly client;
12106
12381
  private readonly transloco;
12107
12382
  private readonly router;
@@ -12109,41 +12384,57 @@ export declare class ChangePasswordComponent {
12109
12384
  private readonly applicationService;
12110
12385
  private readonly location;
12111
12386
  private readonly auditService;
12112
- protected readonly containerClass: import("@angular/core").Signal<"flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)" | "flex w-full flex-col gap-(--spacing-md)">;
12113
- protected readonly footerClass = "flex justify-end gap-(--spacing-2xs) -mx-(--spacing-md) -mb-(--spacing-md) rounded-b-(--radius-md) bg-(--layer-page-on-layer) px-(--spacing-md) py-(--spacing-sm)";
12114
- protected readonly fieldClass = "flex flex-col gap-(--spacing-2xs)";
12115
- protected readonly labelClass = "text-(length:--size-base) font-(--weight-semibold) text-(--font-primary-base)";
12116
- protected readonly errorClass = "text-(length:--size-base) text-(--font-error-base)";
12117
- protected readonly alertClass = "rounded-(--radius-sm) bg-(--bg-error-lightest) p-(--spacing-xs) text-(length:--size-base) text-(--font-error-base)";
12118
- /** Form model. Replaces the three former scalar models. */
12119
- readonly passwords: import("@angular/core").ModelSignal<PasswordChange>;
12120
- /** `protected` and not `private`: a subclass template must be able to bind its own controls. */
12387
+ protected readonly css: {
12388
+ form: string;
12389
+ field: string;
12390
+ label: string;
12391
+ error: string;
12392
+ alert: string;
12393
+ actions: string;
12394
+ };
12395
+ protected readonly fields: readonly [{
12396
+ readonly name: "currentPassword";
12397
+ readonly id: "change-current-password";
12398
+ readonly label: "login.currentPassword";
12399
+ readonly autocomplete: "current-password";
12400
+ }, {
12401
+ readonly name: "newPassword";
12402
+ readonly id: "change-new-password";
12403
+ readonly label: "login.newPassword";
12404
+ readonly autocomplete: "new-password";
12405
+ }, {
12406
+ readonly name: "confirmPassword";
12407
+ readonly id: "change-confirm-password";
12408
+ readonly label: "login.confirmPassword";
12409
+ readonly autocomplete: "new-password";
12410
+ }];
12411
+ protected readonly showError: typeof fieldShowsError;
12412
+ protected readonly errorKey: (field: FieldTree<string>) => string;
12413
+ readonly passwords: import("@angular/core").WritableSignal<PasswordChange>;
12121
12414
  protected readonly passwordForm: FieldTree<PasswordChange, string | number, "writable">;
12122
- pending: WritableSignal<boolean>;
12123
- errorMsg: WritableSignal<string | null>;
12124
- readonly currentPasswordType: WritableSignal<PasswordFieldType>;
12125
- readonly newPasswordType: WritableSignal<PasswordFieldType>;
12126
- readonly confirmPasswordType: WritableSignal<PasswordFieldType>;
12127
- valid: import("@angular/core").Signal<boolean>;
12128
- confirmInvalid: import("@angular/core").Signal<boolean>;
12415
+ readonly pending: import("@angular/core").WritableSignal<boolean>;
12416
+ readonly errorMsg: import("@angular/core").WritableSignal<string | null>;
12417
+ /** The server rejects a password change made while acting as another user (HTTP 400). */
12418
+ protected readonly overridingUser: import("@angular/core").Signal<boolean>;
12419
+ /** Whether a submission would run: valid form, nothing in flight, not impersonating. */
12420
+ readonly canSubmit: import("@angular/core").Signal<boolean>;
12421
+ /** Names of the fields currently shown in clear text. */
12422
+ private readonly revealed;
12129
12423
  readonly effectiveUsername: import("@angular/core").Signal<string | null>;
12130
- protected togglePasswordType(field: WritableSignal<PasswordFieldType>): void;
12131
- /** A field shows its error only once the user has left it — never while typing the first time. */
12132
- protected showError<T>(field: FieldTree<T>): boolean;
12133
- /** Maps the first validation error to its translation key (`login.errors.passwordMismatch`, …). */
12134
- protected errorKey<T>(field: FieldTree<T>): string;
12424
+ constructor();
12425
+ protected isRevealed(name: keyof PasswordChange): boolean;
12426
+ protected toggleReveal(name: keyof PasswordChange): void;
12135
12427
  private clearLocalAuthState;
12136
12428
  /**
12137
12429
  * Submits the form. `submit()` marks every field as touched — revealing the validation
12138
- * messages — and only runs the action when the form is valid, replacing the former
12139
- * `if (!this.valid()) return;` guard.
12430
+ * messages — and only runs the action when the form is valid.
12140
12431
  */
12141
12432
  changePassword(): Promise<boolean>;
12142
12433
  /** The submission itself. Only ever reached with a valid form. */
12143
12434
  private performChange;
12144
12435
  onCancel(): void;
12145
- static ɵfac: i0.ɵɵFactoryDeclaration<ChangePasswordComponent, never>;
12146
- static ɵcmp: i0.ɵɵComponentDeclaration<ChangePasswordComponent, "change-password, ChangePassword, changepassword", never, {
12436
+ static ɵfac: i0.ɵɵFactoryDeclaration<ChangePasswordFormComponent, never>;
12437
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChangePasswordFormComponent, "change-password-form, ChangePasswordForm, changepasswordform", never, {
12147
12438
  "username": {
12148
12439
  "alias": "username";
12149
12440
  "required": false;
@@ -12164,25 +12455,22 @@ export declare class ChangePasswordComponent {
12164
12455
  "required": false;
12165
12456
  "isSignal": true;
12166
12457
  };
12167
- "surface": {
12168
- "alias": "surface";
12169
- "required": false;
12170
- "isSignal": true;
12171
- };
12172
- "passwords": {
12173
- "alias": "passwords";
12458
+ "showActions": {
12459
+ "alias": "showActions";
12174
12460
  "required": false;
12175
12461
  "isSignal": true;
12176
12462
  };
12177
12463
  }, {
12178
12464
  "success": "success";
12179
12465
  "cancel": "cancel";
12180
- "passwords": "passwordsChange";
12181
12466
  }, never, never, true, never>;
12182
12467
  }
12183
12468
  /**
12184
- * Represents the LoginComponent class, which is responsible for handling the login functionality.
12185
- * This component is used to authenticate users and manage the user's authentication status.
12469
+ * The sign-in screen: the credentials form (`<sign-in-form>`) dressed as an auth page block — logo and
12470
+ * card — plus everything around the form: the SSO / OAuth / SAML / bearer handshake, the loader shown
12471
+ * while it runs, and the password-expiry notice.
12472
+ *
12473
+ * Use `<sign-in-form>` directly anywhere the logo, the card and the handshake have no place.
12186
12474
  */
12187
12475
  export declare class SignInComponent implements OnInit {
12188
12476
  cn: import("cn").CnFunction;
@@ -12190,6 +12478,7 @@ export declare class SignInComponent implements OnInit {
12190
12478
  config: Readonly<Partial<{
12191
12479
  app: string;
12192
12480
  backendUrl: string;
12481
+ apiPrefix: string;
12193
12482
  autoOAuthProvider: string;
12194
12483
  autoSAMLProvider: string;
12195
12484
  bearerToken: string;
@@ -12209,10 +12498,9 @@ export declare class SignInComponent implements OnInit {
12209
12498
  loginPath: string;
12210
12499
  createRoutes: boolean;
12211
12500
  }> & Record<string, unknown>>;
12212
- protected readonly containerClass: import("@angular/core").Signal<"flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)" | "flex w-full flex-col gap-(--spacing-md)">;
12213
- protected readonly fieldClass = "flex flex-col gap-(--spacing-2xs)";
12214
- protected readonly labelClass = "text-(length:--size-base) font-(--weight-semibold) text-(--font-primary-base)";
12215
- protected readonly errorClass = "text-(length:--size-base) text-(--font-error-base)";
12501
+ protected readonly surfaceClass = "flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)";
12502
+ /** The credentials form, once rendered: its username feeds the password-expiry notice. */
12503
+ private readonly signInForm;
12216
12504
  /**
12217
12505
  * True when authentication is handled outside the credentials form — the browser or a proxy
12218
12506
  * (`sso`), an auto-configured OAuth/SAML provider, or a configured token (`bearer`). In those modes
@@ -12229,11 +12517,6 @@ export declare class SignInComponent implements OnInit {
12229
12517
  * step, a wizard — where `h-dvh` would blow the container out.
12230
12518
  */
12231
12519
  fullscreen: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12232
- /**
12233
- * Renders the form as a card (background, padding, shadow). Set `false` when the container
12234
- * already provides the surface — a dialog body, a settings panel — to avoid nesting cards.
12235
- */
12236
- surface: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12237
12520
  /**
12238
12521
  * Navigate to the `returnUrl` once authenticated. Opt-out when the host owns what comes next
12239
12522
  * (same contract as `ChangePasswordComponent`): the component then only emits `success`.
@@ -12249,17 +12532,6 @@ export declare class SignInComponent implements OnInit {
12249
12532
  readonly changePassword: import("@angular/core").OutputEmitterRef<string>;
12250
12533
  /** Emitted once authenticated and the application is initialized — before any navigation. */
12251
12534
  readonly success: import("@angular/core").OutputEmitterRef<void>;
12252
- /**
12253
- * Form model. Keeps the exact shape of the `credentials` computed it replaces, so reading
12254
- * `credentials()` is unchanged for consumers — only `.set()` is new.
12255
- */
12256
- readonly credentials: import("@angular/core").ModelSignal<Credentials>;
12257
- /**
12258
- * The sign-in form itself. `protected` and not `private`: extending this component is documented
12259
- * publicly, and a subclass template must be able to bind `[formField]="signInForm.username"`.
12260
- */
12261
- protected readonly signInForm: FieldTree<Credentials, string | number, "writable">;
12262
- isValid: import("@angular/core").Signal<boolean>;
12263
12535
  private readonly router;
12264
12536
  private readonly route;
12265
12537
  private readonly applicationService;
@@ -12305,10 +12577,6 @@ export declare class SignInComponent implements OnInit {
12305
12577
  * instead of routing to /error.
12306
12578
  */
12307
12579
  readonly showCredentialsFallback: import("@angular/core").WritableSignal<boolean>;
12308
- /** A field shows its error only once the user has left it — never while typing the first time. */
12309
- protected showError<T>(field: FieldTree<T>): boolean;
12310
- /** Maps the first validation error to its translation key (`login.errors.required`, …). */
12311
- protected errorKey<T>(field: FieldTree<T>): string;
12312
12580
  private readonly destroyRef;
12313
12581
  constructor();
12314
12582
  /**
@@ -12344,14 +12612,8 @@ export declare class SignInComponent implements OnInit {
12344
12612
  private checkPasswordExpiresSoon;
12345
12613
  handleLogout(): Promise<void>;
12346
12614
  handleLogin(): Promise<boolean>;
12347
- /**
12348
- * Submits the credentials form. `submit()` marks every field as touched — which reveals the
12349
- * validation messages — and only runs the action when the form is valid, replacing the former
12350
- * `if (!this.isValid()) return;` guard.
12351
- */
12352
- handleLoginWithCredentials(): Promise<boolean>;
12353
- /** The submission itself. Only ever reached with a valid form (see `handleLoginWithCredentials`). */
12354
- private performLogin;
12615
+ /** The form authenticated and initialized the app — before any navigation. */
12616
+ protected onSuccess(): void;
12355
12617
  handleBack(): void;
12356
12618
  static ɵfac: i0.ɵɵFactoryDeclaration<SignInComponent, never>;
12357
12619
  static ɵcmp: i0.ɵɵComponentDeclaration<SignInComponent, "signIn, signin, sign-in", never, {
@@ -12365,18 +12627,84 @@ export declare class SignInComponent implements OnInit {
12365
12627
  "required": false;
12366
12628
  "isSignal": true;
12367
12629
  };
12368
- "surface": {
12369
- "alias": "surface";
12630
+ "redirectAfterSuccess": {
12631
+ "alias": "redirectAfterSuccess";
12370
12632
  "required": false;
12371
12633
  "isSignal": true;
12372
12634
  };
12635
+ "autoStart": {
12636
+ "alias": "autoStart";
12637
+ "required": false;
12638
+ "isSignal": true;
12639
+ };
12640
+ }, {
12641
+ "forgotPassword": "forgotPassword";
12642
+ "changePassword": "changePassword";
12643
+ "success": "success";
12644
+ }, never, never, true, never>;
12645
+ }
12646
+ /**
12647
+ * The credentials form, and nothing else: no logo, no card, no loader, no external handshake.
12648
+ *
12649
+ * It lays out like any block of content, so it can be dropped anywhere — inline in a page, in the
12650
+ * body of a dialog, or inside the card of an auth page (`<sign-in>`, which also drives the SSO / OAuth /
12651
+ * SAML handshake). A container that owns the submit button sets `[showActions]="false"` and drives the
12652
+ * form through {@link handleLoginWithCredentials} and {@link canSubmit}.
12653
+ */
12654
+ export declare class SignInFormComponent {
12655
+ private readonly client;
12656
+ private readonly router;
12657
+ private readonly route;
12658
+ private readonly applicationService;
12659
+ private readonly auditService;
12660
+ /**
12661
+ * Navigate to the `returnUrl` once authenticated. Opt-out when the host owns what comes next
12662
+ * (same contract as `ChangePasswordFormComponent`): the component then only emits `success` — and, on an
12663
+ * expired password, `changePassword` without navigating to the change-password page.
12664
+ */
12665
+ readonly redirectAfterSuccess: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12666
+ /**
12667
+ * Renders the submit button. Set `false` when the container owns it — a dialog footer — and drive
12668
+ * the form through `handleLoginWithCredentials()` / `canSubmit()`.
12669
+ */
12670
+ readonly showActions: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12671
+ readonly forgotPassword: import("@angular/core").OutputEmitterRef<void>;
12672
+ /** Emitted when the server requires a password change (401 « password expired »). Payload: username. */
12673
+ readonly changePassword: import("@angular/core").OutputEmitterRef<string>;
12674
+ /** Emitted once authenticated and the application is initialized — before any navigation. */
12675
+ readonly success: import("@angular/core").OutputEmitterRef<void>;
12676
+ protected readonly css: {
12677
+ form: string;
12678
+ field: string;
12679
+ label: string;
12680
+ error: string;
12681
+ };
12682
+ protected readonly showError: typeof fieldShowsError;
12683
+ protected readonly errorKey: (field: FieldTree<string>) => string;
12684
+ /** Form model. */
12685
+ readonly credentials: import("@angular/core").ModelSignal<Credentials>;
12686
+ protected readonly signInForm: FieldTree<Credentials, string | number, "writable">;
12687
+ /** Whether a submission would run: both fields filled, nothing in flight. */
12688
+ readonly canSubmit: import("@angular/core").Signal<boolean>;
12689
+ protected onForgotPassword(event: Event): void;
12690
+ constructor();
12691
+ /**
12692
+ * Submits the credentials form. `submit()` marks every field as touched — which reveals the
12693
+ * validation messages — and only runs the action when the form is valid, replacing the former
12694
+ * `if (!this.isValid()) return;` guard.
12695
+ */
12696
+ handleLoginWithCredentials(): Promise<boolean>;
12697
+ /** The submission itself. Only ever reached with a valid form (see `handleLoginWithCredentials`). */
12698
+ private performLogin;
12699
+ static ɵfac: i0.ɵɵFactoryDeclaration<SignInFormComponent, never>;
12700
+ static ɵcmp: i0.ɵɵComponentDeclaration<SignInFormComponent, "sign-in-form, SignInForm, signinform", never, {
12373
12701
  "redirectAfterSuccess": {
12374
12702
  "alias": "redirectAfterSuccess";
12375
12703
  "required": false;
12376
12704
  "isSignal": true;
12377
12705
  };
12378
- "autoStart": {
12379
- "alias": "autoStart";
12706
+ "showActions": {
12707
+ "alias": "showActions";
12380
12708
  "required": false;
12381
12709
  "isSignal": true;
12382
12710
  };
@@ -12392,37 +12720,64 @@ export declare class SignInComponent implements OnInit {
12392
12720
  "credentials": "credentialsChange";
12393
12721
  }, never, never, true, never>;
12394
12722
  }
12723
+ /**
12724
+ * The password-reset form dressed as an auth page block: the product logo above the form, inside a card.
12725
+ *
12726
+ * It only adds the dressing — every behaviour lives in {@link ForgotPasswordFormComponent}, which is
12727
+ * what to use anywhere the logo has no place.
12728
+ */
12729
+ export declare class ForgotPasswordComponent {
12730
+ readonly cancel: import("@angular/core").OutputEmitterRef<void>;
12731
+ readonly success: import("@angular/core").OutputEmitterRef<void>;
12732
+ protected readonly surfaceClass = "flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)";
12733
+ static ɵfac: i0.ɵɵFactoryDeclaration<ForgotPasswordComponent, never>;
12734
+ static ɵcmp: i0.ɵɵComponentDeclaration<ForgotPasswordComponent, "forgot-password, ForgotPassword, forgotpassword", never, {}, {
12735
+ "cancel": "cancel";
12736
+ "success": "success";
12737
+ }, never, never, true, never>;
12738
+ }
12395
12739
  /** Model of the password-reset request. `username` matches `Credentials.username` and the `login.username` key. */
12396
12740
  export interface PasswordResetRequest {
12397
12741
  username: string;
12398
12742
  }
12399
- export declare class ForgotPasswordComponent {
12743
+ /**
12744
+ * The password-reset request form, and nothing else: no logo, no card, no surface of its own.
12745
+ *
12746
+ * It lays out like any block of content, so it can be dropped anywhere — inline in a page, in the
12747
+ * body of a dialog, or inside the card of an auth page (`<forgot-password>`). A container that owns
12748
+ * the buttons sets `[showActions]="false"` and drives it through {@link submit} and {@link canSubmit}.
12749
+ */
12750
+ export declare class ForgotPasswordFormComponent {
12400
12751
  readonly cancel: import("@angular/core").OutputEmitterRef<void>;
12401
12752
  readonly success: import("@angular/core").OutputEmitterRef<void>;
12402
12753
  /**
12403
- * Renders the form as a card (background, padding, shadow). Set `false` when the container
12404
- * already provides the surface — a dialog body, a settings panel — to avoid nesting cards.
12754
+ * Renders the Cancel / Send row. Set `false` when the container owns the buttons — a dialog
12755
+ * footer — and drive the form through `submit()` / `canSubmit()`.
12405
12756
  */
12406
- surface: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12757
+ readonly showActions: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12758
+ /** Renders the title above the description. Set `false` when the container already shows it — a dialog header. */
12759
+ readonly showTitle: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
12407
12760
  private readonly client;
12408
12761
  private readonly transloco;
12409
12762
  private readonly auditService;
12410
- protected readonly containerClass: import("@angular/core").Signal<"flex w-full flex-col gap-(--spacing-md) rounded-(--radius-md) border border-solid border-(--layer-page-edge) bg-(--layer-page-layer) p-(--spacing-md) shadow-(--shadow-2)" | "flex w-full flex-col gap-(--spacing-md)">;
12411
- protected readonly footerClass = "flex justify-end gap-(--spacing-2xs) -mx-(--spacing-md) -mb-(--spacing-md) rounded-b-(--radius-md) bg-(--layer-page-on-layer) px-(--spacing-md) py-(--spacing-sm)";
12412
- protected readonly fieldClass = "flex flex-col gap-(--spacing-2xs)";
12413
- protected readonly labelClass = "text-(length:--size-base) font-(--weight-semibold) text-(--font-primary-base)";
12414
- protected readonly errorClass = "text-(length:--size-base) text-(--font-error-base)";
12415
- protected readonly alertClass = "rounded-(--radius-sm) bg-(--bg-error-lightest) p-(--spacing-xs) text-(length:--size-base) text-(--font-error-base)";
12416
- /** Form model. Replaces the former `userName` model — note the lowercase `n`. */
12763
+ protected readonly css: {
12764
+ form: string;
12765
+ field: string;
12766
+ label: string;
12767
+ error: string;
12768
+ alert: string;
12769
+ actions: string;
12770
+ };
12771
+ protected readonly showError: typeof fieldShowsError;
12772
+ protected readonly errorKey: (field: FieldTree<string>) => string;
12773
+ /** Form model. Two-way bindable, so a wizard can carry the username over from a previous step. */
12417
12774
  readonly resetRequest: import("@angular/core").ModelSignal<PasswordResetRequest>;
12418
- /** `protected` and not `private`: a subclass template must be able to bind its own controls. */
12419
12775
  protected readonly resetForm: FieldTree<PasswordResetRequest, string | number, "writable">;
12420
- pending: import("@angular/core").WritableSignal<boolean>;
12421
- errorMsg: import("@angular/core").WritableSignal<string | null>;
12422
- /** A field shows its error only once the user has left it — never while typing the first time. */
12423
- protected showError<T>(field: FieldTree<T>): boolean;
12424
- /** Maps the first validation error to its translation key (`login.errors.required`, …). */
12425
- protected errorKey<T>(field: FieldTree<T>): string;
12776
+ readonly pending: import("@angular/core").WritableSignal<boolean>;
12777
+ readonly errorMsg: import("@angular/core").WritableSignal<string | null>;
12778
+ /** Whether a submission would run: valid form, nothing in flight. */
12779
+ readonly canSubmit: import("@angular/core").Signal<boolean>;
12780
+ constructor();
12426
12781
  /**
12427
12782
  * Submits the form. `submit()` marks every field as touched — revealing the validation
12428
12783
  * messages — and only runs the action when the form is valid.
@@ -12430,10 +12785,15 @@ export declare class ForgotPasswordComponent {
12430
12785
  submit(): Promise<boolean>;
12431
12786
  /** The submission itself. Only ever reached with a valid form. */
12432
12787
  private sendResetLink;
12433
- static ɵfac: i0.ɵɵFactoryDeclaration<ForgotPasswordComponent, never>;
12434
- static ɵcmp: i0.ɵɵComponentDeclaration<ForgotPasswordComponent, "forgot-password, ForgotPassword, forgotpassword", never, {
12435
- "surface": {
12436
- "alias": "surface";
12788
+ static ɵfac: i0.ɵɵFactoryDeclaration<ForgotPasswordFormComponent, never>;
12789
+ static ɵcmp: i0.ɵɵComponentDeclaration<ForgotPasswordFormComponent, "forgot-password-form, ForgotPasswordForm, forgotpasswordform", never, {
12790
+ "showActions": {
12791
+ "alias": "showActions";
12792
+ "required": false;
12793
+ "isSignal": true;
12794
+ };
12795
+ "showTitle": {
12796
+ "alias": "showTitle";
12437
12797
  "required": false;
12438
12798
  "isSignal": true;
12439
12799
  };
@@ -12486,10 +12846,25 @@ export declare class BookmarkButtonComponent {
12486
12846
  */
12487
12847
  tabIndex: import("@angular/core").InputSignal<number | undefined>;
12488
12848
  readonly article: import("@angular/core").InputSignal<Partial<Article>>;
12849
+ /**
12850
+ * Where the button files the document. `bookmarks` (default) is the historical behaviour: a click toggles
12851
+ * the bookmark. `collections` opts in to the collections: a click opens the "add to collection" panel, and the
12852
+ * button reads as pressed when the document is in at least one collection. Bookmarks are then left alone.
12853
+ */
12854
+ readonly target: import("@angular/core").InputSignal<"bookmarks" | "collections">;
12489
12855
  private readonly userSettingsStore;
12490
12856
  private readonly route;
12491
12857
  private readonly transloco;
12858
+ protected readonly panelId: string;
12859
+ protected readonly panelOpen: import("@angular/core").WritableSignal<boolean>;
12860
+ /** The panel only reads the id: a partial article is all it needs. */
12861
+ protected readonly panelArticles: import("@angular/core").Signal<Article[]>;
12862
+ private readonly trigger;
12863
+ private readonly panel;
12492
12864
  protected isBookmarked: import("@angular/core").Signal<boolean>;
12865
+ constructor();
12866
+ protected closePanel(): void;
12867
+ protected onPanelToggle(event: Event): void;
12493
12868
  bookmark(e: Event): Promise<void>;
12494
12869
  static ɵfac: i0.ɵɵFactoryDeclaration<BookmarkButtonComponent, never>;
12495
12870
  static ɵcmp: i0.ɵɵComponentDeclaration<BookmarkButtonComponent, "bookmark-button, bookmarkbutton, BookmarkButton", never, {
@@ -12518,6 +12893,11 @@ export declare class BookmarkButtonComponent {
12518
12893
  "required": true;
12519
12894
  "isSignal": true;
12520
12895
  };
12896
+ "target": {
12897
+ "alias": "target";
12898
+ "required": false;
12899
+ "isSignal": true;
12900
+ };
12521
12901
  }, {}, never, never, true, never>;
12522
12902
  }
12523
12903
  interface ListPanelDeleteEvent<T> {
@@ -12655,12 +13035,8 @@ export declare const BOOKMARKS_OPTIONS: BookmarksConfig;
12655
13035
  export declare const BOOKMARKS_CONFIG: InjectionToken<ListPanelConfig>;
12656
13036
  export declare class BookmarksComponent {
12657
13037
  floating: PopoverDirective | null;
12658
- private readonly selection;
12659
- private readonly queryService;
12660
13038
  private readonly userSettingsStore;
12661
- private readonly appStore;
12662
13039
  private readonly transloco;
12663
- private destroyRef;
12664
13040
  options: import("@angular/core").InputSignal<ListPanelConfig | undefined>;
12665
13041
  config: ListPanelConfig;
12666
13042
  protected idOf: (bookmark: Bookmark) => string;
@@ -12670,8 +13046,8 @@ export declare class BookmarksComponent {
12670
13046
  paginatedBookmarks: import("@angular/core").Signal<Bookmark[]>;
12671
13047
  hasMore: import("@angular/core").Signal<boolean>;
12672
13048
  constructor();
13049
+ private readonly openBookmark;
12673
13050
  onClick(bookmark: Bookmark): void;
12674
- private performSecondSearch;
12675
13051
  onDelete(event: ListPanelDeleteEvent<Bookmark>): void;
12676
13052
  loadMore(): void;
12677
13053
  static ɵfac: i0.ɵɵFactoryDeclaration<BookmarksComponent, never>;
@@ -12683,14 +13059,20 @@ export declare class BookmarksComponent {
12683
13059
  };
12684
13060
  }, {}, never, never, true, never>;
12685
13061
  }
13062
+ /**
13063
+ * Returns a function that opens a bookmark: it looks the document up by id (in the query the bookmark was made
13064
+ * from, then in the default query) and makes it the current article, or warns that it is outdated.
13065
+ *
13066
+ * Call it in an injection context. Shared by the bookmarks list and the collections manager.
13067
+ */
13068
+ export declare function injectOpenBookmark(): (bookmark: Pick<Bookmark, "id" | "queryName">) => void;
12686
13069
  export type CollectionsConfig = ListPanelConfig;
12687
13070
  export declare const COLLECTIONS_OPTIONS: CollectionsConfig;
12688
13071
  export declare const COLLECTIONS_CONFIG: InjectionToken<ListPanelConfig>;
12689
13072
  export declare class CollectionsComponent {
12690
13073
  floating: PopoverDirective | null;
12691
13074
  private readonly userSettingsStore;
12692
- private readonly queryParamsStore;
12693
- private readonly router;
13075
+ private readonly applyCollection;
12694
13076
  private readonly injector;
12695
13077
  options: import("@angular/core").InputSignal<ListPanelConfig | undefined>;
12696
13078
  config: ListPanelConfig;
@@ -12712,6 +13094,78 @@ export declare class CollectionsComponent {
12712
13094
  };
12713
13095
  }, {}, never, never, true, never>;
12714
13096
  }
13097
+ /**
13098
+ * Returns a function that applies a collection as a filter: it opens `/search` scoped to it (`?b=<name>`).
13099
+ *
13100
+ * The basket is written into `QueryParamsStore` **before** navigating: `patchState` is synchronous while
13101
+ * `router.navigate` is not, so the destination page must already see the basket when it fires its first query.
13102
+ * `syncUrl: false` because the navigation below already writes the URL, and `patch()` must not race it.
13103
+ *
13104
+ * Call it from an injection context.
13105
+ */
13106
+ export declare function injectApplyCollection(): (collection: Pick<Basket, "name">) => Promise<boolean>;
13107
+ type ViewMode = "grid" | "list";
13108
+ type ManagerTab = "collections" | "bookmarks";
13109
+ /**
13110
+ * Manages the user's collections. Two views, one component:
13111
+ *
13112
+ * - **the list**: every collection as a grid or a list, filtered by name; it can create one, delete one,
13113
+ * open one (a click) or apply one to the filters. Its content is centered and stops at `max-w-4xl`, however wide the
13114
+ * host is;
13115
+ * - **the detail** of a collection: its name (which can be changed), its documents (each can be previewed,
13116
+ * beside the list, or taken out of the collection), and the same "apply to the filters" action.
13117
+ *
13118
+ * "Apply to the filters" opens `/search` scoped to the collection (`?b=<name>`), see `injectApplyCollection`.
13119
+ * An application that wants to do it itself sets `navigateOnApply` to `false` and listens to `applied`.
13120
+ *
13121
+ * It reads `UserSettingsStore.baskets`; nothing needs to be passed in.
13122
+ */
13123
+ export declare class CollectionsManager {
13124
+ /**
13125
+ * Apply a collection by opening `/search` scoped to it. Set to `false` when the host does it itself
13126
+ * from `applied`.
13127
+ */
13128
+ readonly navigateOnApply: import("@angular/core").InputSignal<boolean>;
13129
+ /** The user asked to apply this collection to the filters (from the list or from its detail). */
13130
+ readonly applied: import("@angular/core").OutputEmitterRef<Basket>;
13131
+ private readonly userSettingsStore;
13132
+ private readonly applyCollection;
13133
+ private readonly injector;
13134
+ private readonly host;
13135
+ protected readonly collections: import("@angular/core").Signal<Basket[]>;
13136
+ protected readonly viewMode: import("@angular/core").WritableSignal<ViewMode>;
13137
+ private readonly activeTab;
13138
+ protected readonly bookmarkCount: import("@angular/core").Signal<number>;
13139
+ protected readonly hasBookmarks: import("@angular/core").Signal<boolean>;
13140
+ /** The tab shown: with no bookmark left the tab bar is gone, and the list of collections is all there is. */
13141
+ protected readonly tab: import("@angular/core").Signal<ManagerTab>;
13142
+ protected onTabChange(value: string | undefined): void;
13143
+ /** The filter box, bound to its own query signal. */
13144
+ protected readonly query: import("@angular/core").WritableSignal<string>;
13145
+ protected readonly searchForm: import("@angular/forms/signals").FieldTree<string, string | number, "writable">;
13146
+ protected readonly filtered: import("@angular/core").Signal<Basket[]>;
13147
+ /**
13148
+ * The collection whose detail is shown, by name: if it disappears (deleted elsewhere) the list comes back.
13149
+ * The detail reports a rename (`renamed`), which is how this follows the collection to its new name.
13150
+ */
13151
+ protected readonly openedName: import("@angular/core").WritableSignal<string | null>;
13152
+ protected readonly opened: import("@angular/core").Signal<Basket | undefined>;
13153
+ protected open(collection: Basket): void;
13154
+ protected closeDetail(): void;
13155
+ protected apply(collection: Basket): void;
13156
+ protected create(): void;
13157
+ protected remove(collection: Basket): void;
13158
+ static ɵfac: i0.ɵɵFactoryDeclaration<CollectionsManager, never>;
13159
+ static ɵcmp: i0.ɵɵComponentDeclaration<CollectionsManager, "CollectionsManager, collections-manager", never, {
13160
+ "navigateOnApply": {
13161
+ "alias": "navigateOnApply";
13162
+ "required": false;
13163
+ "isSignal": true;
13164
+ };
13165
+ }, {
13166
+ "applied": "applied";
13167
+ }, never, never, true, never>;
13168
+ }
12715
13169
  export declare class CollectionsDialog {
12716
13170
  protected readonly call: import("@sinequa/galactik").CallRef<Article | Article[], DialogResult>;
12717
13171
  readonly createInputElement: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>;
@@ -12757,6 +13211,37 @@ export declare class CollectionsDialog {
12757
13211
  }
12758
13212
  /** Imperative entry point: `await AddToCollection.call(articles)` → "dialog-yes"/"dialog-no"/event. */
12759
13213
  export declare const AddToCollection: import("@sinequa/galactik").Callable<Article | Article[], DialogResult>;
13214
+ /**
13215
+ * Names a new, empty collection. The name is checked as it is typed (a taken name shows at once),
13216
+ * an empty one only once a submission was attempted. Closes with `dialog-yes` once the collection exists.
13217
+ */
13218
+ export declare class CreateCollectionDialog {
13219
+ protected readonly call: import("@sinequa/galactik").CallRef<Record<string, never>, DialogResult>;
13220
+ private readonly dialog;
13221
+ private readonly nameInput;
13222
+ private readonly injector;
13223
+ private readonly userSettingsStore;
13224
+ private readonly transloco;
13225
+ protected readonly formId: string;
13226
+ protected readonly nameId: string;
13227
+ protected readonly errorId: string;
13228
+ private readonly model;
13229
+ protected readonly createForm: import("@angular/forms/signals").FieldTree<{
13230
+ name: string;
13231
+ }, string | number, "writable">;
13232
+ /**
13233
+ * Set when "Create" is pressed. An empty name is only reported then, not when the field loses the focus:
13234
+ * leaving it for "Cancel" or the close button is not an error. (A taken name shows as it is typed.)
13235
+ */
13236
+ protected readonly attempted: import("@angular/core").WritableSignal<boolean>;
13237
+ protected readonly nameError: import("@angular/core").Signal<"nameExists" | "nameRequired" | null>;
13238
+ constructor();
13239
+ private create;
13240
+ static ɵfac: i0.ɵɵFactoryDeclaration<CreateCollectionDialog, never>;
13241
+ static ɵcmp: i0.ɵɵComponentDeclaration<CreateCollectionDialog, "create-collection-dialog", never, {}, {}, never, never, true, never>;
13242
+ }
13243
+ /** Imperative entry point: `await CreateCollection.call({})` — resolves `dialog-yes` once created. */
13244
+ export declare const CreateCollection: import("@sinequa/galactik").Callable<Record<string, never>, DialogResult>;
12760
13245
  export interface DeleteCollectionArgs {
12761
13246
  collection: Basket;
12762
13247
  index: number;
@@ -12773,6 +13258,200 @@ export declare class DeleteCollectionDialog {
12773
13258
  }
12774
13259
  /** Imperative entry point: `await DeleteCollection.call({ collection, index })`. */
12775
13260
  export declare const DeleteCollection: import("@sinequa/galactik").Callable<DeleteCollectionArgs, DialogResult>;
13261
+ /** How many of the documents a collection already holds. */
13262
+ export type CollectionCoverage = "all" | "some" | "none";
13263
+ /** What the panel just did, shown in its header (and announced): an addition, a removal or a creation. */
13264
+ type PanelStatus = {
13265
+ kind: "added" | "removed" | "created";
13266
+ name: string;
13267
+ };
13268
+ /**
13269
+ * The "add to collection" panel opened from the multi-selection actions: a list of the user's
13270
+ * collections, each with a button that says where the selected documents stand in it — `+` to add
13271
+ * them, `✓` when they are all there (clicking it takes them out). A collection holding only part of
13272
+ * them keeps the `+` and says so under its name. A new collection is named in place, at the top of
13273
+ * the list (which stays on screen, dimmed), and appears there once created, ready for its `+`.
13274
+ *
13275
+ * The panel owns no positioning: the host shows it (in a popover, a sheet…) and listens to it.
13276
+ * - `done` — an addition has just been saved and confirmed in the header: the panel's
13277
+ * job is over, the host closes it. It fires about a second after the click, so the confirmation is
13278
+ * seen; a removal never ends the panel.
13279
+ * - `changed` — a collection was saved (added to, removed from, created): the host refreshes.
13280
+ * - `closeRequested` — the close button.
13281
+ *
13282
+ * Every change is saved at once, as in the dialog it replaces for the multi-selection: there is no
13283
+ * "Save" button to forget.
13284
+ */
13285
+ export declare class AddToCollectionPanelComponent {
13286
+ /** The documents to file. */
13287
+ readonly articles: import("@angular/core").InputSignal<Article[]>;
13288
+ /**
13289
+ * `add` (default): each collection offers `+` / `✓`, the documents stay where they are.
13290
+ * `move`: each collection offers a single "move here" button; the panel only adds the documents to the
13291
+ * chosen collection and reports `moved`. Taking them out of their source is the host's job.
13292
+ */
13293
+ readonly mode: import("@angular/core").InputSignal<"add" | "move">;
13294
+ /** `move` only: a collection left out of the list, the one the documents come from. */
13295
+ readonly exclude: import("@angular/core").InputSignal<string | undefined>;
13296
+ /** `move` only: the documents were added to this collection (its name). The host removes them from the source. */
13297
+ readonly moved: import("@angular/core").OutputEmitterRef<string>;
13298
+ /** An addition was saved and confirmed: the host closes the panel. Carries the collection's name. */
13299
+ readonly done: import("@angular/core").OutputEmitterRef<string>;
13300
+ /** A collection was saved (added to, removed from, created). */
13301
+ readonly changed: import("@angular/core").OutputEmitterRef<void>;
13302
+ /** The close button. */
13303
+ readonly closeRequested: import("@angular/core").OutputEmitterRef<void>;
13304
+ private readonly userSettingsStore;
13305
+ private readonly injector;
13306
+ protected readonly titleId: string;
13307
+ protected readonly nameId: string;
13308
+ protected readonly errorId: string;
13309
+ private readonly scrollElement;
13310
+ private readonly searchInput;
13311
+ private readonly nameInput;
13312
+ protected readonly collections: import("@angular/core").Signal<Basket[]>;
13313
+ /** Same threshold as the dialog: the field only earns its place past six collections. */
13314
+ protected readonly showSearch: import("@angular/core").Signal<boolean>;
13315
+ protected readonly count: import("@angular/core").Signal<number>;
13316
+ private readonly ids;
13317
+ protected readonly searchText: import("@angular/core").WritableSignal<string>;
13318
+ protected readonly searchField: import("@angular/forms/signals").FieldTree<string, string | number, "writable">;
13319
+ /** Collections created from this panel, newest first: they are listed at the top, where the name field was. */
13320
+ private readonly createdHere;
13321
+ protected readonly filteredCollections: import("@angular/core").Signal<Basket[]>;
13322
+ protected readonly status: import("@angular/core").WritableSignal<PanelStatus | null>;
13323
+ protected readonly creating: import("@angular/core").WritableSignal<boolean>;
13324
+ private readonly createModel;
13325
+ protected readonly createForm: import("@angular/forms/signals").FieldTree<{
13326
+ name: string;
13327
+ }, string | number, "writable">;
13328
+ /** Whether a submission was refused since the form was opened: a blur alone must not report an empty name. */
13329
+ private readonly submitAttempted;
13330
+ /**
13331
+ * The message under the name field. A taken name shows as it is typed — the user should not have
13332
+ * to try first — an empty one only once a submission was attempted, never on a mere blur (leaving
13333
+ * the field to cancel would otherwise flash it and shift the row under the pointer).
13334
+ */
13335
+ protected readonly nameError: import("@angular/core").Signal<"nameExists" | "nameRequired" | null>;
13336
+ /** A collection holding part of the documents says so on a second line: its row is taller. */
13337
+ protected readonly virtualizer: import("@tanstack/angular-virtual").AngularVirtualizer<HTMLElement, Element>;
13338
+ private doneTimer;
13339
+ constructor();
13340
+ coverageOf(collection: Basket | undefined): CollectionCoverage;
13341
+ /** How many of the documents the collection already holds. */
13342
+ heldIn(collection: Basket): number;
13343
+ /** `+` adds every document the collection lacks; `✓` takes them all out. */
13344
+ toggle(collection: Basket): Promise<void>;
13345
+ /** `move` mode: files every document in the collection, then tells the host, which empties the source. */
13346
+ protected move(collection: Basket): Promise<void>;
13347
+ protected startCreation(): void;
13348
+ /**
13349
+ * Leaves the name field for the list. On Escape, the key is kept from the popover around the panel,
13350
+ * which would otherwise close as well: one Escape undoes one thing.
13351
+ */
13352
+ protected cancelCreation(event?: Event): void;
13353
+ /**
13354
+ * Reached only with a valid name (see the schema). As in lexiQ, the collection is created empty and
13355
+ * takes its place at the top of the list, highlighted, with the focus on its `+`: filing the
13356
+ * documents in it is the user's next click, the same one as for any other collection.
13357
+ */
13358
+ private create;
13359
+ private confirmAdded;
13360
+ private nameTaken;
13361
+ protected onHostToggle(event: Event): void;
13362
+ private focusFirst;
13363
+ static ɵfac: i0.ɵɵFactoryDeclaration<AddToCollectionPanelComponent, never>;
13364
+ static ɵcmp: i0.ɵɵComponentDeclaration<AddToCollectionPanelComponent, "AddToCollectionPanel, add-to-collection-panel", never, {
13365
+ "articles": {
13366
+ "alias": "articles";
13367
+ "required": true;
13368
+ "isSignal": true;
13369
+ };
13370
+ "mode": {
13371
+ "alias": "mode";
13372
+ "required": false;
13373
+ "isSignal": true;
13374
+ };
13375
+ "exclude": {
13376
+ "alias": "exclude";
13377
+ "required": false;
13378
+ "isSignal": true;
13379
+ };
13380
+ }, {
13381
+ "moved": "moved";
13382
+ "done": "done";
13383
+ "changed": "changed";
13384
+ "closeRequested": "closeRequested";
13385
+ }, never, never, true, never>;
13386
+ }
13387
+ /** What `ChangePassword.call()` takes. */
13388
+ export interface ChangePasswordDialogProps {
13389
+ /** Account to log back in with after the change. Defaults to the signed-in user. */
13390
+ username?: string | null;
13391
+ }
13392
+ /**
13393
+ * The change-password form in a standard dialog. The form owns no button here (`[showActions]="false"`):
13394
+ * Cancel and Confirm live in the `DialogFooter`, and drive the form through its public API.
13395
+ */
13396
+ export declare class ChangePasswordDialogComponent {
13397
+ protected readonly call: import("@sinequa/galactik").CallRef<ChangePasswordDialogProps | undefined, DialogResult>;
13398
+ readonly dialog: import("@angular/core").Signal<DialogComponent | undefined>;
13399
+ private readonly focusFirstInput;
13400
+ constructor();
13401
+ static ɵfac: i0.ɵɵFactoryDeclaration<ChangePasswordDialogComponent, never>;
13402
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChangePasswordDialogComponent, "change-password-dialog", never, {}, {}, never, never, true, never>;
13403
+ }
13404
+ /** Imperative entry point: `await ChangePassword.call({ username })`. */
13405
+ export declare const ChangePassword: import("@sinequa/galactik").Callable<ChangePasswordDialogProps | undefined, DialogResult>;
13406
+ /**
13407
+ * The password-reset request form in a standard dialog. The form owns no button here
13408
+ * (`[showActions]="false"`): Cancel and Send live in the `DialogFooter`, and drive the form through its
13409
+ * public API. The promise resolves with `"dialog-confirm"` once the reset email was requested.
13410
+ */
13411
+ export declare class ForgotPasswordDialogComponent {
13412
+ protected readonly call: import("@sinequa/galactik").CallRef<void, DialogResult>;
13413
+ readonly dialog: import("@angular/core").Signal<DialogComponent | undefined>;
13414
+ private readonly focusFirstInput;
13415
+ constructor();
13416
+ static ɵfac: i0.ɵɵFactoryDeclaration<ForgotPasswordDialogComponent, never>;
13417
+ static ɵcmp: i0.ɵɵComponentDeclaration<ForgotPasswordDialogComponent, "forgot-password-dialog", never, {}, {}, never, never, true, never>;
13418
+ }
13419
+ /** Imperative entry point: `await ForgotPassword.call()`. */
13420
+ export declare const ForgotPassword: import("@sinequa/galactik").Callable<void, DialogResult>;
13421
+ /** The steps of the dialog. */
13422
+ type SignInStep = "sign-in" | "forgot-password" | "change-password";
13423
+ /**
13424
+ * The credentials form in a standard dialog, as a wizard: one dialog, whose content switches in place.
13425
+ *
13426
+ * - `sign-in` — the credentials form. "Forgot password" moves to `forgot-password`; an expired password
13427
+ * reported by the server moves to `change-password`.
13428
+ * - `forgot-password` — requests the reset email, then goes back to `sign-in`.
13429
+ * - `change-password` — changes the expired password, which also signs the user in with the new one.
13430
+ *
13431
+ * No form owns a button here (`[showActions]="false"`): the `DialogFooter` has the buttons of the current
13432
+ * step, and drives its form through the public API. Only the credentials form is shown: no external
13433
+ * handshake is ever started from here.
13434
+ *
13435
+ * Resolves with `"dialog-confirm"` once signed in (the application is initialized) and `"dialog-cancel"`
13436
+ * when dismissed.
13437
+ */
13438
+ export declare class SignInDialogComponent {
13439
+ protected readonly call: import("@sinequa/galactik").CallRef<void, DialogResult>;
13440
+ readonly dialog: import("@angular/core").Signal<DialogComponent | undefined>;
13441
+ protected readonly step: import("@angular/core").WritableSignal<SignInStep>;
13442
+ /** The account whose password expired, carried over to the change-password step. */
13443
+ protected readonly expiredUsername: import("@angular/core").WritableSignal<string | null>;
13444
+ protected readonly signInForm: import("@angular/core").Signal<SignInFormComponent | undefined>;
13445
+ protected readonly resetForm: import("@angular/core").Signal<ForgotPasswordFormComponent | undefined>;
13446
+ protected readonly passwordForm: import("@angular/core").Signal<ChangePasswordFormComponent | undefined>;
13447
+ private readonly focusFirstInput;
13448
+ constructor();
13449
+ protected onPasswordExpired(username: string): void;
13450
+ static ɵfac: i0.ɵɵFactoryDeclaration<SignInDialogComponent, never>;
13451
+ static ɵcmp: i0.ɵɵComponentDeclaration<SignInDialogComponent, "sign-in-dialog", never, {}, {}, never, never, true, never>;
13452
+ }
13453
+ /** Imperative entry point: `await SignIn.call()`. */
13454
+ export declare const SignIn: import("@sinequa/galactik").Callable<void, DialogResult>;
12776
13455
  /** Editable text/boolean fields of a converter (the app-filled `conversion` is excluded). */
12777
13456
  type ConverterField = "name" | "converter" | "format" | "primary" | "display" | "default";
12778
13457
  /** Groups the toggles are bucketed into, in display order. */
@@ -13088,7 +13767,7 @@ export declare class ExportDialog {
13088
13767
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
13089
13768
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
13090
13769
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
13091
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
13770
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
13092
13771
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
13093
13772
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
13094
13773
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -13278,6 +13957,7 @@ export declare class FeedbackDialogComponent {
13278
13957
  enabled?: boolean;
13279
13958
  data?: string[];
13280
13959
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
13960
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
13281
13961
  };
13282
13962
  previewMultiConversion?: boolean;
13283
13963
  persistFiltersAcrossTabs?: boolean;
@@ -13320,6 +14000,7 @@ export declare class FeedbackDialogComponent {
13320
14000
  enabled?: boolean;
13321
14001
  data?: string[];
13322
14002
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14003
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
13323
14004
  };
13324
14005
  previewMultiConversion?: boolean;
13325
14006
  persistFiltersAcrossTabs?: boolean;
@@ -13384,6 +14065,7 @@ export declare class FeedbackDialogComponent {
13384
14065
  enabled?: boolean;
13385
14066
  data?: string[];
13386
14067
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14068
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
13387
14069
  };
13388
14070
  previewMultiConversion?: boolean;
13389
14071
  persistFiltersAcrossTabs?: boolean;
@@ -13478,6 +14160,7 @@ export declare class FeedbackDialogComponent {
13478
14160
  enabled?: boolean;
13479
14161
  data?: string[];
13480
14162
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14163
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
13481
14164
  };
13482
14165
  previewMultiConversion?: boolean;
13483
14166
  persistFiltersAcrossTabs?: boolean;
@@ -13520,6 +14203,7 @@ export declare class FeedbackDialogComponent {
13520
14203
  enabled?: boolean;
13521
14204
  data?: string[];
13522
14205
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14206
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
13523
14207
  };
13524
14208
  previewMultiConversion?: boolean;
13525
14209
  persistFiltersAcrossTabs?: boolean;
@@ -13605,7 +14289,7 @@ export declare class SearchFeedbackComponent {
13605
14289
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
13606
14290
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
13607
14291
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
13608
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
14292
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
13609
14293
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
13610
14294
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
13611
14295
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -13995,7 +14679,7 @@ export declare class AggregationDateComponent {
13995
14679
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
13996
14680
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
13997
14681
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
13998
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
14682
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
13999
14683
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
14000
14684
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
14001
14685
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -14083,6 +14767,9 @@ export declare class AggregationDateComponent {
14083
14767
  readonly allowCustomRange: boolean;
14084
14768
  readonly transloco: TranslocoService;
14085
14769
  private readonly injector;
14770
+ private readonly breakpoints;
14771
+ /** Clear all / Apply: a 44px target on touch (a finger, no hover), one step smaller with a mouse. */
14772
+ protected readonly actionSize: import("@angular/core").Signal<"md" | "lg">;
14086
14773
  private readonly host;
14087
14774
  protected readonly selection: import("@angular/core").WritableSignal<boolean>;
14088
14775
  protected readonly validSelection: import("@angular/core").WritableSignal<boolean>;
@@ -14507,7 +15194,7 @@ export declare class AggregationTreeComponent {
14507
15194
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
14508
15195
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
14509
15196
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
14510
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
15197
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
14511
15198
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
14512
15199
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
14513
15200
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -14640,6 +15327,7 @@ export declare class AggregationTreeComponent {
14640
15327
  enabled?: boolean;
14641
15328
  data?: string[];
14642
15329
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15330
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14643
15331
  };
14644
15332
  previewMultiConversion?: boolean;
14645
15333
  persistFiltersAcrossTabs?: boolean;
@@ -14682,6 +15370,7 @@ export declare class AggregationTreeComponent {
14682
15370
  enabled?: boolean;
14683
15371
  data?: string[];
14684
15372
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15373
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14685
15374
  };
14686
15375
  previewMultiConversion?: boolean;
14687
15376
  persistFiltersAcrossTabs?: boolean;
@@ -14746,6 +15435,7 @@ export declare class AggregationTreeComponent {
14746
15435
  enabled?: boolean;
14747
15436
  data?: string[];
14748
15437
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15438
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14749
15439
  };
14750
15440
  previewMultiConversion?: boolean;
14751
15441
  persistFiltersAcrossTabs?: boolean;
@@ -14840,6 +15530,7 @@ export declare class AggregationTreeComponent {
14840
15530
  enabled?: boolean;
14841
15531
  data?: string[];
14842
15532
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15533
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14843
15534
  };
14844
15535
  previewMultiConversion?: boolean;
14845
15536
  persistFiltersAcrossTabs?: boolean;
@@ -14882,6 +15573,7 @@ export declare class AggregationTreeComponent {
14882
15573
  enabled?: boolean;
14883
15574
  data?: string[];
14884
15575
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15576
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
14885
15577
  };
14886
15578
  previewMultiConversion?: boolean;
14887
15579
  persistFiltersAcrossTabs?: boolean;
@@ -15382,7 +16074,7 @@ export declare class AggregationListComponent {
15382
16074
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
15383
16075
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
15384
16076
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
15385
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
16077
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
15386
16078
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
15387
16079
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
15388
16080
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -15515,6 +16207,7 @@ export declare class AggregationListComponent {
15515
16207
  enabled?: boolean;
15516
16208
  data?: string[];
15517
16209
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16210
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15518
16211
  };
15519
16212
  previewMultiConversion?: boolean;
15520
16213
  persistFiltersAcrossTabs?: boolean;
@@ -15527,19 +16220,7 @@ export declare class AggregationListComponent {
15527
16220
  light?: {
15528
16221
  small?: string;
15529
16222
  large?: string;
15530
- sidebar?
15531
- /**
15532
- * When `false`, applying or clearing filters updates the store without
15533
- * synchronizing the URL (no browser history entry, not shareable/restorable).
15534
- *
15535
- * @default true
15536
- */
15537
- /**
15538
- * When `false`, applying or clearing filters updates the store without
15539
- * synchronizing the URL (no browser history entry, not shareable/restorable).
15540
- *
15541
- * @default true
15542
- */ : string;
16223
+ sidebar?: string;
15543
16224
  };
15544
16225
  dark?: {
15545
16226
  small?: string;
@@ -15569,6 +16250,7 @@ export declare class AggregationListComponent {
15569
16250
  enabled?: boolean;
15570
16251
  data?: string[];
15571
16252
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16253
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15572
16254
  };
15573
16255
  previewMultiConversion?: boolean;
15574
16256
  persistFiltersAcrossTabs?: boolean;
@@ -15603,19 +16285,7 @@ export declare class AggregationListComponent {
15603
16285
  light?: {
15604
16286
  small?: string;
15605
16287
  large?: string;
15606
- sidebar?
15607
- /**
15608
- * When `false`, applying or clearing filters updates the store without
15609
- * synchronizing the URL (no browser history entry, not shareable/restorable).
15610
- *
15611
- * @default true
15612
- */
15613
- /**
15614
- * When `false`, applying or clearing filters updates the store without
15615
- * synchronizing the URL (no browser history entry, not shareable/restorable).
15616
- *
15617
- * @default true
15618
- */ : string;
16288
+ sidebar?: string;
15619
16289
  };
15620
16290
  dark?: {
15621
16291
  small?: string;
@@ -15645,6 +16315,7 @@ export declare class AggregationListComponent {
15645
16315
  enabled?: boolean;
15646
16316
  data?: string[];
15647
16317
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16318
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15648
16319
  };
15649
16320
  previewMultiConversion?: boolean;
15650
16321
  persistFiltersAcrossTabs?: boolean;
@@ -15739,6 +16410,7 @@ export declare class AggregationListComponent {
15739
16410
  enabled?: boolean;
15740
16411
  data?: string[];
15741
16412
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16413
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15742
16414
  };
15743
16415
  previewMultiConversion?: boolean;
15744
16416
  persistFiltersAcrossTabs?: boolean;
@@ -15751,19 +16423,7 @@ export declare class AggregationListComponent {
15751
16423
  light?: {
15752
16424
  small?: string;
15753
16425
  large?: string;
15754
- sidebar?
15755
- /**
15756
- * When `false`, applying or clearing filters updates the store without
15757
- * synchronizing the URL (no browser history entry, not shareable/restorable).
15758
- *
15759
- * @default true
15760
- */
15761
- /**
15762
- * When `false`, applying or clearing filters updates the store without
15763
- * synchronizing the URL (no browser history entry, not shareable/restorable).
15764
- *
15765
- * @default true
15766
- */ : string;
16426
+ sidebar?: string;
15767
16427
  };
15768
16428
  dark?: {
15769
16429
  small?: string;
@@ -15793,6 +16453,7 @@ export declare class AggregationListComponent {
15793
16453
  enabled?: boolean;
15794
16454
  data?: string[];
15795
16455
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16456
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
15796
16457
  };
15797
16458
  previewMultiConversion?: boolean;
15798
16459
  persistFiltersAcrossTabs?: boolean;
@@ -16056,6 +16717,7 @@ export declare class AggregationComponent {
16056
16717
  enabled?: boolean;
16057
16718
  data?: string[];
16058
16719
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16720
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16059
16721
  };
16060
16722
  previewMultiConversion?: boolean;
16061
16723
  persistFiltersAcrossTabs?: boolean;
@@ -16098,6 +16760,7 @@ export declare class AggregationComponent {
16098
16760
  enabled?: boolean;
16099
16761
  data?: string[];
16100
16762
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16763
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16101
16764
  };
16102
16765
  previewMultiConversion?: boolean;
16103
16766
  persistFiltersAcrossTabs?: boolean;
@@ -16162,6 +16825,7 @@ export declare class AggregationComponent {
16162
16825
  enabled?: boolean;
16163
16826
  data?: string[];
16164
16827
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16828
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16165
16829
  };
16166
16830
  previewMultiConversion?: boolean;
16167
16831
  persistFiltersAcrossTabs?: boolean;
@@ -16256,6 +16920,7 @@ export declare class AggregationComponent {
16256
16920
  enabled?: boolean;
16257
16921
  data?: string[];
16258
16922
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16923
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16259
16924
  };
16260
16925
  previewMultiConversion?: boolean;
16261
16926
  persistFiltersAcrossTabs?: boolean;
@@ -16298,6 +16963,7 @@ export declare class AggregationComponent {
16298
16963
  enabled?: boolean;
16299
16964
  data?: string[];
16300
16965
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16966
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
16301
16967
  };
16302
16968
  previewMultiConversion?: boolean;
16303
16969
  persistFiltersAcrossTabs?: boolean;
@@ -16730,6 +17396,9 @@ export declare class AggregationPanelComponent {
16730
17396
  private readonly searchBox;
16731
17397
  private readonly searchToggle;
16732
17398
  private readonly injector;
17399
+ private readonly breakpoints;
17400
+ /** Clear all / Apply: a 44px target on touch (a finger, no hover), one step smaller with a mouse. */
17401
+ protected readonly actionSize: import("@angular/core").Signal<"md" | "lg">;
16733
17402
  /** The galactik popover (`[popover]` / `[dropdown]`) this panel is shown in, if any — resolved through the injector tree. */
16734
17403
  protected readonly isInPopover: boolean;
16735
17404
  private static nextId;
@@ -16861,6 +17530,8 @@ export type AppliedFilterChip = {
16861
17530
  readonly field: string;
16862
17531
  /** Aggregation name, when the filter carries one. */
16863
17532
  readonly name?: string;
17533
+ /** Icon configured for the aggregation in the custom JSON (FontAwesome class string), when there is one. */
17534
+ readonly icon?: string;
16864
17535
  /** The value as stored. */
16865
17536
  readonly value: string;
16866
17537
  /** What to show. Pipe it through `syslang`. */
@@ -16937,6 +17608,7 @@ export declare function filterKey(leaf: LegacyFilter): string;
16937
17608
  */
16938
17609
  export declare class AppliedFiltersComponent {
16939
17610
  private readonly queryParamsStore;
17611
+ private readonly appStore;
16940
17612
  private static nextId;
16941
17613
  protected readonly listId: string;
16942
17614
  private readonly list;
@@ -16964,6 +17636,12 @@ export declare class AppliedFiltersComponent {
16964
17636
  readonly syncUrl: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
16965
17637
  /** Whether each chip is prefixed with its aggregation (or field) name. */
16966
17638
  readonly showField: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
17639
+ /**
17640
+ * Whether the aggregation's icon replaces its name in the prefix, when the custom JSON configures one.
17641
+ * The name remains the tooltip and the accessible text. Aggregations without an icon keep `<name>:`.
17642
+ * Only applies while `showField` is on.
17643
+ */
17644
+ readonly fieldIcon: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
16967
17645
  /**
16968
17646
  * Chip fill, passed straight to galactik's `tag`.
16969
17647
  *
@@ -17037,6 +17715,11 @@ export declare class AppliedFiltersComponent {
17037
17715
  "required": false;
17038
17716
  "isSignal": true;
17039
17717
  };
17718
+ "fieldIcon": {
17719
+ "alias": "fieldIcon";
17720
+ "required": false;
17721
+ "isSignal": true;
17722
+ };
17040
17723
  "variant": {
17041
17724
  "alias": "variant";
17042
17725
  "required": false;
@@ -17283,7 +17966,7 @@ export declare class FilterButtonComponent {
17283
17966
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
17284
17967
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
17285
17968
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
17286
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
17969
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
17287
17970
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
17288
17971
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
17289
17972
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -17416,6 +18099,7 @@ export declare class FilterButtonComponent {
17416
18099
  enabled?: boolean;
17417
18100
  data?: string[];
17418
18101
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18102
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
17419
18103
  };
17420
18104
  previewMultiConversion?: boolean;
17421
18105
  persistFiltersAcrossTabs?: boolean;
@@ -17458,6 +18142,7 @@ export declare class FilterButtonComponent {
17458
18142
  enabled?: boolean;
17459
18143
  data?: string[];
17460
18144
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18145
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
17461
18146
  };
17462
18147
  previewMultiConversion?: boolean;
17463
18148
  persistFiltersAcrossTabs?: boolean;
@@ -17522,6 +18207,7 @@ export declare class FilterButtonComponent {
17522
18207
  enabled?: boolean;
17523
18208
  data?: string[];
17524
18209
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18210
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
17525
18211
  };
17526
18212
  previewMultiConversion?: boolean;
17527
18213
  persistFiltersAcrossTabs?: boolean;
@@ -17616,6 +18302,7 @@ export declare class FilterButtonComponent {
17616
18302
  enabled?: boolean;
17617
18303
  data?: string[];
17618
18304
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18305
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
17619
18306
  };
17620
18307
  previewMultiConversion?: boolean;
17621
18308
  persistFiltersAcrossTabs?: boolean;
@@ -17658,6 +18345,7 @@ export declare class FilterButtonComponent {
17658
18345
  enabled?: boolean;
17659
18346
  data?: string[];
17660
18347
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18348
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
17661
18349
  };
17662
18350
  previewMultiConversion?: boolean;
17663
18351
  persistFiltersAcrossTabs?: boolean;
@@ -17980,6 +18668,7 @@ export declare class MoreButtonComponent {
17980
18668
  enabled?: boolean;
17981
18669
  data?: string[];
17982
18670
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18671
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
17983
18672
  };
17984
18673
  previewMultiConversion?: boolean;
17985
18674
  persistFiltersAcrossTabs?: boolean;
@@ -18022,6 +18711,7 @@ export declare class MoreButtonComponent {
18022
18711
  enabled?: boolean;
18023
18712
  data?: string[];
18024
18713
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18714
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18025
18715
  };
18026
18716
  previewMultiConversion?: boolean;
18027
18717
  persistFiltersAcrossTabs?: boolean;
@@ -18086,6 +18776,7 @@ export declare class MoreButtonComponent {
18086
18776
  enabled?: boolean;
18087
18777
  data?: string[];
18088
18778
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18779
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18089
18780
  };
18090
18781
  previewMultiConversion?: boolean;
18091
18782
  persistFiltersAcrossTabs?: boolean;
@@ -18180,6 +18871,7 @@ export declare class MoreButtonComponent {
18180
18871
  enabled?: boolean;
18181
18872
  data?: string[];
18182
18873
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18874
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18183
18875
  };
18184
18876
  previewMultiConversion?: boolean;
18185
18877
  persistFiltersAcrossTabs?: boolean;
@@ -18222,6 +18914,7 @@ export declare class MoreButtonComponent {
18222
18914
  enabled?: boolean;
18223
18915
  data?: string[];
18224
18916
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18917
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18225
18918
  };
18226
18919
  previewMultiConversion?: boolean;
18227
18920
  persistFiltersAcrossTabs?: boolean;
@@ -18274,7 +18967,7 @@ export declare class MoreButtonComponent {
18274
18967
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
18275
18968
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
18276
18969
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
18277
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
18970
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
18278
18971
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
18279
18972
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
18280
18973
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -18757,6 +19450,7 @@ export declare class FiltersBarComponent {
18757
19450
  enabled?: boolean;
18758
19451
  data?: string[];
18759
19452
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19453
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18760
19454
  };
18761
19455
  previewMultiConversion?: boolean;
18762
19456
  persistFiltersAcrossTabs?: boolean;
@@ -18799,6 +19493,7 @@ export declare class FiltersBarComponent {
18799
19493
  enabled?: boolean;
18800
19494
  data?: string[];
18801
19495
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19496
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18802
19497
  };
18803
19498
  previewMultiConversion?: boolean;
18804
19499
  persistFiltersAcrossTabs?: boolean;
@@ -18863,6 +19558,7 @@ export declare class FiltersBarComponent {
18863
19558
  enabled?: boolean;
18864
19559
  data?: string[];
18865
19560
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19561
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18866
19562
  };
18867
19563
  previewMultiConversion?: boolean;
18868
19564
  persistFiltersAcrossTabs?: boolean;
@@ -18957,6 +19653,7 @@ export declare class FiltersBarComponent {
18957
19653
  enabled?: boolean;
18958
19654
  data?: string[];
18959
19655
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19656
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
18960
19657
  };
18961
19658
  previewMultiConversion?: boolean;
18962
19659
  persistFiltersAcrossTabs?: boolean;
@@ -18999,6 +19696,7 @@ export declare class FiltersBarComponent {
18999
19696
  enabled?: boolean;
19000
19697
  data?: string[];
19001
19698
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19699
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19002
19700
  };
19003
19701
  previewMultiConversion?: boolean;
19004
19702
  persistFiltersAcrossTabs?: boolean;
@@ -19060,7 +19758,7 @@ export declare class FiltersBarComponent {
19060
19758
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
19061
19759
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
19062
19760
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
19063
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
19761
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
19064
19762
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
19065
19763
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
19066
19764
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -19347,7 +20045,7 @@ type FiltersTab = "all" | "quick";
19347
20045
  /**
19348
20046
  * The filters panel: the facets of the search, and the quick filters of the user, in one card-sized column.
19349
20047
  *
19350
- * "All" holds the facets (`<aside-filters>`, driven by the application's filters configuration) with a field that narrows them by
20048
+ * "All" holds every configured facet (`<aside-filters>`, whatever its `position`: LexiQ has no left/right notion) with a field that narrows them by
19351
20049
  * name, the count of documents, and a button that saves the filters applied right now as a quick filter (a card under the button
19352
20050
  * asks for its name). "Quick Filters" is the list of the `<quick-filters>` pill, inline (`<quick-filters-list>`): one line per quick filter, with the
19353
20051
  * count of its filters — hovering it shows them as tags — and a cross that deletes it. A click on a quick filter replaces **all** the
@@ -19370,6 +20068,7 @@ export declare class FiltersPanelComponent {
19370
20068
  readonly closed: import("@angular/core").OutputEmitterRef<void>;
19371
20069
  private readonly appStore;
19372
20070
  private readonly aggregationsStore;
20071
+ private readonly aggregationsService;
19373
20072
  private readonly queryParamsStore;
19374
20073
  private readonly userSettingsStore;
19375
20074
  private readonly transloco;
@@ -19385,11 +20084,13 @@ export declare class FiltersPanelComponent {
19385
20084
  private readonly nameInput;
19386
20085
  private readonly saveButton;
19387
20086
  /**
19388
- * The facets whose name contains the query, as the names `<aside-filters [aggregations]>` takes.
19389
- * Empty query → the component's own configuration-driven list (the input is left empty).
19390
- *
19391
- * An explicit list bypasses the `position` and "hidden" rules of that configuration, so the same two
19392
- * rules are applied here first.
20087
+ * Every configured facet the user may see: the `position` of the configuration (`left` / `both`) does not apply here — the panel
20088
+ * is the only place the facets live — but the authorizations and the admin "hidden" rule do.
20089
+ */
20090
+ private readonly facets;
20091
+ /**
20092
+ * The names of the facets whose name contains the query (all of them when it is empty), as `<aside-filters [aggregations]>` takes them.
20093
+ * The list is always explicit: an empty one would make `<aside-filters>` fall back on its own `position`-driven configuration.
19393
20094
  */
19394
20095
  protected readonly matching: import("@angular/core").Signal<string[]>;
19395
20096
  protected selectTab(values: readonly string[]): void;
@@ -19494,6 +20195,7 @@ export declare class LabelService {
19494
20195
  enabled?: boolean;
19495
20196
  data?: string[];
19496
20197
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20198
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19497
20199
  };
19498
20200
  previewMultiConversion?: boolean;
19499
20201
  persistFiltersAcrossTabs?: boolean;
@@ -19536,6 +20238,7 @@ export declare class LabelService {
19536
20238
  enabled?: boolean;
19537
20239
  data?: string[];
19538
20240
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20241
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19539
20242
  };
19540
20243
  previewMultiConversion?: boolean;
19541
20244
  persistFiltersAcrossTabs?: boolean;
@@ -19600,6 +20303,7 @@ export declare class LabelService {
19600
20303
  enabled?: boolean;
19601
20304
  data?: string[];
19602
20305
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20306
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19603
20307
  };
19604
20308
  previewMultiConversion?: boolean;
19605
20309
  persistFiltersAcrossTabs?: boolean;
@@ -19694,6 +20398,7 @@ export declare class LabelService {
19694
20398
  enabled?: boolean;
19695
20399
  data?: string[];
19696
20400
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20401
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19697
20402
  };
19698
20403
  previewMultiConversion?: boolean;
19699
20404
  persistFiltersAcrossTabs?: boolean;
@@ -19736,6 +20441,7 @@ export declare class LabelService {
19736
20441
  enabled?: boolean;
19737
20442
  data?: string[];
19738
20443
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20444
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
19739
20445
  };
19740
20446
  previewMultiConversion?: boolean;
19741
20447
  persistFiltersAcrossTabs?: boolean;
@@ -20038,6 +20744,7 @@ export declare class HistoryPanelComponent {
20038
20744
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
20039
20745
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
20040
20746
  unbookmark: (id: string) => Promise<void>;
20747
+ unbookmarkMany: (ids: string[]) => Promise<void>;
20041
20748
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
20042
20749
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
20043
20750
  isFavoriteSearch: (search: Pick<SearchItem, "label" | "display">) => boolean;
@@ -20538,7 +21245,7 @@ export declare class SearchBoxComponent {
20538
21245
  relevanceTransforms?: import("@angular/core").Signal<string | undefined> | undefined;
20539
21246
  removeDuplicates?: import("@angular/core").Signal<boolean | undefined> | undefined;
20540
21247
  queryId?: import("@angular/core").Signal<string | undefined> | undefined;
20541
- aggregations?: import("@angular/core").Signal<Record<string, import("@sinequa/atomic").AggregationOptions> | string[] | undefined> | undefined;
21248
+ aggregations?: import("@angular/core").Signal<string[] | Record<string, import("@sinequa/atomic").AggregationOptions> | undefined> | undefined;
20542
21249
  orderBy?: import("@angular/core").Signal<string | undefined> | undefined;
20543
21250
  groupBy?: import("@angular/core").Signal<string | undefined> | undefined;
20544
21251
  neuralSearch?: import("@angular/core").Signal<boolean | undefined> | undefined;
@@ -20671,6 +21378,7 @@ export declare class SearchBoxComponent {
20671
21378
  enabled?: boolean;
20672
21379
  data?: string[];
20673
21380
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21381
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20674
21382
  };
20675
21383
  previewMultiConversion?: boolean;
20676
21384
  persistFiltersAcrossTabs?: boolean;
@@ -20713,6 +21421,7 @@ export declare class SearchBoxComponent {
20713
21421
  enabled?: boolean;
20714
21422
  data?: string[];
20715
21423
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21424
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20716
21425
  };
20717
21426
  previewMultiConversion?: boolean;
20718
21427
  persistFiltersAcrossTabs?: boolean;
@@ -20777,6 +21486,7 @@ export declare class SearchBoxComponent {
20777
21486
  enabled?: boolean;
20778
21487
  data?: string[];
20779
21488
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21489
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20780
21490
  };
20781
21491
  previewMultiConversion?: boolean;
20782
21492
  persistFiltersAcrossTabs?: boolean;
@@ -20871,6 +21581,7 @@ export declare class SearchBoxComponent {
20871
21581
  enabled?: boolean;
20872
21582
  data?: string[];
20873
21583
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21584
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20874
21585
  };
20875
21586
  previewMultiConversion?: boolean;
20876
21587
  persistFiltersAcrossTabs?: boolean;
@@ -20913,6 +21624,7 @@ export declare class SearchBoxComponent {
20913
21624
  enabled?: boolean;
20914
21625
  data?: string[];
20915
21626
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21627
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
20916
21628
  };
20917
21629
  previewMultiConversion?: boolean;
20918
21630
  persistFiltersAcrossTabs?: boolean;
@@ -20957,6 +21669,7 @@ export declare class SearchBoxComponent {
20957
21669
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
20958
21670
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
20959
21671
  unbookmark: (id: string) => Promise<void>;
21672
+ unbookmarkMany: (ids: string[]) => Promise<void>;
20960
21673
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
20961
21674
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
20962
21675
  isFavoriteSearch: (search: Pick<SearchItem, "label" | "display">) => boolean;
@@ -21268,6 +21981,7 @@ export declare class RecentSearchesComponent {
21268
21981
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
21269
21982
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
21270
21983
  unbookmark: (id: string) => Promise<void>;
21984
+ unbookmarkMany: (ids: string[]) => Promise<void>;
21271
21985
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
21272
21986
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
21273
21987
  isFavoriteSearch: (search: Pick<SearchItem, "label" | "display">) => boolean;
@@ -21393,6 +22107,7 @@ export declare class SavedSearchPopover {
21393
22107
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
21394
22108
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
21395
22109
  unbookmark: (id: string) => Promise<void>;
22110
+ unbookmarkMany: (ids: string[]) => Promise<void>;
21396
22111
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
21397
22112
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
21398
22113
  isFavoriteSearch: (search: Pick<SearchItem, "label" | "display">) => boolean;
@@ -21489,6 +22204,7 @@ export declare class SavedSearchesComponent {
21489
22204
  updateBookmarks: (bookmarks: import("@sinequa/atomic-angular").UserSettingsState["bookmarks"], auditEvents?: import("@sinequa/atomic").AuditEvents) => Promise<void>;
21490
22205
  bookmark: (article: import("@sinequa/atomic").Article, queryName?: string) => Promise<void>;
21491
22206
  unbookmark: (id: string) => Promise<void>;
22207
+ unbookmarkMany: (ids: string[]) => Promise<void>;
21492
22208
  isBookmarked: (article: Partial<import("@sinequa/atomic").Article>) => boolean;
21493
22209
  toggleBookmark: (article: import("@sinequa/atomic").Article) => Promise<void>;
21494
22210
  isFavoriteSearch: (search: Pick<SearchItem, "label" | "display">) => boolean;
@@ -21768,8 +22484,12 @@ export declare class SettingsShortcutsPanelComponent {
21768
22484
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingsShortcutsPanelComponent, never>;
21769
22485
  static ɵcmp: i0.ɵɵComponentDeclaration<SettingsShortcutsPanelComponent, "settings-shortcuts-panel", never, {}, {}, never, never, true, never>;
21770
22486
  }
21771
- /** The two buckets of a `UserProfile`: the configured fields, and the free-form ones. */
21772
- export type UserProfileCategory = "data" | "customData";
22487
+ /**
22488
+ * The buckets of a `UserProfile`: the configured fields, the free-form ones, and the private free-form
22489
+ * ones. `privateCustomData` is only returned for the caller's own profile and only ever goes through the
22490
+ * private endpoints.
22491
+ */
22492
+ export type UserProfileCategory = "data" | "customData" | "privateCustomData";
21773
22493
  /**
21774
22494
  * Model of the profile form.
21775
22495
  *
@@ -21785,6 +22505,7 @@ export type UserProfileCategory = "data" | "customData";
21785
22505
  export interface UserProfileFormModel {
21786
22506
  data: Record<string, string>;
21787
22507
  customData: Record<string, string>;
22508
+ privateCustomData: Record<string, string>;
21788
22509
  }
21789
22510
  export declare class UserProfileFormComponent {
21790
22511
  /**
@@ -21907,6 +22628,7 @@ export declare class UserProfileFormComponent {
21907
22628
  enabled?: boolean;
21908
22629
  data?: string[];
21909
22630
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22631
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21910
22632
  };
21911
22633
  previewMultiConversion?: boolean;
21912
22634
  persistFiltersAcrossTabs?: boolean;
@@ -21949,6 +22671,7 @@ export declare class UserProfileFormComponent {
21949
22671
  enabled?: boolean;
21950
22672
  data?: string[];
21951
22673
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22674
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
21952
22675
  };
21953
22676
  previewMultiConversion?: boolean;
21954
22677
  persistFiltersAcrossTabs?: boolean;
@@ -22013,6 +22736,7 @@ export declare class UserProfileFormComponent {
22013
22736
  enabled?: boolean;
22014
22737
  data?: string[];
22015
22738
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22739
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22016
22740
  };
22017
22741
  previewMultiConversion?: boolean;
22018
22742
  persistFiltersAcrossTabs?: boolean;
@@ -22107,6 +22831,7 @@ export declare class UserProfileFormComponent {
22107
22831
  enabled?: boolean;
22108
22832
  data?: string[];
22109
22833
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22834
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22110
22835
  };
22111
22836
  previewMultiConversion?: boolean;
22112
22837
  persistFiltersAcrossTabs?: boolean;
@@ -22149,6 +22874,7 @@ export declare class UserProfileFormComponent {
22149
22874
  enabled?: boolean;
22150
22875
  data?: string[];
22151
22876
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22877
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22152
22878
  };
22153
22879
  previewMultiConversion?: boolean;
22154
22880
  persistFiltersAcrossTabs?: boolean;
@@ -22186,7 +22912,7 @@ export declare class UserProfileFormComponent {
22186
22912
  * pairs for contrast (it is the `light-accent` button): a neutral background with a neutral text was
22187
22913
  * unreadable.
22188
22914
  */
22189
- protected readonly chipClass = "inline-flex items-center rounded-(--radius-rounded) bg-(--bg-accent-base-alt) px-(--spacing-2xs) text-(length:--size-sm) font-medium text-(--font-accent-base)";
22915
+ protected readonly chipClass = "inline-flex items-center gap-(--spacing-3xs) rounded-(--radius-rounded) bg-(--bg-accent-base-alt) px-(--spacing-2xs) text-(length:--size-sm) font-medium text-(--font-accent-base)";
22190
22916
  /**
22191
22917
  * Polite announcement of what just happened — entering edit mode, saving, cancelling, deleting.
22192
22918
  *
@@ -22204,17 +22930,26 @@ export declare class UserProfileFormComponent {
22204
22930
  protected readonly formKeys: Signal<string[]>;
22205
22931
  protected readonly allowProfilePhoto: Signal<boolean>;
22206
22932
  private readonly customDataConfig;
22933
+ private readonly privateCustomDataConfig;
22207
22934
  /**
22208
- * The rows of the free-form properties.
22935
+ * The rows of the free-form properties of a bucket.
22209
22936
  *
22210
- * Users only edit values, and the structure is the administrator's, in the custom JSON. So a property
22211
- * that is an object — by its default, or by what the profile holds — is not one row but one row per
22212
- * leaf (`workingHours › start`), each read-only: the form shows the values without any way to change
22213
- * the shape. A scalar is an editable row, and an array a read-only one.
22937
+ * A property is a `/`-separated path (`agent/favorites`), and the structure is the administrator's, in
22938
+ * the custom JSON. A property that is an object — by its default, or by what the profile holds — is not
22939
+ * one row but one row per leaf (`workingHours › start`). A leaf and a scalar are editable rows, and an
22940
+ * array a read-only one. A row is written at its path, the rest of the bucket untouched.
22214
22941
  */
22942
+ private rowsOf;
22215
22943
  private readonly customRows;
22944
+ private readonly privateRows;
22216
22945
  protected readonly customData: Signal<string[]>;
22946
+ protected readonly privateCustomData: Signal<string[]>;
22217
22947
  private readonly customRowIndex;
22948
+ private readonly privateRowIndex;
22949
+ /** The row of a free-form property; `undefined` for a `data` key. */
22950
+ private rowOf;
22951
+ /** Where the profile holds a property, from the root of its bucket. */
22952
+ private pathOf;
22218
22953
  /**
22219
22954
  * The editable properties, flattened in display order — one row per entry.
22220
22955
  *
@@ -22229,19 +22964,33 @@ export declare class UserProfileFormComponent {
22229
22964
  translated: boolean;
22230
22965
  }[]>;
22231
22966
  /**
22232
- * The rows grouped in the two cards of the form — the configured fields, then the free-form ones.
22233
- * A group with no row is left out, so a profile without custom properties shows a single card.
22967
+ * The rows grouped in the cards of the form — the configured fields, the free-form ones, then the private
22968
+ * ones. A group with no row is left out, so a profile without custom properties shows a single card, and
22969
+ * one without `privateCustomData` shows no private card. `visibility` says who can see the card's values.
22234
22970
  */
22235
22971
  protected readonly sections: Signal<{
22236
- id: string;
22972
+ id: "information" | "preferences" | "private";
22973
+ visibility: "public" | "private";
22237
22974
  rows: {
22238
22975
  category: UserProfileCategory;
22239
22976
  key: string;
22240
22977
  translated: boolean;
22241
22978
  }[];
22242
22979
  }[]>;
22980
+ /** Whether the sections are tabs: a profile with a single block shows its card alone, with no tab. */
22981
+ protected readonly tabbed: Signal<boolean>;
22982
+ /**
22983
+ * The tab being looked at, one of the `sections()`. It falls back on the first one when the section it held
22984
+ * is gone (the configuration changed), and is otherwise kept.
22985
+ */
22986
+ protected readonly activeSection: import("@angular/core").WritableSignal<string | undefined>;
22243
22987
  protected readonly initials: Signal<string>;
22244
22988
  protected readonly username: Signal<string | null>;
22989
+ /**
22990
+ * The properties deleted since the profile was loaded, `"<category>.<key>"`, until they are saved again. Their
22991
+ * local value is an empty string, so the value alone cannot tell "deleted" from "saved as empty".
22992
+ */
22993
+ private readonly deletedProperties;
22245
22994
  /** Id of the property being edited, `"<category>.<key>"` — at most one at a time. */
22246
22995
  protected readonly propertyToEdit: import("@angular/core").WritableSignal<string | undefined>;
22247
22996
  readonly changingPassword: import("@angular/core").WritableSignal<boolean>;
@@ -22281,6 +23030,11 @@ export declare class UserProfileFormComponent {
22281
23030
  protected showError(field: FieldTree<string> | undefined): boolean;
22282
23031
  /** Maps the first validation error to its translation key (`userProfile.errors.required`, …). */
22283
23032
  protected errorKey(field: FieldTree<string> | undefined): string;
23033
+ /**
23034
+ * Switches tab. An edit in progress is discarded: its field is about to be hidden, and a draft left behind a
23035
+ * tab would still hold the form in edit mode.
23036
+ */
23037
+ protected onSectionChange(id: string | undefined): void;
22284
23038
  /** Whether `key` is the property currently being edited. */
22285
23039
  protected isEditing(category: UserProfileCategory, key: string): boolean;
22286
23040
  /**
@@ -22292,7 +23046,7 @@ export declare class UserProfileFormComponent {
22292
23046
  protected getDataValue(category: UserProfileCategory, key: string): string | undefined;
22293
23047
  /** The default of a custom property, shown while the profile holds no value for it. */
22294
23048
  private defaultValue;
22295
- /** Whether a row is a leaf of an object: shown, never edited. */
23049
+ /** Whether a row is nested: a leaf of an object, or a `/`-separated path. */
22296
23050
  protected isLeaf(category: UserProfileCategory, key: string): boolean;
22297
23051
  /** What the profile holds for a property — at its path, for a leaf. */
22298
23052
  private storedValue;
@@ -22303,8 +23057,11 @@ export declare class UserProfileFormComponent {
22303
23057
  protected isBoolean(category: UserProfileCategory, key: string): boolean;
22304
23058
  /** Whether a boolean property is on. */
22305
23059
  protected booleanValue(category: UserProfileCategory, key: string): boolean;
22306
- /** Whether a property holds an array, which the form shows but never edits. */
22307
- protected isReadOnlyValue(category: UserProfileCategory, key: string): boolean;
23060
+ /**
23061
+ * Whether a property holds an array. It is shown as tags and edited as JSON, in a text area, since its items
23062
+ * can be anything: values, objects, arrays.
23063
+ */
23064
+ protected isArray(category: UserProfileCategory, key: string): boolean;
22308
23065
  /** The tags of an array property: a string as is, anything else as its JSON, a repeated value once. */
22309
23066
  protected arrayTags(category: UserProfileCategory, key: string): string[];
22310
23067
  /** The stored value of a property, else its default — what the field shows when it is not being edited. */
@@ -22347,6 +23104,8 @@ export declare class UserProfileFormComponent {
22347
23104
  * (Transloco answers a missing entry with the path it was asked for).
22348
23105
  */
22349
23106
  protected labelFor(category: UserProfileCategory, key: string): string;
23107
+ /** A free-form key, translated under `userProfile.<category>.<key>` when the application provides it; the key otherwise. */
23108
+ private translatedName;
22350
23109
  /** Whether a property shows its default: the profile holds no value for it and the administrator gave one. */
22351
23110
  protected isDefault(category: UserProfileCategory, key: string): boolean;
22352
23111
  /** Whether a property has just been saved — its row shows a confirmation for a few seconds. */
@@ -22395,12 +23154,26 @@ export declare class UserProfileFormComponent {
22395
23154
  * back before the next render never changes it.
22396
23155
  */
22397
23156
  protected onToggleBoolean(category: UserProfileCategory, key: string, checked: boolean, toggle: SwitchComponent): Promise<void>;
23157
+ /** A path as the API takes it: the bare name for one segment, the segments otherwise (a name may hold a `/`). */
23158
+ private endpointPath;
22398
23159
  /**
22399
23160
  * Patches a single property and folds the response back into the stored profile.
22400
23161
  *
23162
+ * The server does not create the nodes on the way (it answers 404): the write is made at the first missing
23163
+ * one, carrying the rest of the path (see `writeTarget`). A private property only goes through the private
23164
+ * endpoint, never the public one.
23165
+ *
22401
23166
  * @returns whether the property was persisted.
22402
23167
  */
22403
23168
  private patchProperty;
23169
+ /**
23170
+ * Folds the answer of a PATCH back into the stored profile, so the form shows what was just saved.
23171
+ *
23172
+ * The answer is the value alone — the string for `data`, any JSON value for `customData` — since the
23173
+ * profile routes answer with the addressed resource and nothing else (ES-34373). A server that still
23174
+ * answers with the whole profile (`{ data, customData, … }`) keeps working: it is merged as before.
23175
+ */
23176
+ private foldSavedValue;
22404
23177
  /**
22405
23178
  * Reads the picked image and stores it as the profile photo.
22406
23179
  *
@@ -22425,6 +23198,17 @@ export declare class UserProfileFormComponent {
22425
23198
  * @returns The guard function.
22426
23199
  */
22427
23200
  export declare function AuthGuard(): CanActivateFn;
23201
+ /**
23202
+ * Returns a guard function that lets a route match only when the Agent store is available
23203
+ * (`features.isAvailable.agentStore` of `GET /api/v2/version`, see {@link LicenseCapabilitiesService}).
23204
+ *
23205
+ * It is a `canMatch` guard: when the store is not available, the router falls through to the next route
23206
+ * that matches the URL (typically the catch-all), so neither the route nor its lazy chunk is reachable.
23207
+ * It only reads a signal: load it first with `LicenseCapabilitiesService.load()`, before the first
23208
+ * navigation (an application initializer), otherwise the capability reads as `false`.
23209
+ * @returns The guard function.
23210
+ */
23211
+ export declare function AgentStoreGuard(): CanMatchFn;
22428
23212
  /**
22429
23213
  * Intercepts HTTP requests to add audit information if the request URL includes the API path.
22430
23214
  *
@@ -22627,6 +23411,7 @@ export declare class SourceIconPipe implements PipeTransform {
22627
23411
  enabled?: boolean;
22628
23412
  data?: string[];
22629
23413
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
23414
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22630
23415
  };
22631
23416
  previewMultiConversion?: boolean;
22632
23417
  persistFiltersAcrossTabs?: boolean;
@@ -22669,6 +23454,7 @@ export declare class SourceIconPipe implements PipeTransform {
22669
23454
  enabled?: boolean;
22670
23455
  data?: string[];
22671
23456
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
23457
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22672
23458
  };
22673
23459
  previewMultiConversion?: boolean;
22674
23460
  persistFiltersAcrossTabs?: boolean;
@@ -22733,6 +23519,7 @@ export declare class SourceIconPipe implements PipeTransform {
22733
23519
  enabled?: boolean;
22734
23520
  data?: string[];
22735
23521
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
23522
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22736
23523
  };
22737
23524
  previewMultiConversion?: boolean;
22738
23525
  persistFiltersAcrossTabs?: boolean;
@@ -22827,6 +23614,7 @@ export declare class SourceIconPipe implements PipeTransform {
22827
23614
  enabled?: boolean;
22828
23615
  data?: string[];
22829
23616
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
23617
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22830
23618
  };
22831
23619
  previewMultiConversion?: boolean;
22832
23620
  persistFiltersAcrossTabs?: boolean;
@@ -22869,6 +23657,7 @@ export declare class SourceIconPipe implements PipeTransform {
22869
23657
  enabled?: boolean;
22870
23658
  data?: string[];
22871
23659
  customData?: import("@sinequa/atomic-angular").CustomDataEntry[];
23660
+ privateCustomData?: import("@sinequa/atomic-angular").CustomDataEntry[];
22872
23661
  };
22873
23662
  previewMultiConversion?: boolean;
22874
23663
  persistFiltersAcrossTabs?: boolean;
@@ -23076,7 +23865,7 @@ export declare function injectAtomicClient(): AtomicClient;
23076
23865
  *
23077
23866
  * Only HTTP statuses `400`, `403`, `500` and `503` produce a toast, plus the explicit "Cannot override
23078
23867
  * user" message for an impersonation rejected with a `401`. `404`, `429`, `502`, `504` and any failure
23079
- * without an HTTP response (network error) stay silent, as does everything on `api/v1/preview` and a
23868
+ * without an HTTP response (network error) stay silent, as do `api/v1/preview` and `api/v2/security/password/change` (surfaced by their own UI) and a
23080
23869
  * `400` on `api/v2/user-profile`.
23081
23870
  *
23082
23871
  * The library renders nothing: `notify.error(...)` only dispatches a `notification` `CustomEvent` on
@@ -23257,10 +24046,14 @@ export type SessionExpiryOptions = {
23257
24046
  /**
23258
24047
  * Action of the "about to expire" notification: lets the user keep working without losing the session.
23259
24048
  *
23260
- * Defaults to one light authenticated request (`principal`). The platform has no refresh endpoint: it only
23261
- * renews the token as a side effect of a request, and only when the server's JSON Web Token auto-refresh
23262
- * is enabled and the token's maximum lifetime is not reached. When the expiry did not move afterwards,
23263
- * `onReconnect` runs instead, so the action never leaves the user believing the session was extended.
24049
+ * Defaults to renewing the session through `security.webtoken`: it needs no credentials as long as the JSON
24050
+ * Web Token cookie is still valid, and renews it whatever the way the user signed in. It cannot revive a
24051
+ * session that already expired, and a bearer access token whose JSON method rules exclude `webtoken` is
24052
+ * refused. In both cases, and when the server returns no token, one light authenticated request
24053
+ * (`principal`) is tried instead: the platform then only renews the token as a side effect of a request,
24054
+ * and only when the server's JSON Web Token auto-refresh is enabled and the token's maximum lifetime is not
24055
+ * reached. When the expiry did not move afterwards, `onReconnect` runs, so the action never leaves the user
24056
+ * believing the session was extended.
23264
24057
  *
23265
24058
  * A custom handler replaces all of this, including that fallback.
23266
24059
  */