@getlupa/client 0.10.0-alpha-2 → 0.10.2

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.
Files changed (37) hide show
  1. package/dist/cjs/components/search-box/SearchBox.vue.d.ts +7 -1
  2. package/dist/cjs/components/search-box/products/SearchBoxProduct.vue.d.ts +1 -0
  3. package/dist/cjs/components/search-results/SearchResults.vue.d.ts +2 -0
  4. package/dist/cjs/components/search-results/filters/facets/StatsFacet.vue.d.ts +2 -0
  5. package/dist/cjs/components/search-results/products/product-card/SearchResultsProductCard.vue.d.ts +1 -0
  6. package/dist/cjs/constants/development/searchResultsDev.example.const.d.ts +1 -0
  7. package/dist/cjs/index.min.js +150 -41
  8. package/dist/cjs/store/modules/tracking.d.ts +3 -1
  9. package/dist/cjs/types/AnalyticsOptions.d.ts +3 -2
  10. package/dist/cjs/types/search-box/Common.d.ts +1 -0
  11. package/dist/cjs/types/search-results/SearchResultsProductCardOptions.d.ts +1 -0
  12. package/dist/cjs/utils/string.utils.d.ts +1 -0
  13. package/dist/es/components/search-box/SearchBox.vue.d.ts +7 -1
  14. package/dist/es/components/search-box/products/SearchBoxProduct.vue.d.ts +1 -0
  15. package/dist/es/components/search-results/SearchResults.vue.d.ts +2 -0
  16. package/dist/es/components/search-results/filters/facets/StatsFacet.vue.d.ts +2 -0
  17. package/dist/es/components/search-results/products/product-card/SearchResultsProductCard.vue.d.ts +1 -0
  18. package/dist/es/constants/development/searchResultsDev.example.const.d.ts +1 -0
  19. package/dist/es/index.min.js +150 -41
  20. package/dist/es/store/modules/tracking.d.ts +3 -1
  21. package/dist/es/types/AnalyticsOptions.d.ts +3 -2
  22. package/dist/es/types/search-box/Common.d.ts +1 -0
  23. package/dist/es/types/search-results/SearchResultsProductCardOptions.d.ts +1 -0
  24. package/dist/es/utils/string.utils.d.ts +1 -0
  25. package/dist/iife/components/search-box/SearchBox.vue.d.ts +7 -1
  26. package/dist/iife/components/search-box/products/SearchBoxProduct.vue.d.ts +1 -0
  27. package/dist/iife/components/search-results/SearchResults.vue.d.ts +2 -0
  28. package/dist/iife/components/search-results/filters/facets/StatsFacet.vue.d.ts +2 -0
  29. package/dist/iife/components/search-results/products/product-card/SearchResultsProductCard.vue.d.ts +1 -0
  30. package/dist/iife/constants/development/searchResultsDev.example.const.d.ts +1 -0
  31. package/dist/iife/index.min.js +1 -1
  32. package/dist/iife/store/modules/tracking.d.ts +3 -1
  33. package/dist/iife/types/AnalyticsOptions.d.ts +3 -2
  34. package/dist/iife/types/search-box/Common.d.ts +1 -0
  35. package/dist/iife/types/search-results/SearchResultsProductCardOptions.d.ts +1 -0
  36. package/dist/iife/utils/string.utils.d.ts +1 -0
  37. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { FetchedData, HighlightedDocInfo, InputSuggestion, InputSuggestionFacet, SelectedData, TrackableEventData } from "@/types/search-box/Common";
2
2
  import { SearchBoxInputOptions, SearchBoxOptions, SearchBoxPanelOptions } from "@/types/search-box/SearchBoxOptions";
3
3
  import { QueryParams } from "@/types/search-results/QueryParams";
4
- import { Document } from "@getlupa/client-sdk/Types";
4
+ import { Document, PublicQuery } from "@getlupa/client-sdk/Types";
5
5
  import Vue from "vue";
6
6
  declare const params: import("vuex-class/lib/bindings").BindingHelpers;
7
7
  export default class SearchBox extends Vue {
@@ -28,6 +28,10 @@ export default class SearchBox extends Vue {
28
28
  queryKey: string;
29
29
  data: TrackableEventData;
30
30
  }) => void;
31
+ trackSearch: ({ queryKey, query, }: {
32
+ queryKey: string;
33
+ query: PublicQuery;
34
+ }) => void;
31
35
  setSearchResultsLink: (searchResultsLink: string) => {
32
36
  searchResultsLink: string;
33
37
  };
@@ -63,7 +67,9 @@ export default class SearchBox extends Vue {
63
67
  query: string;
64
68
  }): void;
65
69
  trackDocumentClick(doc: HighlightedDocInfo): void;
