@sinequa/atomic-angular 1.0.19 → 1.0.21

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.
@@ -1789,42 +1789,49 @@ async function withFetch(callback, injector) {
1789
1789
  }
1790
1790
  }
1791
1791
 
1792
+ /**
1793
+ * Canonical default shape of the query params state.
1794
+ *
1795
+ * Shared between `withState()` (initial value) and `reset()` (replacement state) so the
1796
+ * two cannot drift apart. Keep in sync with `QueryParamsState`.
1797
+ */
1798
+ const QUERY_PARAMS_DEFAULTS = {
1799
+ // QueryParams specific properties
1800
+ path: "",
1801
+ filters: [],
1802
+ id: "",
1803
+ // Query properties (all optional due to Partial<>)
1804
+ name: "",
1805
+ text: "",
1806
+ action: "",
1807
+ select: [],
1808
+ open: [],
1809
+ page: undefined,
1810
+ pageSize: undefined,
1811
+ tab: "",
1812
+ scope: "",
1813
+ sort: "",
1814
+ basket: "",
1815
+ isFirstPage: undefined,
1816
+ strictRefine: undefined,
1817
+ globalRelevance: undefined,
1818
+ questionLanguage: "",
1819
+ questionDefaultLanguage: "",
1820
+ spellingCorrectionMode: undefined,
1821
+ spellingCorrectionFilter: "",
1822
+ documentWeight: "",
1823
+ textPartWeights: "",
1824
+ relevanceTransforms: "",
1825
+ removeDuplicates: undefined,
1826
+ queryId: "",
1827
+ aggregations: undefined,
1828
+ orderBy: "",
1829
+ groupBy: "",
1830
+ neuralSearch: undefined
1831
+ };
1792
1832
  const QueryParamsStore = signalStore({ providedIn: "root" }, withDevtools("QueryParams"), withQueryParamsFeatures());
