@empathyco/x-components 3.0.0-alpha.186 → 3.0.0-alpha.188

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file. See
4
4
  [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.0.0-alpha.188](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.187...@empathyco/x-components@3.0.0-alpha.188) (2022-10-05)
7
+
8
+ ### Bug Fixes
9
+
10
+ - wait for the extra params to make the initial requests (#754)
11
+ ([468a61b](https://github.com/empathyco/x/commit/468a61b69e11b3917a33d44bd415a5ea14c5c409)),
12
+ closes [EX-6977](https://searchbroker.atlassian.net/browse/EX-6977)
13
+
14
+ # Change Log
15
+
16
+ All notable changes to this project will be documented in this file. See
17
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
18
+
19
+ ## [3.0.0-alpha.187](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.186...@empathyco/x-components@3.0.0-alpha.187) (2022-10-05)
20
+
21
+ ### Features
22
+
23
+ - **query-preview:** Add `debounceTimeMs` to `QueryPreview` component. (#752)
24
+ ([ddca375](https://github.com/empathyco/x/commit/ddca375201056d374515b7426df1fac3a1ecf6c1)),
25
+ closes [EX-7049](https://searchbroker.atlassian.net/browse/EX-7049)
26
+
27
+ # Change Log
28
+
29
+ All notable changes to this project will be documented in this file. See
30
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
31
+
6
32
  ## [3.0.0-alpha.186](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.185...@empathyco/x-components@3.0.0-alpha.186) (2022-10-03)
7
33
 
8
34
  ### Features
@@ -0,0 +1,13 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [QueryPreview](./x-components.querypreview.md) &gt; [debounceTimeMs](./x-components.querypreview.debouncetimems.md)
4
+
5
+ ## QueryPreview.debounceTimeMs property
6
+
7
+ Debounce time in milliseconds for triggering the search requests. It will default to 0 to fit the most common use case (pre-search), and it would work properly with a 250 value inside empathize.
8
+
9
+ <b>Signature:</b>
10
+
11
+ ```typescript
12
+ debounceTimeMs: number;
13
+ ```
@@ -18,18 +18,12 @@ export default class QueryPreview extends Vue
18
18
  | Property | Modifiers | Type | Description |
19
19
  | --- | --- | --- | --- |
20
20
  | [config](./x-components.querypreview.config.md) | | [QueriesPreviewConfig](./x-components.queriespreviewconfig.md) | As the request is handled in this component, we need the config that will be used in the request. |
21
+ | [debounceTimeMs](./x-components.querypreview.debouncetimems.md) | | number | Debounce time in milliseconds for triggering the search requests. It will default to 0 to fit the most common use case (pre-search), and it would work properly with a 250 value inside empathize. |
21
22
  | [maxItemsToRender?](./x-components.querypreview.maxitemstorender.md) | | number | <i>(Optional)</i> Number of query preview results to be rendered. |
22
23
  | [params](./x-components.querypreview.params.md) | | Dictionary&lt;unknown&gt; | As the request is handled in this component, we need the extra params that will be used in the request. |
23
24
  | [previewResults](./x-components.querypreview.previewresults.md) | | Dictionary&lt;[QueryPreviewItem](./x-components.querypreviewitem.md)<!-- -->&gt; | The results preview of the queries preview mounted. It is a dictionary, indexed by the query preview query. |
24
25
  | [query](./x-components.querypreview.query.md) | | string | The query to retrieve the results preview. |
25
- | [queryFeature?](./x-components.querypreview.queryfeature.md) | | [QueryFeature](./x-components.queryfeature.md) | <i>(Optional)</i> . The origin property for the request |
26
- | [queryPreviewRequest](./x-components.querypreview.querypreviewrequest.md) | | SearchRequest | The computed request object to be used to retrieve the query preview results. |
26
+ | [queryFeature?](./x-components.querypreview.queryfeature.md) | | [QueryFeature](./x-components.queryfeature.md) | <i>(Optional)</i> The origin property for the request. |
27
27
  | [queryPreviewResults](./x-components.querypreview.querypreviewresults.md) | | Partial&lt;[QueryPreviewItem](./x-components.querypreviewitem.md)<!-- -->&gt; \| undefined | Gets from the state the results preview of the query preview. |
28
28
  | [results](./x-components.querypreview.results.md) | | Result\[\] \| undefined | The results to render from the state. |
29
29
 
30
- ## Methods
31
-
32
- | Method | Modifiers | Description |
33
- | --- | --- | --- |
34
- | [mounted()](./x-components.querypreview.mounted.md) | | |
35
-
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## QueryPreview.queryFeature property
6
6
 
7
- . The origin property for the request
7
+ The origin property for the request.
8
8
 
9
9
  <b>Signature:</b>
10
10
 
@@ -12,11 +12,12 @@ By default, it renders the names of the results.
12
12
 
13
13
  ## Props
14
14
 
15
- | Name | Description | Type | Default |
16
- | ----------------------------- | ----------------------------------------------- | ------------------------- | ------------- |
17
- | <code>query</code> | The query to retrieve the results preview. | <code>string</code> | <code></code> |
18
- | <code>queryFeature</code> | | <code>QueryFeature</code> | <code></code> |
19
- | <code>maxItemsToRender</code> | Number of query preview results to be rendered. | <code>number</code> | <code></code> |
15
+ | Name | Description | Type | Default |
16
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | -------------- |
17
+ | <code>query</code> | The query to retrieve the results preview. | <code>string</code> | <code></code> |
18
+ | <code>queryFeature</code> | The origin property for the request. | <code>QueryFeature</code> | <code></code> |
19
+ | <code>maxItemsToRender</code> | Number of query preview results to be rendered. | <code>number</code> | <code></code> |
20
+ | <code>debounceTimeMs</code> | Debounce time in milliseconds for triggering the search requests.<br />It will default to 0 to fit the most common use case (pre-search),<br />and it would work properly with a 250 value inside empathize. | <code>number</code> | <code>0</code> |
20
21
 
21
22
  ## Slots
22
23
 
@@ -16,20 +16,15 @@ function registerStoreEmitters({ name, storeEmitters, storeModule }, bus, store)
16
16
  const safeGettersProxy = getGettersProxyFromModule(store.getters, name, storeModule);
17
17
  forEach(storeEmitters, (event, stateSelector) => {
18
18
  const { selector, immediate, filter, ...options } = normalizeStateSelector(stateSelector, event);
19
- const emit = (value, oldValue) => {
20
- bus.emit(event, value, { moduleName: name, oldValue });
21
- };
22
19
  const watcherSelector = () => selector(store.state.x[name], safeGettersProxy);
23
- const debouncedEffect = debounceWatcherEffect(event, (newValue, oldValue) => {
20
+ const emit = debounceWatcherEffect(event, (newValue, oldValue) => {
24
21
  if (filter(newValue, oldValue)) {
25
- emit(newValue, oldValue);
22
+ bus.emit(event, newValue, { moduleName: name, oldValue });
26
23
  }
27
24
  });
28
- store.watch(watcherSelector, debouncedEffect, options);
25
+ store.watch(watcherSelector, emit, options);
29
26
  if (immediate) {
30
- Promise.resolve().then(() => {
31
- emit(watcherSelector());
32
- });
27
+ emit(watcherSelector());
33
28
  }
34
29
  });
35
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"x-emitters.js","sources":["../../../src/plugins/x-emitters.ts"],"sourcesContent":["import { forEach, Dictionary } from '@empathyco/x-utils';\nimport { Store } from 'vuex';\nimport { getGettersProxyFromModule } from '../store/utils/getters-proxy.utils';\nimport { AnySimpleStateSelector, AnyStateSelector } from '../store/utils/store-emitters.utils';\nimport { debounce } from '../utils/debounce';\nimport { DebouncedFunction } from '../utils/types';\nimport { XEvent, XEventPayload } from '../wiring/events.types';\nimport { AnyXModule } from '../x-modules/x-modules.types';\nimport { XBus } from './x-bus.types';\n\n/**\n * Registers the store emitters, making them emit the event when the part of the state selected\n * changes.\n *\n * @param xModule - The {@link XModule} to register its Store Emitters.\n * @param bus - The {@Link XBus} to emit the events by the Emitters.\n * @param store - The Vuex store to access to state and getters to watch them.\n *\n * @internal\n */\nexport function registerStoreEmitters(\n { name, storeEmitters, storeModule }: AnyXModule,\n bus: XBus,\n store: Store<any>\n): void {\n const safeGettersProxy = getGettersProxyFromModule(store.getters, name, storeModule);\n forEach(storeEmitters, (event, stateSelector: AnySimpleStateSelector | AnyStateSelector) => {\n const { selector, immediate, filter, ...options } = normalizeStateSelector(\n stateSelector,\n event\n );\n\n const emit = (\n value: XEventPayload<typeof event>,\n oldValue?: XEventPayload<typeof event>\n ): void => {\n bus.emit(event, value, { moduleName: name, oldValue });\n };\n const watcherSelector = (): XEventPayload<typeof event> =>\n selector(store.state.x[name], safeGettersProxy);\n const debouncedEffect = debounceWatcherEffect(event, (newValue, oldValue) => {\n if (filter(newValue, oldValue)) {\n emit(newValue, oldValue);\n }\n });\n\n store.watch(watcherSelector, debouncedEffect, options);\n\n if (immediate) {\n Promise.resolve().then(() => {\n emit(watcherSelector());\n });\n }\n });\n}\n\n/**\n * This function \"wraps\" the watcher effect (the callback of the watcher) with debounce to avoid\n * repeating events and request. Right now this function wraps every effect in a debounce and adds\n * an extra debounce to the \"SecondLevelEvent\" events, to try to delay this events after the state\n * change events.\n *\n * @param event - The {@link XEvent} to emit.\n * @param watcherEffect - The callback to execute.\n * @returns A new function with the `watcherEffect` callback wrapped in debounce.\n */\nfunction debounceWatcherEffect<Event extends XEvent = XEvent>(\n event: Event,\n watcherEffect: (newValue: XEventPayload<Event>, oldValue: XEventPayload<Event>) => void\n): (newValue: XEventPayload<Event>, oldValue: XEventPayload<Event>) => void {\n /*\n * Due the debounce added to the watch callback, the `oldValue` would be the one from the last\n * watcher execution instead of the last callback execution. This would cause problems receiving\n * unstable oldValues, used in the Emitter filter.\n * To solve this, we store the `oldValue` of the watcher in the `previousValue` variable, and we\n * keep there until the watcher callback is finally executed (after the debounce). Then this\n * `previousValue` is cleared to store the next `oldValue`.\n */\n let previousValue: XEventPayload<Event> | undefined = undefined;\n\n let watcherCallback = debounce(\n (newValue: XEventPayload<Event>, oldValue: XEventPayload<Event>): void => {\n watcherEffect(newValue, oldValue);\n previousValue = undefined;\n },\n 0\n );\n /* Only applying the extra debounce to the \"SecondLevelEvent\" events to avoid repeating outer\n * effects (requests, URL changes). If we only apply the debounce to all the events we still have\n * the problem of outer effects. */\n if (isSecondLevelEventEmitter(event)) {\n const previousCallback = watcherCallback;\n const debouncedPreviousCallback = debounce(previousCallback, 0);\n watcherCallback = ((n, o) => {\n previousCallback.cancel();\n debouncedPreviousCallback(n, o);\n }) as DebouncedFunction<any>;\n }\n\n return (newValue, oldValue) => {\n previousValue = previousValue !== undefined ? previousValue : oldValue;\n watcherCallback(newValue, previousValue);\n };\n}\n\n/**\n * Transforms a {@link AnySimpleStateSelector} into a {@link AnyStateSelector}, and sets\n * default values for its properties.\n *\n * @param stateSelector - The state selector to normalize.\n * @param event - The event name of the emitter.\n * @returns A {@link AnyStateSelector} with all the properties set.\n *\n * @internal\n */\nfunction normalizeStateSelector(\n stateSelector: AnySimpleStateSelector | AnyStateSelector,\n event: XEvent\n): Required<AnyStateSelector> {\n const normalizedSelector = isSimpleSelector(stateSelector)\n ? { selector: stateSelector }\n : stateSelector;\n return {\n deep: false,\n immediate: false,\n filter: isSecondLevelEventEmitter(event)\n ? (newValue, oldValue) => !hasPayloadChanged(newValue, oldValue)\n : () => true,\n ...normalizedSelector\n };\n}\n\n/**\n * Checks if a the type of the store emitter selector is simple or complex. This selector can be\n * a function if it is simple or an object with the selector and other options if it is complex.\n *\n * @param stateSelector - The store emitter selector.\n * @returns A boolean which flags if the stateSelector is simple (function) or complex (object).\n *\n * @internal\n */\nexport function isSimpleSelector(\n stateSelector: AnySimpleStateSelector | AnyStateSelector\n): stateSelector is AnySimpleStateSelector {\n return typeof stateSelector === 'function';\n}\n\n// TODO: Generalize the Naming of the Events to take this into account\nconst secondLevelEvents: RegExp[] = [/RequestChanged$/, /UrlStateChanged$/];\n\n/**\n * Function to detect if an {@link XEvent} is a \"SecondLevelEvent\", to treat it differently.\n *\n * @param event - The name of the {@link XEvent} to check.\n * @returns True if is an `SecondLevelEvent`, False otherwise.\n *\n * @internal\n */\nfunction isSecondLevelEventEmitter(event: XEvent): boolean {\n return secondLevelEvents.some(regex => regex.test(event));\n}\n/**\n * Function to filter if a payload of an {@link XEvent} has really changed or not. It only\n * compares the first level of fields and not deeply, to avoid CPU consuming task here.\n *\n * @param request1 - First request to compare.\n * @param request2 - Second request to compare.\n * @returns True if the two objects are different, false otherwise.\n *\n * @internal\n */\nfunction hasPayloadChanged<T extends Dictionary>(request1?: T, request2?: T): boolean {\n if (request1 === request2) {\n return true;\n }\n if (!request1 || !request2) {\n return false;\n }\n const keys1 = Object.keys(request1);\n const keys2 = Object.keys(request2);\n if (keys1.length !== keys2.length) {\n return false;\n }\n return !keys1.some(key => request1[key] !== request2[key]);\n}\n"],"names":[],"mappings":";;;;AAUA;;;;;;;;;;SAUgB,qBAAqB,CACnC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAc,EAChD,GAAS,EACT,KAAiB;IAEjB,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACrF,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,aAAwD;QACrF,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,sBAAsB,CACxE,aAAa,EACb,KAAK,CACN,CAAC;QAEF,MAAM,IAAI,GAAG,CACX,KAAkC,EAClC,QAAsC;YAEtC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;SACxD,CAAC;QACF,MAAM,eAAe,GAAG,MACtB,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,qBAAqB,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ;YACtE,IAAI,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;gBAC9B,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;aAC1B;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;QAEvD,IAAI,SAAS,EAAE;YACb,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC;gBACrB,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;aACzB,CAAC,CAAC;SACJ;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;AAUA,SAAS,qBAAqB,CAC5B,KAAY,EACZ,aAAuF;;;;;;;;;IAUvF,IAAI,aAAa,GAAqC,SAAS,CAAC;IAEhE,IAAI,eAAe,GAAG,QAAQ,CAC5B,CAAC,QAA8B,EAAE,QAA8B;QAC7D,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClC,aAAa,GAAG,SAAS,CAAC;KAC3B,EACD,CAAC,CACF,CAAC;;;;IAIF,IAAI,yBAAyB,CAAC,KAAK,CAAC,EAAE;QACpC,MAAM,gBAAgB,GAAG,eAAe,CAAC;QACzC,MAAM,yBAAyB,GAAG,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAChE,eAAe,IAAI,CAAC,CAAC,EAAE,CAAC;YACtB,gBAAgB,CAAC,MAAM,EAAE,CAAC;YAC1B,yBAAyB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACjC,CAA2B,CAAC;KAC9B;IAED,OAAO,CAAC,QAAQ,EAAE,QAAQ;QACxB,aAAa,GAAG,aAAa,KAAK,SAAS,GAAG,aAAa,GAAG,QAAQ,CAAC;QACvE,eAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;AAUA,SAAS,sBAAsB,CAC7B,aAAwD,EACxD,KAAa;IAEb,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,aAAa,CAAC;UACtD,EAAE,QAAQ,EAAE,aAAa,EAAE;UAC3B,aAAa,CAAC;IAClB,OAAO;QACL,IAAI,EAAE,KAAK;QACX,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,yBAAyB,CAAC,KAAK,CAAC;cACpC,CAAC,QAAQ,EAAE,QAAQ,KAAK,CAAC,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC;cAC9D,MAAM,IAAI;QACd,GAAG,kBAAkB;KACtB,CAAC;AACJ,CAAC;AAED;;;;;;;;;SASgB,gBAAgB,CAC9B,aAAwD;IAExD,OAAO,OAAO,aAAa,KAAK,UAAU,CAAC;AAC7C,CAAC;AAED;AACA,MAAM,iBAAiB,GAAa,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;AAE5E;;;;;;;;AAQA,SAAS,yBAAyB,CAAC,KAAa;IAC9C,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5D,CAAC;AACD;;;;;;;;;;AAUA,SAAS,iBAAiB,CAAuB,QAAY,EAAE,QAAY;IACzE,IAAI,QAAQ,KAAK,QAAQ,EAAE;QACzB,OAAO,IAAI,CAAC;KACb;IACD,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE;QAC1B,OAAO,KAAK,CAAC;KACd;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;QACjC,OAAO,KAAK,CAAC;KACd;IACD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D;;;;"}
1
+ {"version":3,"file":"x-emitters.js","sources":["../../../src/plugins/x-emitters.ts"],"sourcesContent":["import { forEach, Dictionary } from '@empathyco/x-utils';\nimport { Store } from 'vuex';\nimport { getGettersProxyFromModule } from '../store/utils/getters-proxy.utils';\nimport { AnySimpleStateSelector, AnyStateSelector } from '../store/utils/store-emitters.utils';\nimport { debounce } from '../utils/debounce';\nimport { DebouncedFunction } from '../utils/types';\nimport { XEvent, XEventPayload } from '../wiring/events.types';\nimport { AnyXModule } from '../x-modules/x-modules.types';\nimport { XBus } from './x-bus.types';\n\n/**\n * Registers the store emitters, making them emit the event when the part of the state selected\n * changes.\n *\n * @param xModule - The {@link XModule} to register its Store Emitters.\n * @param bus - The {@Link XBus} to emit the events by the Emitters.\n * @param store - The Vuex store to access to state and getters to watch them.\n *\n * @internal\n */\nexport function registerStoreEmitters(\n { name, storeEmitters, storeModule }: AnyXModule,\n bus: XBus,\n store: Store<any>\n): void {\n const safeGettersProxy = getGettersProxyFromModule(store.getters, name, storeModule);\n forEach(storeEmitters, (event, stateSelector: AnySimpleStateSelector | AnyStateSelector) => {\n const { selector, immediate, filter, ...options } = normalizeStateSelector(\n stateSelector,\n event\n );\n\n const watcherSelector = (): XEventPayload<typeof event> =>\n selector(store.state.x[name], safeGettersProxy);\n const emit = debounceWatcherEffect(event, (newValue, oldValue) => {\n if (filter(newValue, oldValue)) {\n bus.emit(event, newValue, { moduleName: name, oldValue });\n }\n });\n\n store.watch(watcherSelector, emit, options);\n\n if (immediate) {\n emit(watcherSelector());\n }\n });\n}\n\n/**\n * This function \"wraps\" the watcher effect (the callback of the watcher) with debounce to avoid\n * repeating events and request. Right now this function wraps every effect in a debounce and adds\n * an extra debounce to the \"SecondLevelEvent\" events, to try to delay this events after the state\n * change events.\n *\n * @param event - The {@link XEvent} to emit.\n * @param watcherEffect - The callback to execute.\n * @returns A new function with the `watcherEffect` callback wrapped in debounce.\n */\nfunction debounceWatcherEffect<Event extends XEvent = XEvent>(\n event: Event,\n watcherEffect: (newValue: XEventPayload<Event>, oldValue: XEventPayload<Event>) => void\n): (newValue: XEventPayload<Event>, oldValue: XEventPayload<Event>) => void {\n /*\n * Due the debounce added to the watch callback, the `oldValue` would be the one from the last\n * watcher execution instead of the last callback execution. This would cause problems receiving\n * unstable oldValues, used in the Emitter filter.\n * To solve this, we store the `oldValue` of the watcher in the `previousValue` variable, and we\n * keep there until the watcher callback is finally executed (after the debounce). Then this\n * `previousValue` is cleared to store the next `oldValue`.\n */\n let previousValue: XEventPayload<Event> | undefined = undefined;\n\n let watcherCallback = debounce(\n (newValue: XEventPayload<Event>, oldValue: XEventPayload<Event>): void => {\n watcherEffect(newValue, oldValue);\n previousValue = undefined;\n },\n 0\n );\n /* Only applying the extra debounce to the \"SecondLevelEvent\" events to avoid repeating outer\n * effects (requests, URL changes). If we only apply the debounce to all the events we still have\n * the problem of outer effects. */\n if (isSecondLevelEventEmitter(event)) {\n const previousCallback = watcherCallback;\n const debouncedPreviousCallback = debounce(previousCallback, 0);\n watcherCallback = ((n, o) => {\n previousCallback.cancel();\n debouncedPreviousCallback(n, o);\n }) as DebouncedFunction<any>;\n }\n\n return (newValue, oldValue) => {\n previousValue = previousValue !== undefined ? previousValue : oldValue;\n watcherCallback(newValue, previousValue);\n };\n}\n\n/**\n * Transforms a {@link AnySimpleStateSelector} into a {@link AnyStateSelector}, and sets\n * default values for its properties.\n *\n * @param stateSelector - The state selector to normalize.\n * @param event - The event name of the emitter.\n * @returns A {@link AnyStateSelector} with all the properties set.\n *\n * @internal\n */\nfunction normalizeStateSelector(\n stateSelector: AnySimpleStateSelector | AnyStateSelector,\n event: XEvent\n): Required<AnyStateSelector> {\n const normalizedSelector = isSimpleSelector(stateSelector)\n ? { selector: stateSelector }\n : stateSelector;\n return {\n deep: false,\n immediate: false,\n filter: isSecondLevelEventEmitter(event)\n ? (newValue, oldValue) => !hasPayloadChanged(newValue, oldValue)\n : () => true,\n ...normalizedSelector\n };\n}\n\n/**\n * Checks if a the type of the store emitter selector is simple or complex. This selector can be\n * a function if it is simple or an object with the selector and other options if it is complex.\n *\n * @param stateSelector - The store emitter selector.\n * @returns A boolean which flags if the stateSelector is simple (function) or complex (object).\n *\n * @internal\n */\nexport function isSimpleSelector(\n stateSelector: AnySimpleStateSelector | AnyStateSelector\n): stateSelector is AnySimpleStateSelector {\n return typeof stateSelector === 'function';\n}\n\n// TODO: Generalize the Naming of the Events to take this into account\nconst secondLevelEvents: RegExp[] = [/RequestChanged$/, /UrlStateChanged$/];\n\n/**\n * Function to detect if an {@link XEvent} is a \"SecondLevelEvent\", to treat it differently.\n *\n * @param event - The name of the {@link XEvent} to check.\n * @returns True if is an `SecondLevelEvent`, False otherwise.\n *\n * @internal\n */\nfunction isSecondLevelEventEmitter(event: XEvent): boolean {\n return secondLevelEvents.some(regex => regex.test(event));\n}\n/**\n * Function to filter if a payload of an {@link XEvent} has really changed or not. It only\n * compares the first level of fields and not deeply, to avoid CPU consuming task here.\n *\n * @param request1 - First request to compare.\n * @param request2 - Second request to compare.\n * @returns True if the two objects are different, false otherwise.\n *\n * @internal\n */\nfunction hasPayloadChanged<T extends Dictionary>(request1?: T, request2?: T): boolean {\n if (request1 === request2) {\n return true;\n }\n if (!request1 || !request2) {\n return false;\n }\n const keys1 = Object.keys(request1);\n const keys2 = Object.keys(request2);\n if (keys1.length !== keys2.length) {\n return false;\n }\n return !keys1.some(key => request1[key] !== request2[key]);\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"query-preview.vue.js","sources":["../../../../../src/x-modules/queries-preview/components/query-preview.vue"],"sourcesContent":["<template>\n <NoElement v-if=\"queryPreviewResults && queryPreviewResults.totalResults\">\n <!--\n @slot Query Preview default slot.\n @binding {string} query - query\n @binding {Result[]} results - The results preview of the query preview\n @binding {number} totalResults - The total results of the search request\n -->\n <slot\n :query=\"query\"\n :results=\"queryPreviewResults.results\"\n :totalResults=\"queryPreviewResults.totalResults\"\n >\n <ul data-test=\"query-preview\" class=\"x-query-preview\">\n <li\n v-for=\"result in queryPreviewResults.results\"\n :key=\"result.id\"\n class=\"x-query-preview__item\"\n data-test=\"query-preview-item\"\n >\n <!--\n @slot Query Preview result slot.\n @binding {Result} result - A Query Preview result\n -->\n <slot name=\"result\" :result=\"result\">\n <span data-test=\"result-name\">{{ result.name }}</span>\n </slot>\n </li>\n </ul>\n </slot>\n </NoElement>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop, Inject } from 'vue-property-decorator';\n import { Dictionary } from '@empathyco/x-utils';\n import { SearchRequest, Result } from '@empathyco/x-types';\n import { State } from '../../../components/decorators/store.decorators';\n import { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts';\n import { XProvide } from '../../../components/decorators/injection.decorators';\n import { XEmit } from '../../../components/decorators/bus.decorators';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { NoElement } from '../../../components/no-element';\n import { QueryFeature, FeatureLocation } from '../../../types/origin';\n import { QueryPreviewItem } from '../store/types';\n import { QueriesPreviewConfig } from '../config.types';\n import { queriesPreviewXModule } from '../x-module';\n import { createOrigin } from '../../../utils/origin';\n\n /**\n * Retrieves a preview of the results of a query and exposes them in the default slot,\n * along with the query preview and the totalResults of the search request.\n * By default, it renders the names of the results.\n *\n * @public\n */\n @Component({\n components: {\n NoElement\n },\n mixins: [xComponentMixin(queriesPreviewXModule)]\n })\n export default class QueryPreview extends Vue {\n /**\n * The query to retrieve the results preview.\n *\n * @public\n */\n @Prop({\n required: true\n })\n protected query!: string;\n\n /**.\n * The origin property for the request\n *\n * @public\n */\n @Prop()\n protected queryFeature?: QueryFeature;\n\n /**\n * Number of query preview results to be rendered.\n *\n * @public\n */\n @Prop()\n protected maxItemsToRender?: number;\n\n /**\n * The results preview of the queries preview mounted.\n * It is a dictionary, indexed by the query preview query.\n */\n @State('queriesPreview', 'queriesPreview')\n public previewResults!: Dictionary<QueryPreviewItem>;\n\n /**\n * As the request is handled in this component, we need\n * the extra params that will be used in the request.\n */\n @State('queriesPreview', 'params')\n public params!: Dictionary<unknown>;\n\n /**\n * As the request is handled in this component, we need\n * the config that will be used in the request.\n */\n @State('queriesPreview', 'config')\n public config!: QueriesPreviewConfig;\n\n /**\n * The results to render from the state.\n *\n * @remarks The results list are provided with `items` key. It can be\n * concatenated with list items from components such as `BannersList`, `PromotedsList`,\n * `BaseGrid` or any component that injects the list.\n *\n * @returns A list of results.\n * @public\n */\n @XProvide(LIST_ITEMS_KEY)\n public get results(): Result[] | undefined {\n return this.queryPreviewResults?.results;\n }\n\n /**\n * It injects the provided {@link FeatureLocation} of the selected query in the search request.\n *\n * @internal\n */\n @Inject()\n public location?: FeatureLocation;\n\n /**\n * The computed request object to be used to retrieve the query preview results.\n *\n * @returns The search request object.\n * @public\n */\n @XEmit('QueryPreviewRequestChanged', { immediate: false })\n public get queryPreviewRequest(): SearchRequest {\n const origin = createOrigin({\n feature: this.queryFeature,\n location: this.location\n });\n\n return {\n query: this.query,\n rows: this.config.maxItemsToRequest,\n extraParams: this.params,\n ...(origin && { origin })\n };\n }\n\n protected mounted(): void {\n this.$x.emit('QueryPreviewRequestChanged', this.queryPreviewRequest);\n }\n\n /**\n * Gets from the state the results preview of the query preview.\n *\n * @returns The results preview of the actual query preview.\n */\n public get queryPreviewResults(): Partial<QueryPreviewItem> | undefined {\n const previewResults = this.previewResults[this.query];\n return previewResults?.results\n ? {\n totalResults: previewResults.totalResults,\n results: previewResults.results.slice(0, this.maxItemsToRender)\n }\n : undefined;\n }\n }\n</script>\n<docs lang=\"mdx\">\n## Events\n\nA list of events that the component will emit:\n\n- `QueryPreviewRequestChanged`: the event is emitted when the component is mounted and when the\n properties of the request object changes. The event payload is the `queryPreviewRequest` object.\n\n## See it in action\n\nHere you have a basic example of how the QueryPreview is rendered. Keep in mind that this component\nis intended to be used overriding its default slot. By default it will only render the names of the\nresults.\n\n```vue live\n<template>\n <QueryPreview :query=\"query\" />\n</template>\n\n<script>\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n\n export default {\n name: 'QueryPreviewDemo',\n components: {\n QueryPreview\n },\n data() {\n return {\n query: 'sandals'\n };\n }\n };\n</script>\n```\n\n### Play with the default slot\n\nIn this example, the results will be rendered inside a sliding panel.\n\n```vue live\n<template>\n <QueryPreview :query=\"query\" #default=\"{ totalResults, results }\">\n <section>\n <p>Total results: {{ totalResults }}</p>\n <SlidingPanel :resetOnContentChange=\"false\">\n <article\n v-for=\"result in results\"\n :key=\"result.id\"\n class=\"x-result\"\n style=\"max-width: 300px; overflow: hidden\"\n >\n <BaseResultLink :result=\"result\">\n <BaseResultImage :result=\"result\" class=\"x-result__picture\" />\n </BaseResultLink>\n <div class=\"x-result__description\">\n <BaseResultLink :result=\"result\">\n <h1 class=\"x-title3\">{{ result.name }}</h1>\n </BaseResultLink>\n </div>\n </article>\n </SlidingPanel>\n </section>\n </QueryPreview>\n</template>\n\n<script>\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n import { BaseResultImage, BaseResultLink, SlidingPanel } from '@empathyco/x-components';\n\n export default {\n name: 'QueryPreviewDemoOverridingSlot',\n components: {\n BaseResultImage,\n BaseResultLink,\n QueryPreview,\n SlidingPanel\n },\n data() {\n return {\n query: 'flip-flops'\n };\n }\n };\n</script>\n```\n\n### Play with the result slot\n\nThe component exposes a slot to override the result content, without modifying the list.\n\nIn this example, the ID of the results will be rendered along with the name.\n\n```vue\n<template>\n <QueryPreview :query=\"query\" #result=\"{ result }\">\n <span>{{ result.id }}</span>\n <span>{{ result.name }}</span>\n </QueryPreview>\n</template>\n\n<script>\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n\n export default {\n name: 'QueryPreviewDemoOverridingResultSlot',\n components: {\n QueryPreview\n },\n data() {\n return {\n query: 'flips-flops'\n };\n }\n };\n</script>\n```\n\n### Play with props\n\nIn this example, the query preview has been limited to render a maximum of 4 results.\n\n```vue\n<template>\n <QueryPreview :maxItemsToRender=\"maxItemsToRender\" :query=\"query\" #default=\"{ results }\">\n <BaseGrid #default=\"{ item }\" :items=\"results\">\n <BaseResultLink :result=\"item\">\n <BaseResultImage :result=\"item\" />\n </BaseResultLink>\n </BaseGrid>\n </QueryPreview>\n</template>\n\n<script>\n import { BaseGrid, BaseResultImage, BaseResultLink } from '@empathyco/x-components';\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n\n export default {\n name: 'QueryPreviewDemo',\n components: {\n BaseGrid,\n BaseResultImage,\n BaseResultLink,\n QueryPreview\n },\n data() {\n return {\n maxItemsToRender: 4,\n query: 'flips-flops'\n };\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"query-preview.vue.js","sources":["../../../../../src/x-modules/queries-preview/components/query-preview.vue"],"sourcesContent":["<template>\n <NoElement v-if=\"queryPreviewResults && queryPreviewResults.totalResults\">\n <!--\n @slot Query Preview default slot.\n @binding {string} query - query\n @binding {Result[]} results - The results preview of the query preview\n @binding {number} totalResults - The total results of the search request\n -->\n <slot\n :query=\"query\"\n :results=\"queryPreviewResults.results\"\n :totalResults=\"queryPreviewResults.totalResults\"\n >\n <ul data-test=\"query-preview\" class=\"x-query-preview\">\n <li\n v-for=\"result in queryPreviewResults.results\"\n :key=\"result.id\"\n class=\"x-query-preview__item\"\n data-test=\"query-preview-item\"\n >\n <!--\n @slot Query Preview result slot.\n @binding {Result} result - A Query Preview result\n -->\n <slot name=\"result\" :result=\"result\">\n <span data-test=\"result-name\">{{ result.name }}</span>\n </slot>\n </li>\n </ul>\n </slot>\n </NoElement>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop, Inject, Watch } from 'vue-property-decorator';\n import { Dictionary } from '@empathyco/x-utils';\n import { SearchRequest, Result } from '@empathyco/x-types';\n import { State } from '../../../components/decorators/store.decorators';\n import { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts';\n import { XProvide } from '../../../components/decorators/injection.decorators';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { NoElement } from '../../../components/no-element';\n import { QueryFeature, FeatureLocation } from '../../../types/origin';\n import { QueryPreviewItem } from '../store/types';\n import { QueriesPreviewConfig } from '../config.types';\n import { queriesPreviewXModule } from '../x-module';\n import { createOrigin } from '../../../utils/origin';\n import { debounce } from '../../../utils/debounce';\n import { DebouncedFunction } from '../../../utils';\n\n /**\n * Retrieves a preview of the results of a query and exposes them in the default slot,\n * along with the query preview and the totalResults of the search request.\n * By default, it renders the names of the results.\n *\n * @public\n */\n @Component({\n components: {\n NoElement\n },\n mixins: [xComponentMixin(queriesPreviewXModule)]\n })\n export default class QueryPreview extends Vue {\n /**\n * The query to retrieve the results preview.\n *\n * @public\n */\n @Prop({\n required: true\n })\n protected query!: string;\n\n /**\n * The origin property for the request.\n *\n * @public\n */\n @Prop()\n protected queryFeature?: QueryFeature;\n\n /**\n * Number of query preview results to be rendered.\n *\n * @public\n */\n @Prop()\n protected maxItemsToRender?: number;\n\n /**\n * Debounce time in milliseconds for triggering the search requests.\n * It will default to 0 to fit the most common use case (pre-search),\n * and it would work properly with a 250 value inside empathize.\n */\n @Prop({ default: 0 })\n public debounceTimeMs!: number;\n\n /**\n * The results preview of the queries preview mounted.\n * It is a dictionary, indexed by the query preview query.\n */\n @State('queriesPreview', 'queriesPreview')\n public previewResults!: Dictionary<QueryPreviewItem>;\n\n /**\n * As the request is handled in this component, we need\n * the extra params that will be used in the request.\n */\n @State('queriesPreview', 'params')\n public params!: Dictionary<unknown>;\n\n /**\n * As the request is handled in this component, we need\n * the config that will be used in the request.\n */\n @State('queriesPreview', 'config')\n public config!: QueriesPreviewConfig;\n\n /**\n * The results to render from the state.\n *\n * @remarks The results list are provided with `items` key. It can be\n * concatenated with list items from components such as `BannersList`, `PromotedsList`,\n * `BaseGrid` or any component that injects the list.\n *\n * @returns A list of results.\n * @public\n */\n @XProvide(LIST_ITEMS_KEY)\n public get results(): Result[] | undefined {\n return this.queryPreviewResults?.results;\n }\n\n /**\n * It injects the provided {@link FeatureLocation} of the selected query in the search request.\n *\n * @internal\n */\n @Inject({ default: undefined })\n protected location?: FeatureLocation;\n\n /**\n * The computed request object to be used to retrieve the query preview results.\n *\n * @returns The search request object.\n * @internal\n */\n protected get queryPreviewRequest(): SearchRequest {\n const origin = createOrigin({\n feature: this.queryFeature,\n location: this.location\n });\n\n return {\n query: this.query,\n rows: this.config.maxItemsToRequest,\n extraParams: this.params,\n ...(origin && { origin })\n };\n }\n\n /**\n * The debounce method to trigger the request after the debounceTimeMs defined.\n *\n * @returns The search request object.\n * @internal\n */\n protected get emitQueryPreviewRequestChanged(): DebouncedFunction<[SearchRequest]> {\n return debounce(request => {\n this.$x.emit('QueryPreviewRequestChanged', request);\n }, this.debounceTimeMs);\n }\n\n /**\n * Initialises watcher to emit debounced requests, and first value for the requests.\n *\n * @internal\n */\n protected created(): void {\n this.$watch(\n () => this.queryPreviewRequest,\n request => this.emitQueryPreviewRequestChanged(request)\n );\n this.emitQueryPreviewRequestChanged(this.queryPreviewRequest);\n }\n\n /**\n * Cancels the (remaining) requests when the component is destroyed\n * via the `debounce.cancel()` method.\n *\n * @internal\n */\n protected beforeDestroy(): void {\n this.emitQueryPreviewRequestChanged.cancel();\n }\n\n /**\n * Cancels the previous request when the debounced function changes (e.g: the debounceTimeMs\n * prop changes or there is a request in progress that cancels it).\n *\n * @param _new - The new debounced function.\n * @param old - The previous debounced function.\n * @internal\n */\n @Watch('emitQueryPreviewRequestChanged')\n protected cancelEmitPreviewRequestChanged(\n _new: DebouncedFunction<[SearchRequest]>,\n old: DebouncedFunction<[SearchRequest]>\n ): void {\n old.cancel();\n }\n\n /**\n * Gets from the state the results preview of the query preview.\n *\n * @returns The results preview of the actual query preview.\n */\n public get queryPreviewResults(): Partial<QueryPreviewItem> | undefined {\n const previewResults = this.previewResults[this.query];\n return previewResults?.results\n ? {\n totalResults: previewResults.totalResults,\n results: previewResults.results.slice(0, this.maxItemsToRender)\n }\n : undefined;\n }\n }\n</script>\n<docs lang=\"mdx\">\n## Events\n\nA list of events that the component will emit:\n\n- `QueryPreviewRequestChanged`: the event is emitted when the component is mounted and when the\n properties of the request object changes. The event payload is the `queryPreviewRequest` object.\n\n## See it in action\n\nHere you have a basic example of how the QueryPreview is rendered. Keep in mind that this component\nis intended to be used overriding its default slot. By default it will only render the names of the\nresults.\n\n```vue live\n<template>\n <QueryPreview :query=\"query\" />\n</template>\n\n<script>\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n\n export default {\n name: 'QueryPreviewDemo',\n components: {\n QueryPreview\n },\n data() {\n return {\n query: 'sandals'\n };\n }\n };\n</script>\n```\n\n### Play with the default slot\n\nIn this example, the results will be rendered inside a sliding panel.\n\n```vue live\n<template>\n <QueryPreview :query=\"query\" #default=\"{ totalResults, results }\">\n <section>\n <p>Total results: {{ totalResults }}</p>\n <SlidingPanel :resetOnContentChange=\"false\">\n <article\n v-for=\"result in results\"\n :key=\"result.id\"\n class=\"x-result\"\n style=\"max-width: 300px; overflow: hidden\"\n >\n <BaseResultLink :result=\"result\">\n <BaseResultImage :result=\"result\" class=\"x-result__picture\" />\n </BaseResultLink>\n <div class=\"x-result__description\">\n <BaseResultLink :result=\"result\">\n <h1 class=\"x-title3\">{{ result.name }}</h1>\n </BaseResultLink>\n </div>\n </article>\n </SlidingPanel>\n </section>\n </QueryPreview>\n</template>\n\n<script>\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n import { BaseResultImage, BaseResultLink, SlidingPanel } from '@empathyco/x-components';\n\n export default {\n name: 'QueryPreviewDemoOverridingSlot',\n components: {\n BaseResultImage,\n BaseResultLink,\n QueryPreview,\n SlidingPanel\n },\n data() {\n return {\n query: 'flip-flops'\n };\n }\n };\n</script>\n```\n\n### Play with the result slot\n\nThe component exposes a slot to override the result content, without modifying the list.\n\nIn this example, the ID of the results will be rendered along with the name.\n\n```vue\n<template>\n <QueryPreview :query=\"query\" #result=\"{ result }\">\n <span>{{ result.id }}</span>\n <span>{{ result.name }}</span>\n </QueryPreview>\n</template>\n\n<script>\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n\n export default {\n name: 'QueryPreviewDemoOverridingResultSlot',\n components: {\n QueryPreview\n },\n data() {\n return {\n query: 'flips-flops'\n };\n }\n };\n</script>\n```\n\n### Play with props\n\nIn this example, the query preview has been limited to render a maximum of 4 results.\n\n```vue\n<template>\n <QueryPreview :maxItemsToRender=\"maxItemsToRender\" :query=\"query\" #default=\"{ results }\">\n <BaseGrid #default=\"{ item }\" :items=\"results\">\n <BaseResultLink :result=\"item\">\n <BaseResultImage :result=\"item\" />\n </BaseResultLink>\n </BaseGrid>\n </QueryPreview>\n</template>\n\n<script>\n import { BaseGrid, BaseResultImage, BaseResultLink } from '@empathyco/x-components';\n import { QueryPreview } from '@empathyco/x-components/queries-preview';\n\n export default {\n name: 'QueryPreviewDemo',\n components: {\n BaseGrid,\n BaseResultImage,\n BaseResultLink,\n QueryPreview\n },\n data() {\n return {\n maxItemsToRender: 4,\n query: 'flips-flops'\n };\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,14 +1,14 @@
1
1
  import { __decorate } from 'tslib';
2
2
  import Vue from 'vue';
3
- import { Prop, Inject, Component } from 'vue-property-decorator';
3
+ import { Prop, Inject, Watch, Component } from 'vue-property-decorator';
4
4
  import { State } from '../../../components/decorators/store.decorators.js';
5
5
  import { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts.js';
6
6
  import { XProvide } from '../../../components/decorators/injection.decorators.js';
7
- import { XEmit } from '../../../components/decorators/bus.decorators.js';
8
7
  import { xComponentMixin } from '../../../components/x-component.mixin.js';
9
8
  import { NoElement } from '../../../components/no-element.js';
10
9
  import { queriesPreviewXModule } from '../x-module.js';
11
10
  import { createOrigin } from '../../../utils/origin.js';
11
+ import { debounce } from '../../../utils/debounce.js';
12
12
 
13
13
  /**
14
14
  * Retrieves a preview of the results of a query and exposes them in the default slot,
@@ -35,7 +35,7 @@ let QueryPreview = class QueryPreview extends Vue {
35
35
  * The computed request object to be used to retrieve the query preview results.
36
36
  *
37
37
  * @returns The search request object.
38
- * @public
38
+ * @internal
39
39
  */
40
40
  get queryPreviewRequest() {
41
41
  const origin = createOrigin({
@@ -49,8 +49,45 @@ let QueryPreview = class QueryPreview extends Vue {
49
49
  ...(origin && { origin })
50
50
  };
51
51
  }
52
- mounted() {
53
- this.$x.emit('QueryPreviewRequestChanged', this.queryPreviewRequest);
52
+ /**
53
+ * The debounce method to trigger the request after the debounceTimeMs defined.
54
+ *
55
+ * @returns The search request object.
56
+ * @internal
57
+ */
58
+ get emitQueryPreviewRequestChanged() {
59
+ return debounce(request => {
60
+ this.$x.emit('QueryPreviewRequestChanged', request);
61
+ }, this.debounceTimeMs);
62
+ }
63
+ /**
64
+ * Initialises watcher to emit debounced requests, and first value for the requests.
65
+ *
66
+ * @internal
67
+ */
68
+ created() {
69
+ this.$watch(() => this.queryPreviewRequest, request => this.emitQueryPreviewRequestChanged(request));
70
+ this.emitQueryPreviewRequestChanged(this.queryPreviewRequest);
71
+ }
72
+ /**
73
+ * Cancels the (remaining) requests when the component is destroyed
74
+ * via the `debounce.cancel()` method.
75
+ *
76
+ * @internal
77
+ */
78
+ beforeDestroy() {
79
+ this.emitQueryPreviewRequestChanged.cancel();
80
+ }
81
+ /**
82
+ * Cancels the previous request when the debounced function changes (e.g: the debounceTimeMs
83
+ * prop changes or there is a request in progress that cancels it).
84
+ *
85
+ * @param _new - The new debounced function.
86
+ * @param old - The previous debounced function.
87
+ * @internal
88
+ */
89
+ cancelEmitPreviewRequestChanged(_new, old) {
90
+ old.cancel();
54
91
  }
55
92
  /**
56
93
  * Gets from the state the results preview of the query preview.
@@ -78,6 +115,9 @@ __decorate([
78
115
  __decorate([
79
116
  Prop()
80
117
  ], QueryPreview.prototype, "maxItemsToRender", void 0);
118
+ __decorate([
119
+ Prop({ default: 0 })
120
+ ], QueryPreview.prototype, "debounceTimeMs", void 0);
81
121
  __decorate([
82
122
  State('queriesPreview', 'queriesPreview')
83
123
  ], QueryPreview.prototype, "previewResults", void 0);
@@ -91,11 +131,11 @@ __decorate([
91
131
  XProvide(LIST_ITEMS_KEY)
92
132
  ], QueryPreview.prototype, "results", null);
93
133
  __decorate([
94
- Inject()
134
+ Inject({ default: undefined })
95
135
  ], QueryPreview.prototype, "location", void 0);
96
136
  __decorate([
97
- XEmit('QueryPreviewRequestChanged', { immediate: false })
98
- ], QueryPreview.prototype, "queryPreviewRequest", null);
137
+ Watch('emitQueryPreviewRequestChanged')
138
+ ], QueryPreview.prototype, "cancelEmitPreviewRequestChanged", null);
99
139
  QueryPreview = __decorate([
100
140
  Component({
101
141
  components: {
@@ -1 +1 @@
1
- {"version":3,"file":"query-preview.vue_rollup-plugin-vue_script.vue.js","sources":["../../../../../src/x-modules/queries-preview/components/query-preview.vue?rollup-plugin-vue=script.ts"],"sourcesContent":["\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\nimport Vue from 'vue';\nimport { Component, Prop, Inject } from 'vue-property-decorator';\nimport { Dictionary } from '@empathyco/x-utils';\nimport { SearchRequest, Result } from '@empathyco/x-types';\nimport { State } from '../../../components/decorators/store.decorators';\nimport { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts';\nimport { XProvide } from '../../../components/decorators/injection.decorators';\nimport { XEmit } from '../../../components/decorators/bus.decorators';\nimport { xComponentMixin } from '../../../components/x-component.mixin';\nimport { NoElement } from '../../../components/no-element';\nimport { QueryFeature, FeatureLocation } from '../../../types/origin';\nimport { QueryPreviewItem } from '../store/types';\nimport { QueriesPreviewConfig } from '../config.types';\nimport { queriesPreviewXModule } from '../x-module';\nimport { createOrigin } from '../../../utils/origin';\n\n/**\n * Retrieves a preview of the results of a query and exposes them in the default slot,\n * along with the query preview and the totalResults of the search request.\n * By default, it renders the names of the results.\n *\n * @public\n */\n@Component({\n components: {\n NoElement\n },\n mixins: [xComponentMixin(queriesPreviewXModule)]\n})\nexport default class QueryPreview extends Vue {\n /**\n * The query to retrieve the results preview.\n *\n * @public\n */\n @Prop({\n required: true\n })\n protected query!: string;\n\n /**.\n * The origin property for the request\n *\n * @public\n */\n @Prop()\n protected queryFeature?: QueryFeature;\n\n /**\n * Number of query preview results to be rendered.\n *\n * @public\n */\n @Prop()\n protected maxItemsToRender?: number;\n\n /**\n * The results preview of the queries preview mounted.\n * It is a dictionary, indexed by the query preview query.\n */\n @State('queriesPreview', 'queriesPreview')\n public previewResults!: Dictionary<QueryPreviewItem>;\n\n /**\n * As the request is handled in this component, we need\n * the extra params that will be used in the request.\n */\n @State('queriesPreview', 'params')\n public params!: Dictionary<unknown>;\n\n /**\n * As the request is handled in this component, we need\n * the config that will be used in the request.\n */\n @State('queriesPreview', 'config')\n public config!: QueriesPreviewConfig;\n\n /**\n * The results to render from the state.\n *\n * @remarks The results list are provided with `items` key. It can be\n * concatenated with list items from components such as `BannersList`, `PromotedsList`,\n * `BaseGrid` or any component that injects the list.\n *\n * @returns A list of results.\n * @public\n */\n @XProvide(LIST_ITEMS_KEY)\n public get results(): Result[] | undefined {\n return this.queryPreviewResults?.results;\n }\n\n /**\n * It injects the provided {@link FeatureLocation} of the selected query in the search request.\n *\n * @internal\n */\n @Inject()\n public location?: FeatureLocation;\n\n /**\n * The computed request object to be used to retrieve the query preview results.\n *\n * @returns The search request object.\n * @public\n */\n @XEmit('QueryPreviewRequestChanged', { immediate: false })\n public get queryPreviewRequest(): SearchRequest {\n const origin = createOrigin({\n feature: this.queryFeature,\n location: this.location\n });\n\n return {\n query: this.query,\n rows: this.config.maxItemsToRequest,\n extraParams: this.params,\n ...(origin && { origin })\n };\n }\n\n protected mounted(): void {\n this.$x.emit('QueryPreviewRequestChanged', this.queryPreviewRequest);\n }\n\n /**\n * Gets from the state the results preview of the query preview.\n *\n * @returns The results preview of the actual query preview.\n */\n public get queryPreviewResults(): Partial<QueryPreviewItem> | undefined {\n const previewResults = this.previewResults[this.query];\n return previewResults?.results\n ? {\n totalResults: previewResults.totalResults,\n results: previewResults.results.slice(0, this.maxItemsToRender)\n }\n : undefined;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAkDA;;;;;;;AAaA,IAAqB,YAAY,GAAjC,MAAqB,YAAa,SAAQ,GAAG;;;;;;;;;;;IA2D3C,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC;KAC1C;;;;;;;IAiBD,IAAW,mBAAmB;QAC5B,MAAM,MAAM,GAAG,YAAY,CAAC;YAC1B,OAAO,EAAE,IAAI,CAAC,YAAY;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QAEH,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;YACnC,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,IAAI,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;SAC1B,CAAC;KACH;IAES,OAAO;QACf,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,4BAA4B,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;KACtE;;;;;;IAOD,IAAW,mBAAmB;QAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,OAAO,cAAc,EAAE,OAAO;cAC1B;gBACE,YAAY,EAAE,cAAc,CAAC,YAAY;gBACzC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC;aAChE;cACD,SAAS,CAAC;KACf;CACF,CAAA;AArGC;IAHC,IAAI,CAAC;QACJ,QAAQ,EAAE,IAAI;KACf,CAAC;2CACuB;AAQzB;IADC,IAAI,EAAE;kDAC+B;AAQtC;IADC,IAAI,EAAE;sDAC6B;AAOpC;IADC,KAAK,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;oDACW;AAOrD;IADC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC;4CACE;AAOpC;IADC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC;4CACG;AAarC;IADC,QAAQ,CAAC,cAAc,CAAC;2CAGxB;AAQD;IADC,MAAM,EAAE;8CACyB;AASlC;IADC,KAAK,CAAC,4BAA4B,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;uDAazD;AA1FkB,YAAY;IANhC,SAAS,CAAC;QACT,UAAU,EAAE;YACV,SAAS;SACV;QACD,MAAM,EAAE,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC;KACjD,CAAC;GACmB,YAAY,CA8GhC;aA9GoB,YAAY;;;;"}
1
+ {"version":3,"file":"query-preview.vue_rollup-plugin-vue_script.vue.js","sources":["../../../../../src/x-modules/queries-preview/components/query-preview.vue?rollup-plugin-vue=script.ts"],"sourcesContent":["\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\nimport Vue from 'vue';\nimport { Component, Prop, Inject, Watch } from 'vue-property-decorator';\nimport { Dictionary } from '@empathyco/x-utils';\nimport { SearchRequest, Result } from '@empathyco/x-types';\nimport { State } from '../../../components/decorators/store.decorators';\nimport { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts';\nimport { XProvide } from '../../../components/decorators/injection.decorators';\nimport { xComponentMixin } from '../../../components/x-component.mixin';\nimport { NoElement } from '../../../components/no-element';\nimport { QueryFeature, FeatureLocation } from '../../../types/origin';\nimport { QueryPreviewItem } from '../store/types';\nimport { QueriesPreviewConfig } from '../config.types';\nimport { queriesPreviewXModule } from '../x-module';\nimport { createOrigin } from '../../../utils/origin';\nimport { debounce } from '../../../utils/debounce';\nimport { DebouncedFunction } from '../../../utils';\n\n/**\n * Retrieves a preview of the results of a query and exposes them in the default slot,\n * along with the query preview and the totalResults of the search request.\n * By default, it renders the names of the results.\n *\n * @public\n */\n@Component({\n components: {\n NoElement\n },\n mixins: [xComponentMixin(queriesPreviewXModule)]\n})\nexport default class QueryPreview extends Vue {\n /**\n * The query to retrieve the results preview.\n *\n * @public\n */\n @Prop({\n required: true\n })\n protected query!: string;\n\n /**\n * The origin property for the request.\n *\n * @public\n */\n @Prop()\n protected queryFeature?: QueryFeature;\n\n /**\n * Number of query preview results to be rendered.\n *\n * @public\n */\n @Prop()\n protected maxItemsToRender?: number;\n\n /**\n * Debounce time in milliseconds for triggering the search requests.\n * It will default to 0 to fit the most common use case (pre-search),\n * and it would work properly with a 250 value inside empathize.\n */\n @Prop({ default: 0 })\n public debounceTimeMs!: number;\n\n /**\n * The results preview of the queries preview mounted.\n * It is a dictionary, indexed by the query preview query.\n */\n @State('queriesPreview', 'queriesPreview')\n public previewResults!: Dictionary<QueryPreviewItem>;\n\n /**\n * As the request is handled in this component, we need\n * the extra params that will be used in the request.\n */\n @State('queriesPreview', 'params')\n public params!: Dictionary<unknown>;\n\n /**\n * As the request is handled in this component, we need\n * the config that will be used in the request.\n */\n @State('queriesPreview', 'config')\n public config!: QueriesPreviewConfig;\n\n /**\n * The results to render from the state.\n *\n * @remarks The results list are provided with `items` key. It can be\n * concatenated with list items from components such as `BannersList`, `PromotedsList`,\n * `BaseGrid` or any component that injects the list.\n *\n * @returns A list of results.\n * @public\n */\n @XProvide(LIST_ITEMS_KEY)\n public get results(): Result[] | undefined {\n return this.queryPreviewResults?.results;\n }\n\n /**\n * It injects the provided {@link FeatureLocation} of the selected query in the search request.\n *\n * @internal\n */\n @Inject({ default: undefined })\n protected location?: FeatureLocation;\n\n /**\n * The computed request object to be used to retrieve the query preview results.\n *\n * @returns The search request object.\n * @internal\n */\n protected get queryPreviewRequest(): SearchRequest {\n const origin = createOrigin({\n feature: this.queryFeature,\n location: this.location\n });\n\n return {\n query: this.query,\n rows: this.config.maxItemsToRequest,\n extraParams: this.params,\n ...(origin && { origin })\n };\n }\n\n /**\n * The debounce method to trigger the request after the debounceTimeMs defined.\n *\n * @returns The search request object.\n * @internal\n */\n protected get emitQueryPreviewRequestChanged(): DebouncedFunction<[SearchRequest]> {\n return debounce(request => {\n this.$x.emit('QueryPreviewRequestChanged', request);\n }, this.debounceTimeMs);\n }\n\n /**\n * Initialises watcher to emit debounced requests, and first value for the requests.\n *\n * @internal\n */\n protected created(): void {\n this.$watch(\n () => this.queryPreviewRequest,\n request => this.emitQueryPreviewRequestChanged(request)\n );\n this.emitQueryPreviewRequestChanged(this.queryPreviewRequest);\n }\n\n /**\n * Cancels the (remaining) requests when the component is destroyed\n * via the `debounce.cancel()` method.\n *\n * @internal\n */\n protected beforeDestroy(): void {\n this.emitQueryPreviewRequestChanged.cancel();\n }\n\n /**\n * Cancels the previous request when the debounced function changes (e.g: the debounceTimeMs\n * prop changes or there is a request in progress that cancels it).\n *\n * @param _new - The new debounced function.\n * @param old - The previous debounced function.\n * @internal\n */\n @Watch('emitQueryPreviewRequestChanged')\n protected cancelEmitPreviewRequestChanged(\n _new: DebouncedFunction<[SearchRequest]>,\n old: DebouncedFunction<[SearchRequest]>\n ): void {\n old.cancel();\n }\n\n /**\n * Gets from the state the results preview of the query preview.\n *\n * @returns The results preview of the actual query preview.\n */\n public get queryPreviewResults(): Partial<QueryPreviewItem> | undefined {\n const previewResults = this.previewResults[this.query];\n return previewResults?.results\n ? {\n totalResults: previewResults.totalResults,\n results: previewResults.results.slice(0, this.maxItemsToRender)\n }\n : undefined;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAmDA;;;;;;;AAaA,IAAqB,YAAY,GAAjC,MAAqB,YAAa,SAAQ,GAAG;;;;;;;;;;;IAmE3C,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC;KAC1C;;;;;;;IAgBD,IAAc,mBAAmB;QAC/B,MAAM,MAAM,GAAG,YAAY,CAAC;YAC1B,OAAO,EAAE,IAAI,CAAC,YAAY;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QAEH,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;YACnC,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,IAAI,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;SAC1B,CAAC;KACH;;;;;;;IAQD,IAAc,8BAA8B;QAC1C,OAAO,QAAQ,CAAC,OAAO;YACrB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,4BAA4B,EAAE,OAAO,CAAC,CAAC;SACrD,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;KACzB;;;;;;IAOS,OAAO;QACf,IAAI,CAAC,MAAM,CACT,MAAM,IAAI,CAAC,mBAAmB,EAC9B,OAAO,IAAI,IAAI,CAAC,8BAA8B,CAAC,OAAO,CAAC,CACxD,CAAC;QACF,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;KAC/D;;;;;;;IAQS,aAAa;QACrB,IAAI,CAAC,8BAA8B,CAAC,MAAM,EAAE,CAAC;KAC9C;;;;;;;;;IAWS,+BAA+B,CACvC,IAAwC,EACxC,GAAuC;QAEvC,GAAG,CAAC,MAAM,EAAE,CAAC;KACd;;;;;;IAOD,IAAW,mBAAmB;QAC5B,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,OAAO,cAAc,EAAE,OAAO;cAC1B;gBACE,YAAY,EAAE,cAAc,CAAC,YAAY;gBACzC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC;aAChE;cACD,SAAS,CAAC;KACf;CACF,CAAA;AA3JC;IAHC,IAAI,CAAC;QACJ,QAAQ,EAAE,IAAI;KACf,CAAC;2CACuB;AAQzB;IADC,IAAI,EAAE;kDAC+B;AAQtC;IADC,IAAI,EAAE;sDAC6B;AAQpC;IADC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;oDACU;AAO/B;IADC,KAAK,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;oDACW;AAOrD;IADC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC;4CACE;AAOpC;IADC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC;4CACG;AAarC;IADC,QAAQ,CAAC,cAAc,CAAC;2CAGxB;AAQD;IADC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;8CACM;AAkErC;IADC,KAAK,CAAC,gCAAgC,CAAC;mEAMvC;AApJkB,YAAY;IANhC,SAAS,CAAC;QACT,UAAU,EAAE;YACV,SAAS;SACV;QACD,MAAM,EAAE,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC;KACjD,CAAC;GACmB,YAAY,CAoKhC;aApKoB,YAAY;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empathyco/x-components",
3
- "version": "3.0.0-alpha.186",
3
+ "version": "3.0.0-alpha.188",
4
4
  "description": "Empathy X Components",
5
5
  "author": "Empathy Systems Corporation S.L.",
6
6
  "license": "Apache-2.0",
@@ -133,5 +133,5 @@
133
133
  "access": "public",
134
134
  "directory": "dist"
135
135
  },
136
- "gitHead": "a0509afc7015a6bcac399f61948e4aa33eadb9f0"
136
+ "gitHead": "6e6617e57e111d7a1e1af843007d3d69fb3df8f6"
137
137
  }
@@ -31777,12 +31777,12 @@
31777
31777
  },
31778
31778
  {
31779
31779
  "kind": "Property",
31780
- "canonicalReference": "@empathyco/x-components!QueryPreview#maxItemsToRender:member",
31781
- "docComment": "/**\n * Number of query preview results to be rendered.\n *\n * @public\n */\n",
31780
+ "canonicalReference": "@empathyco/x-components!QueryPreview#debounceTimeMs:member",
31781
+ "docComment": "/**\n * Debounce time in milliseconds for triggering the search requests. It will default to 0 to fit the most common use case (pre-search), and it would work properly with a 250 value inside empathize.\n */\n",
31782
31782
  "excerptTokens": [
31783
31783
  {
31784
31784
  "kind": "Content",
31785
- "text": "protected maxItemsToRender?: "
31785
+ "text": "debounceTimeMs: "
31786
31786
  },
31787
31787
  {
31788
31788
  "kind": "Content",
@@ -31793,9 +31793,9 @@
31793
31793
  "text": ";"
31794
31794
  }
31795
31795
  ],
31796
- "isOptional": true,
31796
+ "isOptional": false,
31797
31797
  "releaseTag": "Public",
31798
- "name": "maxItemsToRender",
31798
+ "name": "debounceTimeMs",
31799
31799
  "propertyTypeTokenRange": {
31800
31800
  "startIndex": 1,
31801
31801
  "endIndex": 2
@@ -31803,33 +31803,31 @@
31803
31803
  "isStatic": false
31804
31804
  },
31805
31805
  {
31806
- "kind": "Method",
31807
- "canonicalReference": "@empathyco/x-components!QueryPreview#mounted:member(1)",
31808
- "docComment": "",
31806
+ "kind": "Property",
31807
+ "canonicalReference": "@empathyco/x-components!QueryPreview#maxItemsToRender:member",
31808
+ "docComment": "/**\n * Number of query preview results to be rendered.\n *\n * @public\n */\n",
31809
31809
  "excerptTokens": [
31810
31810
  {
31811
31811
  "kind": "Content",
31812
- "text": "protected mounted(): "
31812
+ "text": "protected maxItemsToRender?: "
31813
31813
  },
31814
31814
  {
31815
31815
  "kind": "Content",
31816
- "text": "void"
31816
+ "text": "number"
31817
31817
  },
31818
31818
  {
31819
31819
  "kind": "Content",
31820
31820
  "text": ";"
31821
31821
  }
31822
31822
  ],
31823
- "isOptional": false,
31824
- "isStatic": false,
31825
- "returnTypeTokenRange": {
31823
+ "isOptional": true,
31824
+ "releaseTag": "Public",
31825
+ "name": "maxItemsToRender",
31826
+ "propertyTypeTokenRange": {
31826
31827
  "startIndex": 1,
31827
31828
  "endIndex": 2
31828
31829
  },
31829
- "releaseTag": "Public",
31830
- "overloadIndex": 1,
31831
- "parameters": [],
31832
- "name": "mounted"
31830
+ "isStatic": false
31833
31831
  },
31834
31832
  {
31835
31833
  "kind": "Property",
@@ -31934,7 +31932,7 @@
31934
31932
  {
31935
31933
  "kind": "Property",
31936
31934
  "canonicalReference": "@empathyco/x-components!QueryPreview#queryFeature:member",
31937
- "docComment": "/**\n * . The origin property for the request\n *\n * @public\n */\n",
31935
+ "docComment": "/**\n * The origin property for the request.\n *\n * @public\n */\n",
31938
31936
  "excerptTokens": [
31939
31937
  {
31940
31938
  "kind": "Content",
@@ -31959,34 +31957,6 @@
31959
31957
  },
31960
31958
  "isStatic": false
31961
31959
  },
31962
- {
31963
- "kind": "Property",
31964
- "canonicalReference": "@empathyco/x-components!QueryPreview#queryPreviewRequest:member",
31965
- "docComment": "/**\n * The computed request object to be used to retrieve the query preview results.\n *\n * @returns The search request object.\n *\n * @public\n */\n",
31966
- "excerptTokens": [
31967
- {
31968
- "kind": "Content",
31969
- "text": "get queryPreviewRequest(): "
31970
- },
31971
- {
31972
- "kind": "Reference",
31973
- "text": "SearchRequest",
31974
- "canonicalReference": "@empathyco/x-components!SearchRequest:interface"
31975
- },
31976
- {
31977
- "kind": "Content",
31978
- "text": ";"
31979
- }
31980
- ],
31981
- "isOptional": false,
31982
- "releaseTag": "Public",
31983
- "name": "queryPreviewRequest",
31984
- "propertyTypeTokenRange": {
31985
- "startIndex": 1,
31986
- "endIndex": 2
31987
- },
31988
- "isStatic": false
31989
- },
31990
31960
  {
31991
31961
  "kind": "Property",
31992
31962
  "canonicalReference": "@empathyco/x-components!QueryPreview#queryPreviewResults:member",
@@ -2999,17 +2999,25 @@ export type QueryOriginInit = Partial<Pick<WireMetadata, 'feature' | 'location'>
2999
2999
 
3000
3000
  // @public
3001
3001
  export class QueryPreview extends Vue_2 {
3002
+ // @internal
3003
+ protected beforeDestroy(): void;
3004
+ // @internal
3005
+ protected cancelEmitPreviewRequestChanged(_new: DebouncedFunction<[SearchRequest]>, old: DebouncedFunction<[SearchRequest]>): void;
3002
3006
  config: QueriesPreviewConfig;
3003
3007
  // @internal
3004
- location?: FeatureLocation;
3008
+ protected created(): void;
3009
+ debounceTimeMs: number;
3010
+ // @internal
3011
+ protected get emitQueryPreviewRequestChanged(): DebouncedFunction<[SearchRequest]>;
3012
+ // @internal
3013
+ protected location?: FeatureLocation;
3005
3014
  protected maxItemsToRender?: number;
3006
- // (undocumented)
3007
- protected mounted(): void;
3008
3015
  params: Dictionary<unknown>;
3009
3016
  previewResults: Dictionary<QueryPreviewItem>;
3010
3017
  protected query: string;
3011
3018
  protected queryFeature?: QueryFeature;
3012
- get queryPreviewRequest(): SearchRequest;
3019
+ // @internal
3020
+ protected get queryPreviewRequest(): SearchRequest;
3013
3021
  get queryPreviewResults(): Partial<QueryPreviewItem> | undefined;
3014
3022
  get results(): Result[] | undefined;
3015
3023
  }
@@ -1 +1 @@
1
- {"version":3,"file":"x-emitters.d.ts","sourceRoot":"","sources":["../../../src/plugins/x-emitters.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAI/F,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,EAAE,UAAU,EAChD,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAChB,IAAI,CA8BN;AA8ED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,sBAAsB,GAAG,gBAAgB,GACvD,aAAa,IAAI,sBAAsB,CAEzC"}
1
+ {"version":3,"file":"x-emitters.d.ts","sourceRoot":"","sources":["../../../src/plugins/x-emitters.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAI/F,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,EAAE,UAAU,EAChD,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAChB,IAAI,CAsBN;AA8ED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,sBAAsB,GAAG,gBAAgB,GACvD,aAAa,IAAI,sBAAsB,CAEzC"}
@@ -4,6 +4,7 @@ import { SearchRequest, Result } from '@empathyco/x-types';
4
4
  import { QueryFeature, FeatureLocation } from '../../../types/origin';
5
5
  import { QueryPreviewItem } from '../store/types';
6
6
  import { QueriesPreviewConfig } from '../config.types';
7
+ import { DebouncedFunction } from '../../../utils';
7
8
  /**
8
9
  * Retrieves a preview of the results of a query and exposes them in the default slot,
9
10
  * along with the query preview and the totalResults of the search request.
@@ -18,8 +19,8 @@ export default class QueryPreview extends Vue {
18
19
  * @public
19
20
  */
20
21
  protected query: string;
21
- /**.
22
- * The origin property for the request
22
+ /**
23
+ * The origin property for the request.
23
24
  *
24
25
  * @public
25
26
  */
@@ -30,6 +31,12 @@ export default class QueryPreview extends Vue {
30
31
  * @public
31
32
  */
32
33
  protected maxItemsToRender?: number;
34
+ /**
35
+ * Debounce time in milliseconds for triggering the search requests.
36
+ * It will default to 0 to fit the most common use case (pre-search),
37
+ * and it would work properly with a 250 value inside empathize.
38
+ */
39
+ debounceTimeMs: number;
33
40
  /**
34
41
  * The results preview of the queries preview mounted.
35
42
  * It is a dictionary, indexed by the query preview query.
@@ -61,15 +68,43 @@ export default class QueryPreview extends Vue {
61
68
  *
62
69
  * @internal
63
70
  */
64
- location?: FeatureLocation;
71
+ protected location?: FeatureLocation;
65
72
  /**
66
73
  * The computed request object to be used to retrieve the query preview results.
67
74
  *
68
75
  * @returns The search request object.
69
- * @public
76
+ * @internal
77
+ */
78
+ protected get queryPreviewRequest(): SearchRequest;
79
+ /**
80
+ * The debounce method to trigger the request after the debounceTimeMs defined.
81
+ *
82
+ * @returns The search request object.
83
+ * @internal
84
+ */
85
+ protected get emitQueryPreviewRequestChanged(): DebouncedFunction<[SearchRequest]>;
86
+ /**
87
+ * Initialises watcher to emit debounced requests, and first value for the requests.
88
+ *
89
+ * @internal
90
+ */
91
+ protected created(): void;
92
+ /**
93
+ * Cancels the (remaining) requests when the component is destroyed
94
+ * via the `debounce.cancel()` method.
95
+ *
96
+ * @internal
97
+ */
98
+ protected beforeDestroy(): void;
99
+ /**
100
+ * Cancels the previous request when the debounced function changes (e.g: the debounceTimeMs
101
+ * prop changes or there is a request in progress that cancels it).
102
+ *
103
+ * @param _new - The new debounced function.
104
+ * @param old - The previous debounced function.
105
+ * @internal
70
106
  */
71
- get queryPreviewRequest(): SearchRequest;
72
- protected mounted(): void;
107
+ protected cancelEmitPreviewRequestChanged(_new: DebouncedFunction<[SearchRequest]>, old: DebouncedFunction<[SearchRequest]>): void;
73
108
  /**
74
109
  * Gets from the state the results preview of the query preview.
75
110
  *
@@ -1 +1 @@
1
- {"version":3,"file":"query-preview.vue?rollup-plugin-vue=script.d.ts","sourceRoot":"","sources":["../../../../../src/x-modules/queries-preview/components/query-preview.vue?rollup-plugin-vue=script.ts"],"names":[],"mappings":"AAkCA,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAO3D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;;;;GAMG;AAOH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,GAAG;IAC3C;;;;OAIG;IAIH,SAAS,CAAC,KAAK,EAAG,MAAM,CAAC;IAEzB;;;;OAIG;IAEH,SAAS,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEtC;;;;OAIG;IAEH,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEpC;;;OAGG;IAEI,cAAc,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAErD;;;OAGG;IAEI,MAAM,EAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpC;;;OAGG;IAEI,MAAM,EAAG,oBAAoB,CAAC;IAErC;;;;;;;;;OASG;IACH,IACW,OAAO,IAAI,MAAM,EAAE,GAAG,SAAS,CAEzC;IAED;;;;OAIG;IAEI,QAAQ,CAAC,EAAE,eAAe,CAAC;IAElC;;;;;OAKG;IACH,IACW,mBAAmB,IAAI,aAAa,CAY9C;IAED,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB;;;;OAIG;IACH,IAAW,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAQtE;CACF"}
1
+ {"version":3,"file":"query-preview.vue?rollup-plugin-vue=script.d.ts","sourceRoot":"","sources":["../../../../../src/x-modules/queries-preview/components/query-preview.vue?rollup-plugin-vue=script.ts"],"names":[],"mappings":"AAkCA,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAM3D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAIvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;;GAMG;AAOH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,GAAG;IAC3C;;;;OAIG;IAIH,SAAS,CAAC,KAAK,EAAG,MAAM,CAAC;IAEzB;;;;OAIG;IAEH,SAAS,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IAEtC;;;;OAIG;IAEH,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEpC;;;;OAIG;IAEI,cAAc,EAAG,MAAM,CAAC;IAE/B;;;OAGG;IAEI,cAAc,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAErD;;;OAGG;IAEI,MAAM,EAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpC;;;OAGG;IAEI,MAAM,EAAG,oBAAoB,CAAC;IAErC;;;;;;;;;OASG;IACH,IACW,OAAO,IAAI,MAAM,EAAE,GAAG,SAAS,CAEzC;IAED;;;;OAIG;IAEH,SAAS,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAErC;;;;;OAKG;IACH,SAAS,KAAK,mBAAmB,IAAI,aAAa,CAYjD;IAED;;;;;OAKG;IACH,SAAS,KAAK,8BAA8B,IAAI,iBAAiB,CAAC,CAAC,aAAa,CAAC,CAAC,CAIjF;IAED;;;;OAIG;IACH,SAAS,CAAC,OAAO,IAAI,IAAI;IAQzB;;;;;OAKG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAI/B;;;;;;;OAOG;IAEH,SAAS,CAAC,+BAA+B,CACvC,IAAI,EAAE,iBAAiB,CAAC,CAAC,aAAa,CAAC,CAAC,EACxC,GAAG,EAAE,iBAAiB,CAAC,CAAC,aAAa,CAAC,CAAC,GACtC,IAAI;IAIP;;;;OAIG;IACH,IAAW,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAQtE;CACF"}
@@ -1,15 +0,0 @@
1
- <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
-
3
- [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [QueryPreview](./x-components.querypreview.md) &gt; [mounted](./x-components.querypreview.mounted.md)
4
-
5
- ## QueryPreview.mounted() method
6
-
7
- <b>Signature:</b>
8
-
9
- ```typescript
10
- protected mounted(): void;
11
- ```
12
- <b>Returns:</b>
13
-
14
- void
15
-
@@ -1,13 +0,0 @@
1
- <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
-
3
- [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [QueryPreview](./x-components.querypreview.md) &gt; [queryPreviewRequest](./x-components.querypreview.querypreviewrequest.md)
4
-
5
- ## QueryPreview.queryPreviewRequest property
6
-
7
- The computed request object to be used to retrieve the query preview results.
8
-
9
- <b>Signature:</b>
10
-
11
- ```typescript
12
- get queryPreviewRequest(): SearchRequest;
13
- ```