70
+ trackSearchQuery(query?: string): void;
66
71
  trackSuggestionClick(suggestion?: string): void;
67
72
  resetValues(): void;
73
+ handleProductClick(): void;
68
74
  }
69
75
  export {};
@@ -23,5 +23,6 @@ export default class SearchBoxProduct extends Vue {
23
23
  get imageElements(): DocumentElement[];
24
24
  get detailElements(): DocumentElement[];
25
25
  get id(): string;
26
+ get title(): string;
26
27
  handleClick(event?: Event): void;
27
28
  }
@@ -2,6 +2,7 @@ import { QueryParams } from "@/types/search-results/QueryParams";
2
2
  import { ProductGrid, SearchResultsDidYouMeanLabels, SearchResultsOptions, SearchResultsProductOptions } from "@/types/search-results/SearchResultsOptions";
3
3
  import { FilterGroup, PublicQuery, SearchQueryResult } from "@getlupa/client-sdk/Types";
4
4
  import Vue from "vue";
5
+ import { AnalyticsEventType } from "@/types/AnalyticsOptions";
5
6
  export default class SearchResults extends Vue {
6
7
  options: SearchResultsOptions;
7
8
  initialFilters: FilterGroup;
@@ -16,6 +17,7 @@ export default class SearchResults extends Vue {
16
17
  trackSearch: ({ queryKey, query, }: {
17
18
  queryKey: string;
18
19
  query: PublicQuery;
20
+ type?: AnalyticsEventType;
19
21
  }) => void;
20
22
  trackResults: ({ queryKey, results, }: {
21
23
  queryKey: string;
@@ -27,6 +27,8 @@ export default class TermFacet extends Vue {
27
27
  get facetMax(): number;
28
28
  get statsSummary(): string;
29
29
  get separator(): string;
30
+ get isIntegerRange(): boolean;
31
+ get interval(): 1 | 0.01;
30
32
  get sliderInputFormat(): string | undefined;
31
33
  onMinValueChange(): void;
32
34
  onMaxValueChange(): void;
@@ -30,6 +30,7 @@ export default class SearchResultsProductCard extends Vue {
30
30
  mounted(): void;
31
31
  checkIfIsInStock(): Promise<void>;
32
32
  get id(): string;
33
+ get title(): string;
33
34
  handleClick(): void;
34
35
  handleProductEvent(item: {
35
36
  type: ReportableEventType;
@@ -100,6 +100,7 @@ export declare const SEARCH_RESULTS_CONFIGURATION: {
100
100
  details: string;
101
101
  };
102
102
  idKey: string;
103
+ titleKey: string;
103
104
  elements: DocumentElement[];
104
105
  breadcrumbs: ({
105
106
  label: string;
@@ -10828,6 +10828,13 @@ const getProductKey = (index, product, idKey) => {
10828
10828
  }
10829
10829
  return index;
10830
10830
  };
10831
+ const normalizeFloat = (value) => {
10832
+ var _a;
10833
+ if (!value) {
10834
+ return 0;
10835
+ }
10836
+ return +((_a = value === null || value === void 0 ? void 0 : value.replace(/[^0-9,.]/g, "")) === null || _a === void 0 ? void 0 : _a.replace(",", "."));
10837
+ };
10831
10838
  const escapeHtml = (value) => {
10832
10839
  if (!value) {
10833
10840
  return "";
@@ -12207,7 +12214,7 @@ const getRelativePath = (link) => {
12207
12214
  }
12208
12215
  catch (_a) {
12209
12216
  // Invalid url, let's return original string
12210
- return link;
12217
+ return (link === null || link === void 0 ? void 0 : link.endsWith("/")) ? link.slice(0, link.length - 1) : link;
12211
12218
  }
12212
12219
  };
12213
12220
  // Checks if url links match absolutely, or if their relative parts are equal
@@ -12265,7 +12272,18 @@ let SearchBoxProduct = class SearchBoxProduct extends Vue$1 {
12265
12272
  }
12266
12273
  return "";
12267
12274
  }
12275
+ get title() {
12276
+ if (!this.panelOptions.titleKey) {
12277
+ return "";
12278
+ }
12279
+ const title = this.item[this.panelOptions.titleKey] || "";
12280
+ this.addHistory({
12281
+ item: title,
12282
+ });
12283
+ return title;
12284
+ }
12268
12285
  handleClick(event) {
12286
+ var _a;
12269
12287
  if (this.panelOptions.titleKey) {
12270
12288
  this.addHistory({
12271
12289
  item: this.item[this.panelOptions.titleKey] || "",
@@ -12282,13 +12300,14 @@ let SearchBoxProduct = class SearchBoxProduct extends Vue$1 {
12282
12300
  type: "itemClick",
12283
12301
  analytics: {
12284
12302
  type: "autocomplete_product_click",
12285
- label: this.link,
12303
+ label: (_a = this.title) !== null && _a !== void 0 ? _a : this.link,
12286
12304
  },
12287
12305
  },
12288
12306
  });
12289
12307
  if (!this.link) {
12290
12308
  return;
12291
12309
  }
12310
+ this.$emit("product-click");
12292
12311
  handleRoutingEvent(this.link, event, this.boxRoutingBehavior === "event");
12293
12312
  }
12294
12313
  };
@@ -12465,6 +12484,11 @@ var __vue_render__$11 = function () {
12465
12484
  highlighted: index === _vm.highlightedIndex,
12466
12485
  inputValue: _vm.inputValue,
12467
12486
  },
12487
+ on: {
12488
+ "product-click": function ($event) {
12489
+ return _vm.$emit("product-click")
12490
+ },
12491
+ },
12468
12492
  })
12469
12493
  }),
12470
12494
  1
@@ -12583,6 +12607,11 @@ var __vue_render__$10 = function () {
12583
12607
  labels: _vm.labels,
12584
12608
  inputValue: _vm.inputValue,
12585
12609
  },
12610
+ on: {
12611
+ "product-click": function ($event) {
12612
+ return _vm.$emit("product-click")
12613
+ },
12614
+ },
12586
12615
  })
12587
12616
  };
12588
12617
  var __vue_staticRenderFns__$10 = [];
@@ -12591,7 +12620,7 @@ __vue_render__$10._withStripped = true;
12591
12620
  /* style */
12592
12621
  const __vue_inject_styles__$10 = function (inject) {
12593
12622
  if (!inject) return
12594
- inject("data-v-45bb68b4_0", { source: "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", map: undefined, media: undefined });
12623
+ inject("data-v-58b6ab21_0", { source: "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", map: undefined, media: undefined });
12595
12624
 
12596
12625
  };
12597
12626
  /* scoped */
@@ -13314,8 +13343,9 @@ let SearchBoxMainPanel = class SearchBoxMainPanel extends Vue$1 {
13314
13343
  this.sdkOptions = this.options.options;
13315
13344
  }
13316
13345
  get displayResults() {
13317
- var _a;
13318
- return ((_a = this.inputValue) === null || _a === void 0 ? void 0 : _a.length) >= this.options.minInputLength;
13346
+ var _a, _b;
13347
+ return (((_a = this.inputValue) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
13348
+ ((_b = this.inputValue) === null || _b === void 0 ? void 0 : _b.length) >= this.options.minInputLength);
13319
13349
  }
13320
13350
  get displayHistory() {
13321
13351
  var _a;
@@ -13462,6 +13492,9 @@ var __vue_render__$V = function () {
13462
13492
  itemSelect: function (item) {
13463
13493
  return _vm.$emit("itemSelect", item)
13464
13494
  },
13495
+ "product-click": function ($event) {
13496
+ return _vm.$emit("product-click")
13497
+ },
13465
13498
  },
13466
13499
  })
13467
13500
  : _vm._e(),
@@ -13511,7 +13544,7 @@ __vue_render__$V._withStripped = true;
13511
13544
  /* style */
13512
13545
  const __vue_inject_styles__$V = function (inject) {
13513
13546
  if (!inject) return
13514
- inject("data-v-0b92689b_0", { source: "#lupa-search-box-panel {\n display: flex;\n justify-content: space-between;\n flex-direction: column;\n}\n.lupa-more-results {\n text-align: center;\n}", map: undefined, media: undefined });
13547
+ inject("data-v-947d134e_0", { source: "#lupa-search-box-panel {\n display: flex;\n justify-content: space-between;\n flex-direction: column;\n}\n.lupa-more-results {\n text-align: center;\n}", map: undefined, media: undefined });
13515
13548
 
13516
13549
  };
13517
13550
  /* scoped */
@@ -30848,6 +30881,7 @@ let SearchBox = class SearchBox extends Vue$1 {
30848
30881
  this.opened = true;
30849
30882
  this.inputValue = value;
30850
30883
  this.suggestedValue = defaultSuggestedValue;
30884
+ this.trackSearchQuery(value);
30851
30885
  if (this.isSearchContainer) {
30852
30886
  this.goToResultsDebounced({
30853
30887
  searchText: this.searchValue,
@@ -30940,11 +30974,22 @@ let SearchBox = class SearchBox extends Vue$1 {
30940
30974
  type: "itemClick",
30941
30975
  analytics: {
30942
30976
  type: "autocomplete_product_click",
30943
- label: doc.doc.url || doc.id,
30977
+ label: doc.title || doc.id,
30944
30978
  },
30945
30979
  },
30946
30980
  });
30947
30981
  }
30982
+ trackSearchQuery(query) {
30983
+ if (!query) {
30984
+ return;
30985
+ }
30986
+ this.trackSearch({
30987
+ queryKey: this.suggestedValue.queryKey,
30988
+ query: {
30989
+ searchText: query,
30990
+ },
30991
+ });
30992
+ }
30948
30993
  trackSuggestionClick(suggestion) {
30949
30994
  var _a;
30950
30995
  if (suggestion ||
@@ -30959,7 +31004,7 @@ let SearchBox = class SearchBox extends Vue$1 {
30959
31004
  searchQuery: this.inputValue,
30960
31005
  type: "suggestionClick",
30961
31006
  analytics: {
30962
- type: "autocomplete_keyword_click",
31007
+ type: "autocomplete_suggestion_click",
30963
31008
  label: suggestion || this.searchValue,
30964
31009
  },
30965
31010
  },
@@ -30969,6 +31014,9 @@ let SearchBox = class SearchBox extends Vue$1 {
30969
31014
  this.inputValue = "";
30970
31015
  this.suggestedValue = defaultSuggestedValue;
30971
31016
  }
31017
+ handleProductClick() {
31018
+ this.opened = false;
31019
+ }
30972
31020
  };
30973
31021
  __decorate([
30974
31022
  Prop()
@@ -30988,6 +31036,9 @@ __decorate([
30988
31036
  __decorate([
30989
31037
  tracking$4.Action("track")
30990
31038
  ], SearchBox.prototype, "trackClick", void 0);
31039
+ __decorate([
31040
+ tracking$4.Action("trackSearch")
31041
+ ], SearchBox.prototype, "trackSearch", void 0);
30991
31042
  __decorate([
30992
31043
  params$e.Action("setSearchResultsLink")
30993
31044
  ], SearchBox.prototype, "setSearchResultsLink", void 0);
@@ -31046,6 +31097,7 @@ var __vue_render__$U = function () {
31046
31097
  fetched: _vm.handleItemsFetch,
31047
31098
  itemSelect: _vm.handleItemSelect,
31048
31099
  "go-to-results": _vm.handleSearch,
31100
+ "product-click": _vm.handleProductClick,
31049
31101
  },
31050
31102
  })
31051
31103
  : _vm._e(),
@@ -31060,7 +31112,7 @@ __vue_render__$U._withStripped = true;
31060
31112
  /* style */
31061
31113
  const __vue_inject_styles__$U = function (inject) {
31062
31114
  if (!inject) return
31063
- inject("data-v-289ccc0f_0", { source: "\n#lupa-search-box {\n width: 100%;\n}\n.lupa-search-box-wrapper {\n position: relative;\n}\n", map: undefined, media: undefined });
31115
+ inject("data-v-d81b3ccc_0", { source: "\n#lupa-search-box {\n width: 100%;\n}\n.lupa-search-box-wrapper {\n position: relative;\n}\n", map: undefined, media: undefined });
31064
31116
 
31065
31117
  };
31066
31118
  /* scoped */
@@ -32077,8 +32129,7 @@ let TermFacet = class TermFacet extends Vue$1 {
32077
32129
  : `${this.sliderRange[0]}`;
32078
32130
  }
32079
32131
  set fromValue(stringValue) {
32080
- const numberString = stringValue.replace(/[^0-9,.]/, "");
32081
- let value = +numberString;
32132
+ let value = normalizeFloat(stringValue);
32082
32133
  if (value < this.facetMin) {
32083
32134
  value = this.facetMin;
32084
32135
  }
@@ -32094,8 +32145,7 @@ let TermFacet = class TermFacet extends Vue$1 {
32094
32145
  : `${this.sliderRange[1]}`;
32095
32146
  }
32096
32147
  set toValue(stringValue) {
32097
- const numberString = stringValue.replace(/[^0-9,.]/, "");
32098
- let value = +numberString;
32148
+ let value = normalizeFloat(stringValue);
32099
32149
  if (value > this.facetMax) {
32100
32150
  value = this.facetMax;
32101
32151
  }
@@ -32157,6 +32207,13 @@ let TermFacet = class TermFacet extends Vue$1 {
32157
32207
  var _a, _b, _c;
32158
32208
  return (_c = (_b = (_a = this.searchResultOptions) === null || _a === void 0 ? void 0 : _a.labels) === null || _b === void 0 ? void 0 : _b.priceSeparator) !== null && _c !== void 0 ? _c : ",";
32159
32209
  }
32210
+ get isIntegerRange() {
32211
+ return (Number.isInteger(this.currentMinValue) &&
32212
+ Number.isInteger(this.currentMaxValue));
32213
+ }
32214
+ get interval() {
32215
+ return this.isIntegerRange ? 1 : 0.01;
32216
+ }
32160
32217
  get sliderInputFormat() {
32161
32218
  return this.isPrice ? `[0-9]+([${this.separator}][0-9]{1,2})?` : undefined;
32162
32219
  }
@@ -32326,6 +32383,7 @@ var __vue_render__$P = function () {
32326
32383
  lazy: true,
32327
32384
  silent: true,
32328
32385
  duration: 0.1,
32386
+ interval: _vm.interval,
32329
32387
  },
32330
32388
  on: {
32331
32389
  change: _vm.handleChange,
@@ -35336,10 +35394,14 @@ let SearchResultsProductCard = class SearchResultsProductCard extends Vue$1 {
35336
35394
  });
35337
35395
  }
35338
35396
  get id() {
35339
- if (this.options.idKey) {
35340
- return this.product[this.options.idKey];
35341
- }
35342
- return "";
35397
+ return this.options.idKey
35398
+ ? this.product[this.options.idKey]
35399
+ : "";
35400
+ }
35401
+ get title() {
35402
+ return this.options.titleKey
35403
+ ? this.product[this.options.titleKey]
35404
+ : "";
35343
35405
  }
35344
35406
  handleClick() {
35345
35407
  var _a, _b;
@@ -35349,6 +35411,10 @@ let SearchResultsProductCard = class SearchResultsProductCard extends Vue$1 {
35349
35411
  itemId: this.id,
35350
35412
  searchQuery: this.query,
35351
35413
  type: "itemClick",
35414
+ analytics: {
35415
+ type: "search_product_click",
35416
+ label: this.title || this.id || this.link,
35417
+ },
35352
35418
  },
35353
35419
  });
35354
35420
  (_b = (_a = this.searchResultOptions.callbacks) === null || _a === void 0 ? void 0 : _a.onProductClick) === null || _b === void 0 ? void 0 : _b.call(_a, {
@@ -35365,8 +35431,8 @@ let SearchResultsProductCard = class SearchResultsProductCard extends Vue$1 {
35365
35431
  type: item.type,
35366
35432
  analytics: item.type === "addToCart"
35367
35433
  ? {
35368
- type: "add_to_cart",
35369
- label: this.link,
35434
+ type: "search_add_to_cart",
35435
+ label: this.title || this.id || this.link,
35370
35436
  }
35371
35437
  : undefined,
35372
35438
  },
@@ -35536,7 +35602,7 @@ __vue_render__$o._withStripped = true;
35536
35602
 
35537
35603
  const initAnalyticsTracking = (analyticsOptions) => {
35538
35604
  try {
35539
- if ((analyticsOptions === null || analyticsOptions === void 0 ? void 0 : analyticsOptions.enabled) && analyticsOptions.type === "ua") {
35605
+ if (analyticsOptions === null || analyticsOptions === void 0 ? void 0 : analyticsOptions.enabled) {
35540
35606
  window.sessionStorage.setItem(TRACKING_ANALYTICS_KEY, JSON.stringify(analyticsOptions));
35541
35607
  }
35542
35608
  else {
@@ -35681,25 +35747,66 @@ const sendGa = (name, ...args) => {
35681
35747
  });
35682
35748
  };
35683
35749
  const trackAnalyticsEvent = (data) => {
35684
- var _a;
35750
+ var _a, _b, _c;
35685
35751
  try {
35686
35752
  const options = JSON.parse((_a = window.sessionStorage.getItem(TRACKING_ANALYTICS_KEY)) !== null && _a !== void 0 ? _a : "{}");
35687
- if (!data.analytics || !options.enabled) {
35753
+ if (!data.analytics ||
35754
+ !options.enabled ||
35755
+ ((_b = options.ignoreEvents) === null || _b === void 0 ? void 0 : _b.includes((_c = data.analytics) === null || _c === void 0 ? void 0 : _c.type))) {
35688
35756
  return;
35689
35757
  }
35690
- const ga = window.ga;
35691
- if (!ga) {
35692
- console.error("Google Analytics object not found");
35693
- return;
35758
+ switch (options.type) {
35759
+ case "ua":
35760
+ sendUaAnalyticsEvent(data, options);
35761
+ break;
35762
+ case "ga4":
35763
+ sendGa4AnalyticsEvent(data, options);
35764
+ break;
35765
+ case "debug":
35766
+ processDebugEvent(data);
35767
+ break;
35768
+ default:
35769
+ sendUaAnalyticsEvent(data, options);
35694
35770
  }
35695
- sendGa("send", "event", options.parentEventName, data.analytics.type, data.analytics.label);
35696
35771
  }
35697
- catch (_b) {
35772
+ catch (_d) {
35698
35773
  console.error("Unable to send an event to google analytics");
35699
35774
  }
35700
35775
  };
35776
+ const sendUaAnalyticsEvent = (data, options) => {
35777
+ var _a, _b, _c, _d;
35778
+ const ga = window.ga;
35779
+ if (!ga) {
35780
+ console.error("Google Analytics object not found");
35781
+ return;
35782
+ }
35783
+ sendGa("send", "event", options.parentEventName, (_b = (_a = data.analytics) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : "", (_d = (_c = data.analytics) === null || _c === void 0 ? void 0 : _c.label) !== null && _d !== void 0 ? _d : "");
35784
+ };
35785
+ const sendGa4AnalyticsEvent = (data, options) => {
35786
+ var _a, _b, _c, _d;
35787
+ if (!window || !window.dataLayer) {
35788
+ console.error("dataLayer object not found.");
35789
+ return;
35790
+ }
35791
+ const sendItemTitle = data.searchQuery !== ((_a = data.analytics) === null || _a === void 0 ? void 0 : _a.label);
35792
+ const params = {
35793
+ search_text: data.searchQuery,
35794
+ item_title: sendItemTitle ? (_b = data.analytics) === null || _b === void 0 ? void 0 : _b.label : undefined,
35795
+ };
35796
+ window.dataLayer.push(Object.assign({ event: (_d = (_c = data.analytics) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : options.parentEventName }, params));
35797
+ };
35798
+ const processDebugEvent = (data) => {
35799
+ var _a, _b, _c;
35800
+ const sendItemTitle = data.searchQuery !== ((_a = data.analytics) === null || _a === void 0 ? void 0 : _a.label);
35801
+ const params = {
35802
+ event: (_b = data.analytics) === null || _b === void 0 ? void 0 : _b.type,
35803
+ search_text: data.searchQuery,
35804
+ item_title: sendItemTitle ? (_c = data.analytics) === null || _c === void 0 ? void 0 : _c.label : undefined,
35805
+ };
35806
+ console.debug("Analytics debug event:", params);
35807
+ };
35701
35808
  const track = (queryKey, data = {}, options) => {
35702
- if (!isTrackingEnabled()) {
35809
+ if (!isTrackingEnabled() || !data.searchQuery) {
35703
35810
  return;
35704
35811
  }
35705
35812
  trackLupaEvent(queryKey, data, options);
@@ -37366,6 +37473,7 @@ let SearchResultsProducts = class SearchResultsProducts extends Vue$1 {
37366
37473
  "labels",
37367
37474
  "queryKey",
37368
37475
  "idKey",
37476
+ "titleKey",
37369
37477
  "routingBehavior",
37370
37478
  ]);
37371
37479
  }
@@ -38052,7 +38160,11 @@ let SearchResults = class SearchResults extends Vue$1 {
38052
38160
  this.query(getPublicQuery(publicQuery, this.initialFilters, this.isProductList));
38053
38161
  }
38054
38162
  query(publicQuery) {
38055
- this.trackSearch({ queryKey: this.options.queryKey, query: publicQuery });
38163
+ this.trackSearch({
38164
+ queryKey: this.options.queryKey,
38165
+ query: publicQuery,
38166
+ type: "search_form_submit",
38167
+ });
38056
38168
  const context = getLupaTrackingContext();
38057
38169
  const limit = publicQuery.limit || this.defaultSearchResultPageSize;
38058
38170
  const query = Object.assign(Object.assign(Object.assign({}, publicQuery), context), { limit });
@@ -38340,9 +38452,9 @@ let SearchResultsEntry = class SearchResultsEntry extends Vue$1 {
38340
38452
  return merge(DEFAULT_OPTIONS_RESULTS, options);
38341
38453
  }
38342
38454
  fetch() {
38343
- var _a;
38455
+ var _a, _b;
38344
38456
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
38345
- (_a = this.$refs.searchResults) === null || _a === void 0 ? void 0 : _a.handleMounted();
38457
+ (_b = (_a = this.$refs.searchResults) === null || _a === void 0 ? void 0 : _a.handleUrlChange) === null || _b === void 0 ? void 0 : _b.call(_a);
38346
38458
  }
38347
38459
  };
38348
38460
  __decorate([
@@ -39318,6 +39430,7 @@ let SearchBoxModule = class SearchBoxModule extends VuexModule {
39318
39430
  link: generateLink((_b = panel.links) === null || _b === void 0 ? void 0 : _b.details, doc),
39319
39431
  queryKey: panel.queryKey,
39320
39432
  id: panel.idKey ? doc[panel.idKey] : "",
39433
+ title: panel.titleKey ? doc[panel.titleKey] : "",
39321
39434
  };
39322
39435
  }
39323
39436
  saveSuggestions({ queryKey, suggestions, inputValue, }) {
@@ -39794,11 +39907,6 @@ let ParamsModule = class ParamsModule extends VuexModule {
39794
39907
  const routing = (_a = this.context.rootGetters["options/boxRoutingBehavior"]) !== null && _a !== void 0 ? _a : "direct-link";
39795
39908
  redirectToResultsPage(this.searchResultsLink, searchText, facet, routing);
39796
39909
  }
39797
- this.context.dispatch("tracking/track", {
39798
- data: {
39799
- analytics: { type: "search_form_submit", label: searchText },
39800
- },
39801
- }, { root: true });
39802
39910
  }
39803
39911
  appendParams({ params, paramsToRemove, encode = true, save = true, searchResultsLink, }) {
39804
39912
  if (!(params === null || params === void 0 ? void 0 : params.length)) {
@@ -39949,22 +40057,23 @@ const getSearchTrackingData = (searchText, type) => {
39949
40057
  };
39950
40058
  };
39951
40059
  let TrackingModule = class TrackingModule extends VuexModule {
39952
- trackSearch({ queryKey, query, }) {
40060
+ trackSearch({ queryKey, query, type = "search_query", }) {
39953
40061
  var _a, _b;
39954
40062
  const options = (_a = this.context.rootGetters["options/envOptions"]) !== null && _a !== void 0 ? _a : {};
39955
40063
  const hasFilters = Object.keys((_b = query.filters) !== null && _b !== void 0 ? _b : {}).length > 0;
39956
40064
  if (hasFilters) {
39957
- const data = getSearchTrackingData(query.searchText, "filters");
40065
+ const data = getSearchTrackingData(query.searchText, "search_filters");
39958
40066
  track(queryKey, data, options);
40067
+ return;
39959
40068
  }
39960
- const data = getSearchTrackingData(query.searchText, "search");
40069
+ const data = getSearchTrackingData(query.searchText, type);
39961
40070
  track(queryKey, data, options);
39962
40071
  }
39963
40072
  trackResults({ queryKey, results, }) {
39964
40073
  var _a;
39965
40074
  const options = (_a = this.context.rootGetters["options/envOptions"]) !== null && _a !== void 0 ? _a : {};
39966
40075
  if (results.total < 1) {
39967
- const data = getSearchTrackingData(results.searchText, "zero_results");
40076
+ const data = getSearchTrackingData(results.searchText, "search_zero_results");
39968
40077
  track(queryKey, data, options);
39969
40078
  }
39970
40079
  }
@@ -1,10 +1,12 @@
1
+ import { AnalyticsEventType } from "@/types/AnalyticsOptions";
1
2
  import { TrackableEventData } from "@/types/search-box/Common";
2
3
  import { PublicQuery, SearchQueryResult } from "@getlupa/client-sdk/Types";
3
4
  import { VuexModule } from "vuex-module-decorators";
4
5
  export default class TrackingModule extends VuexModule {
5
- trackSearch({ queryKey, query, }: {
6
+ trackSearch({ queryKey, query, type, }: {
6
7
  queryKey: string;
7
8
  query: PublicQuery;
9
+ type?: AnalyticsEventType;
8
10
  }): void;
9
11
  trackResults({ queryKey, results, }: {
10
12
  queryKey: string;
@@ -1,7 +1,8 @@
1
1
  export declare const PARENT_EVENT_NAME = "GetLupa";
2
- export declare type AnalyticsEventType = "search" | "search_form_submit" | "autocomplete_keyword_click" | "autocomplete_product_click" | "zero_results" | "filters" | "add_to_cart";
2
+ export declare type AnalyticsEventType = "search_query" | "search_form_submit" | "autocomplete_suggestion_click" | "autocomplete_product_click" | "search_product_click" | "search_zero_results" | "search_filters" | "search_add_to_cart";
3
3
  export declare type AnalyticsOptions = {
4
- type: "ua";
4
+ type: "ua" | "ga4" | "debug";
5
5
  enabled: boolean;
6
6
  parentEventName: string;
7
+ ignoreEvents?: AnalyticsEventType[];
7
8
  };
@@ -41,4 +41,5 @@ export declare type HighlightedDocInfo = {
41
41
  link?: string;
42
42
  queryKey?: string;
43
43
  id?: unknown;
44
+ title?: string;
44
45
  };
@@ -14,6 +14,7 @@ export declare type SearchResultsProductCardOptions = {
14
14
  elements: DocumentElement[];
15
15
  queryKey: string;
16
16
  idKey?: string;
17
+ titleKey?: string;
17
18
  };
18
19
  export declare type SearchResultBadgeOptions = {
19
20
  anchor: AnchorPosition;
@@ -5,4 +5,5 @@ export declare const addParamsToLabel: (label: string, ...params: unknown[]) =>
5
5
  export declare const getRandomString: (length: number) => string;
6
6
  export declare const getDisplayValue: (value?: string | number | undefined) => string;
7
7
  export declare const getProductKey: (index: string, product: Document, idKey: string | undefined) => string;
8
+ export declare const normalizeFloat: (value?: string | undefined) => number;
8
9
  export declare const escapeHtml: (value?: string | undefined) => string;
@@ -1,7 +1,7 @@
1
1
  import { FetchedData, HighlightedDocInfo, InputSuggestion, InputSuggestionFacet, SelectedData, TrackableEventData } from "@/types/search-box/Common";
2
2
  import { SearchBoxInputOptions, SearchBoxOptions, SearchBoxPanelOptions } from "@/types/search-box/SearchBoxOptions";
3
3
  import { QueryParams } from "@/types/search-results/QueryParams";
4
- import { Document } from "@getlupa/client-sdk/Types";
4
+ import { Document, PublicQuery } from "@getlupa/client-sdk/Types";
5
5
  import Vue from "vue";
6
6
  declare const params: import("vuex-class/lib/bindings").BindingHelpers;
7
7
  export default class SearchBox extends Vue {
@@ -28,6 +28,10 @@ export default class SearchBox extends Vue {
28
28
  queryKey: string;
29
29
  data: TrackableEventData;
30
30
  }) => void;
31
+ trackSearch: ({ queryKey, query, }: {
32
+ queryKey: string;
33
+ query: PublicQuery;
34
+ }) => void;
31
35
  setSearchResultsLink: (searchResultsLink: string) => {
32
36
  searchResultsLink: string;
33
37
  };
@@ -63,7 +67,9 @@ export default class SearchBox extends Vue {
63
67
  query: string;
64
68
  }): void;
65
69
  trackDocumentClick(doc: HighlightedDocInfo): void;
70
+ trackSearchQuery(query?: string): void;
66
71
  trackSuggestionClick(suggestion?: string): void;
67
72
  resetValues(): void;
73
+ handleProductClick(): void;
68
74
  }
69
75
  export {};
@@ -23,5 +23,6 @@ export default class SearchBoxProduct extends Vue {
23
23
  get imageElements(): DocumentElement[];
24
24
  get detailElements(): DocumentElement[];
25
25
  get id(): string;
26
+ get title(): string;
26
27
  handleClick(event?: Event): void;
27
28
  }
@@ -2,6 +2,7 @@ import { QueryParams } from "@/types/search-results/QueryParams";
2
2
  import { ProductGrid, SearchResultsDidYouMeanLabels, SearchResultsOptions, SearchResultsProductOptions } from "@/types/search-results/SearchResultsOptions";
3
3
  import { FilterGroup, PublicQuery, SearchQueryResult } from "@getlupa/client-sdk/Types";
4
4
  import Vue from "vue";
5
+ import { AnalyticsEventType } from "@/types/AnalyticsOptions";
5
6
  export default class SearchResults extends Vue {
6
7
  options: SearchResultsOptions;
7
8
  initialFilters: FilterGroup;
@@ -16,6 +17,7 @@ export default class SearchResults extends Vue {
16
17
  trackSearch: ({ queryKey, query, }: {
17
18
  queryKey: string;
18
19
  query: PublicQuery;
20
+ type?: AnalyticsEventType;
19
21
  }) => void;
20
22
  trackResults: ({ queryKey, results, }: {
21
23
  queryKey: string;
@@ -27,6 +27,8 @@ export default class TermFacet extends Vue {
27
27
  get facetMax(): number;
28
28
  get statsSummary(): string;
29
29
  get separator(): string;
30
+ get isIntegerRange(): boolean;
31
+ get interval(): 1 | 0.01;
30
32
  get sliderInputFormat(): string | undefined;
31
33
  onMinValueChange(): void;
32
34
  onMaxValueChange(): void;
@@ -30,6 +30,7 @@ export default class SearchResultsProductCard extends Vue {
30
30
  mounted(): void;
31
31
  checkIfIsInStock(): Promise<void>;
32
32
  get id(): string;
33
+ get title(): string;
33
34
  handleClick(): void;
34
35
  handleProductEvent(item: {
35
36
  type: ReportableEventType;
@@ -100,6 +100,7 @@ export declare const SEARCH_RESULTS_CONFIGURATION: {
100
100
  details: string;
101
101
  };
102
102
  idKey: string;
103
+ titleKey: string;
103
104
  elements: DocumentElement[];
104
105
  breadcrumbs: ({
105
106
  label: string;