1793
1833
  function withQueryParamsFeatures() {
1794
- return signalStoreFeature(withState({
1795
- // QueryParams specific properties
1796
- path: "",
1797
- filters: [],
1798
- id: "",
1799
- // Query properties (all optional due to Partial<>)
1800
- name: "",
1801
- text: "",
1802
- action: "",
1803
- select: [],
1804
- open: [],
1805
- page: undefined,
1806
- pageSize: undefined,
1807
- tab: "",
1808
- scope: "",
1809
- sort: "",
1810
- basket: "",
1811
- isFirstPage: undefined,
1812
- strictRefine: undefined,
1813
- globalRelevance: undefined,
1814
- questionLanguage: "",
1815
- questionDefaultLanguage: "",
1816
- spellingCorrectionMode: undefined,
1817
- spellingCorrectionFilter: "",
1818
- documentWeight: "",
1819
- textPartWeights: "",
1820
- relevanceTransforms: "",
1821
- removeDuplicates: undefined,
1822
- queryId: "",
1823
- aggregations: undefined,
1824
- orderBy: "",
1825
- groupBy: "",
1826
- neuralSearch: undefined
1827
- }), withMethods((store, injector = inject(Injector), router = inject(Router), route = inject(ActivatedRoute), appStore = inject(AppStore)) => ({
1834
+ return signalStoreFeature(withState(QUERY_PARAMS_DEFAULTS), withMethods((store, injector = inject(Injector), router = inject(Router), route = inject(ActivatedRoute), appStore = inject(AppStore)) => ({
1828
1835
  /**
1829
1836
  * Sets the state from the given URL by extracting query parameters and updating the store.
1830
1837
  *
@@ -2059,6 +2066,18 @@ function withQueryParamsFeatures() {
2059
2066
  return newState;
2060
2067
  });
2061
2068
  },
2069
+ /**
2070
+ * Resets the query params to their default state.
2071
+ *
2072
+ * Called on every application (re-)initialization (first login, sign-in, and user
2073
+ * override/impersonation) so that a previous user's search text/filters/sort/etc. don't
2074
+ * leak into the next user's session — `QueryParamsStore` is a root-level singleton that
2075
+ * otherwise survives across logins. See ES-32053.
2076
+ */
2077
+ reset() {
2078
+ patchState(store, QUERY_PARAMS_DEFAULTS);
2079
+ this._updateUrlQueryParams(QUERY_PARAMS_DEFAULTS);
2080
+ },
2062
2081
  /**
2063
2082
  * Retrieves a filter object based on the provided field or name.
2064
2083
  *
@@ -2880,7 +2899,7 @@ function withSavedSearchesFeatures() {
2880
2899
  return { ...state, savedSearches: [...savedSearches] };
2881
2900
  });
2882
2901
  },
2883
- getSavedSearch(search) {
2902
+ getSavedSearch(search, tab) {
2884
2903
  if (!search)
2885
2904
  return undefined;
2886
2905
  const savedSearches = store.savedSearches();
@@ -2889,7 +2908,15 @@ function withSavedSearchesFeatures() {
2889
2908
  if (!queryParams)
2890
2909
  return false;
2891
2910
  const q = queryParams.split('&').find(qp => qp.startsWith('q='));
2892
- return !!q && decodeURI(q.substring(2)) === search;
2911
+ const qMatch = !!q && decodeURI(q.substring(2)) === search;
2912
+ if (!qMatch)
2913
+ return false;
2914
+ // If tab is provided, check it; otherwise accept any tab
2915
+ if (tab) {
2916
+ const t = queryParams.split('&').find(qp => qp.startsWith('t='));
2917
+ return !!t && decodeURI(t.substring(2)) === tab;
2918
+ }
2919
+ return true;
2893
2920
  });
2894
2921
  }
2895
2922
  })));
@@ -3552,6 +3579,7 @@ class ApplicationService {
3552
3579
  userSettingsStore = inject(UserSettingsStore);
3553
3580
  principalStore = inject(PrincipalStore);
3554
3581
  appStore = inject(AppStore);
3582
+ queryParamsStore = inject(QueryParamsStore);
3555
3583
  router = inject(Router);
3556
3584
  titleService = inject(Title);
3557
3585
  components = inject(ROUTE_COMPONENTS);
@@ -3601,6 +3629,8 @@ class ApplicationService {
3601
3629
  * Initializes the application stores.
3602
3630
  * - Fetches the application configuration.
3603
3631
  * - Sets the fetched application configuration in the app store.
3632
+ * - Resets the query params store (runs on first login as well as on every subsequent
3633
+ * re-initialization, e.g. user override, so no previous user's search state leaks in).
3604
3634
  * - Loads the user settings and logs the state of the user settings store.
3605
3635
  */
3606
3636
  async initializeStores() {
@@ -3611,6 +3641,9 @@ class ApplicationService {
3611
3641
  // Load the principal (user information)
3612
3642
  await this.principalStore.initialize();
3613
3643
  info("principalStore", getState(this.principalStore));
3644
+ // Reset the query params (search text, filters, sort, ...) so a previous user's
3645
+ // in-memory search state doesn't leak into the next user's session. ES-32053.
3646
+ this.queryParamsStore.reset();
3614
3647
  // Load the user settings
3615
3648
  await this.userSettingsStore.initialize();
3616
3649
  info("userSettingsStore", getState(this.userSettingsStore));
@@ -4644,9 +4677,10 @@ class SavedSearchesService {
4644
4677
  *
4645
4678
  * @throws {Error} If saving an empty search is attempted.
4646
4679
  */
4647
- saveSearch(saveName) {
4648
- const { text } = getState(this.queryParamsStore);
4680
+ saveSearch(saveName, saveTab) {
4681
+ const { text, tab } = getState(this.queryParamsStore);
4649
4682
  const display = saveName || text;
4683
+ const tabName = saveTab || tab;
4650
4684
  if (!display) {
4651
4685
  console.error("Saving empty search is not allowed");
4652
4686
  return;
@@ -4654,6 +4688,7 @@ class SavedSearchesService {
4654
4688
  const savedSearch = {
4655
4689
  url: window.location.hash.substring(1),
4656
4690
  date: new Date().toISOString(),
4691
+ tab: tabName,
4657
4692
  display
4658
4693
  };
4659
4694
  const savedSearches = this.userSettingsStore.savedSearches();
@@ -15925,7 +15960,7 @@ class SavedSearchDialog {
15925
15960
  this.dialog()?.showModal();
15926
15961
  }
15927
15962
  async confirm() {
15928
- this.savedSearchesService.saveSearch(this.saveName());
15963
+ this.savedSearchesService.saveSearch(this.saveName(), this.queryParamsStore.tab?.());
15929
15964
  notify.success(this.transloco.translate("searches.saved.saved"), { duration: 2000 });
15930
15965
  // emit close output of the component
15931
15966
  this.dialog()?.close("dialog-confirm");