@miso.ai/client-sdk-ui 1.11.4-beta.3 → 1.11.4-beta.5

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 (66) hide show
  1. package/dist/cjs/actor/data.js +1 -1
  2. package/dist/cjs/actor/filters.js +6 -4
  3. package/dist/cjs/actor/tracker.js +29 -13
  4. package/dist/cjs/actor/view.js +4 -2
  5. package/dist/cjs/actor/views.js +3 -6
  6. package/dist/cjs/affiliation/index.js +1 -1
  7. package/dist/cjs/combo/ask/options.js +1 -1
  8. package/dist/cjs/combo/base.js +1 -1
  9. package/dist/cjs/defaults/ask/controls.js +1 -1
  10. package/dist/cjs/defaults/common/templates.js +1 -1
  11. package/dist/cjs/layout/affiliation/affiliation.js +2 -2
  12. package/dist/cjs/layout/banner/banner.js +1 -1
  13. package/dist/cjs/layout/button/more-button.js +1 -1
  14. package/dist/cjs/layout/container/container.js +3 -3
  15. package/dist/cjs/layout/error/error.js +1 -1
  16. package/dist/cjs/layout/input/facets.js +1 -1
  17. package/dist/cjs/layout/input/option-list.js +1 -1
  18. package/dist/cjs/layout/input/search-box.js +2 -2
  19. package/dist/cjs/layout/input/select.js +1 -1
  20. package/dist/cjs/layout/list/cards.js +1 -1
  21. package/dist/cjs/layout/list/carousel.js +1 -1
  22. package/dist/cjs/layout/list/collection.js +1 -1
  23. package/dist/cjs/layout/list/list.js +1 -1
  24. package/dist/cjs/layout/radio/feedback.js +1 -1
  25. package/dist/cjs/layout/radio/radio.js +1 -1
  26. package/dist/cjs/layout/raf.js +1 -1
  27. package/dist/cjs/layout/template.js +1 -1
  28. package/dist/cjs/layout/templates.js +1 -1
  29. package/dist/cjs/layout/text/text.js +1 -1
  30. package/dist/cjs/layout/text/typewriter/index.js +56 -14
  31. package/dist/cjs/layout/trackable.js +3 -3
  32. package/dist/cjs/plugin.js +1 -1
  33. package/dist/cjs/util/trackers.js +3 -3
  34. package/dist/cjs/version.js +1 -1
  35. package/dist/cjs/workflow/answer-based.js +73 -19
  36. package/dist/cjs/workflow/ask.js +7 -7
  37. package/dist/cjs/workflow/asks.js +1 -1
  38. package/dist/cjs/workflow/autocomplete.js +1 -1
  39. package/dist/cjs/workflow/base.js +3 -2
  40. package/dist/cjs/workflow/explore.js +8 -4
  41. package/dist/cjs/workflow/hybrid-search-answer.js +1 -1
  42. package/dist/cjs/workflow/options/layouts.js +1 -1
  43. package/dist/cjs/workflow/options/trackers.js +67 -13
  44. package/dist/cjs/workflow/recommendation.js +1 -1
  45. package/dist/cjs/workflow/search-based.js +1 -1
  46. package/dist/cjs/workflow/search.js +4 -2
  47. package/package.json +2 -2
  48. package/src/actor/filters.js +7 -4
  49. package/src/actor/tracker.js +26 -11
  50. package/src/actor/view.js +2 -1
  51. package/src/actor/views.js +2 -6
  52. package/src/layout/affiliation/affiliation.js +1 -1
  53. package/src/layout/container/container.js +2 -2
  54. package/src/layout/input/search-box.js +1 -1
  55. package/src/layout/text/typewriter/index.js +40 -7
  56. package/src/layout/trackable.js +3 -3
  57. package/src/util/trackers.js +1 -1
  58. package/src/version.js +1 -1
  59. package/src/workflow/answer-based.js +47 -10
  60. package/src/workflow/ask.js +5 -3
  61. package/src/workflow/base.js +3 -3
  62. package/src/workflow/explore.js +9 -4
  63. package/src/workflow/options/trackers.js +63 -15
  64. package/src/workflow/recommendation.js +2 -2
  65. package/src/workflow/search-based.js +2 -2
  66. package/src/workflow/search.js +3 -2
@@ -72,13 +72,14 @@ export default class TypewriterLayout extends ProgressiveLayout {
72
72
  return; // destroyed
73
73
  }
74
74
  const cursorClass = cursorClassName(this.className);
75
- const { onDebug, onCitationLink } = this.options;
75
+ const { onDebug, onCitationLink, variant } = this.options;
76
76
  // TODO: options
77
77
  this._renderer = context.createRenderer({
78
78
  cursorClass,
79
79
  getSource: index => this._getSource(index),
80
80
  onCitationLink,
81
81
  onDebug: normalizeOnDebug(onDebug),
82
+ variant,
82
83
  });
83
84
  // capture citation link click if necessary
84
85
  this._unsubscribes.push(this._view.proxyElement.on('click', (e) => this._onClick(e)));
@@ -149,16 +150,48 @@ export default class TypewriterLayout extends ProgressiveLayout {
149
150
  }
150
151
 
151
152
  // event //
152
- _onClick({ target }) {
153
- const element = target.closest(`[data-role="citation-link"]`);
154
- if (!element) {
153
+ _onClick(event) {
154
+ const { target } = event;
155
+ const citationLinkElement = target.closest(`[data-role="citation-link"]`);
156
+ // citation link click
157
+ if (citationLinkElement) {
158
+ const index = parseInt(citationLinkElement.dataset.index);
159
+ if (!Number.isNaN(index)) {
160
+ this._view._events.emit('citation-click', { index });
161
+ }
155
162
  return;
156
163
  }
157
- const index = parseInt(element.dataset.index);
158
- if (Number.isNaN(index)) {
164
+ // generic link click
165
+ const anchorElement = target.closest('a');
166
+ if (anchorElement) {
167
+ if (!event.defaultPrevented) {
168
+ // TODO: classList, attributes
169
+ const { href, innerText, className } = anchorElement;
170
+ if (href) {
171
+ this._view._events.emit('link-click', trimObj({
172
+ url: href,
173
+ text: innerText ? innerText.trim() : '',
174
+ className: className || '',
175
+ attributes: dumpElementAttributes(anchorElement),
176
+ }));
177
+ }
178
+ }
159
179
  return;
160
180
  }
161
- this._view._events.emit('citation-click', { index });
162
181
  }
182
+ }
163
183
 
184
+ function dumpElementAttributes(element) {
185
+ const { attributes } = element;
186
+ const attrs = {};
187
+ for (const { name, value } of attributes) {
188
+ if (name.startsWith('data-')) {
189
+ attrs[name] = value;
190
+ }
191
+ }
192
+ try {
193
+ return JSON.stringify(attrs);
194
+ } catch (e) {
195
+ return '{}';
196
+ }
164
197
  }
@@ -51,7 +51,7 @@ export class TrackableMixin {
51
51
  if (entries.length === 0) {
52
52
  return;
53
53
  }
54
- const { impression: options } = this._view.trackerOptions || {};
54
+ const { impression: options } = this._view.tracker.options || {};
55
55
  if (!options) {
56
56
  return;
57
57
  }
@@ -68,7 +68,7 @@ export class TrackableMixin {
68
68
  if (entries.length === 0) {
69
69
  return;
70
70
  }
71
- const { viewable: options } = this._view.trackerOptions || {};
71
+ const { viewable: options } = this._view.tracker.options || {};
72
72
  if (!options) {
73
73
  return;
74
74
  }
@@ -78,7 +78,7 @@ export class TrackableMixin {
78
78
  }
79
79
 
80
80
  _trackClick(event, binding) {
81
- const { click: options } = this._view.trackerOptions || {};
81
+ const { click: options } = this._view.tracker.options || {};
82
82
  if (validateClick(options, event, binding)) {
83
83
  this._view.tracker.click([binding.value]);
84
84
  }
@@ -12,7 +12,6 @@ const DEFAULT_TRACKER_OPTIONS = Object.freeze({
12
12
  click: Object.freeze({
13
13
  lenient: false,
14
14
  }),
15
- watch: false,
16
15
  });
17
16
 
18
17
  function mergeOptions(def, opt) {
@@ -21,6 +20,7 @@ function mergeOptions(def, opt) {
21
20
  }
22
21
 
23
22
  export function normalizeTrackerOptions(options) {
23
+ // TODO: make this { active: false } to keep it an object
24
24
  if (options === false) {
25
25
  return false; // turn off all tracking
26
26
  }
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export default '1.11.4-beta.3';
1
+ export default '1.11.4-beta.5';
@@ -4,7 +4,7 @@ import { fields, FeedbackActor } from '../actor/index.js';
4
4
  import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
5
5
  import { SearchBoxLayout, TextLayout, ListLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
6
6
  import { processData as processAffiliationData } from '../affiliation/index.js';
7
- import { mergeRolesOptions } from './options/index.js';
7
+ import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
8
8
  import { writeAnswerStageToMeta, mergeInteraction } from './processors.js';
9
9
  import { enableUseLink } from './use-link.js';
10
10
 
@@ -40,9 +40,15 @@ const DEFAULT_LAYOUTS = Object.freeze({
40
40
 
41
41
  const DEFAULT_TRACKERS = Object.freeze({
42
42
  ...Workflow.DEFAULT_TRACKERS,
43
- [ROLE.SOURCES]: {},
44
- [ROLE.AFFILIATION]: {},
45
- [ROLE.PRODUCTS]: {},
43
+ [ROLE.ANSWER]: {
44
+ active: true,
45
+ itemless: true,
46
+ deduplicated: false,
47
+ click: DEFAULT_TRACKER_OPTIONS.click, // click only
48
+ },
49
+ [ROLE.SOURCES]: DEFAULT_TRACKER_OPTIONS,
50
+ [ROLE.AFFILIATION]: DEFAULT_TRACKER_OPTIONS,
51
+ [ROLE.PRODUCTS]: DEFAULT_TRACKER_OPTIONS,
46
52
  });
47
53
 
48
54
  const DEFAULT_OPTIONS = Object.freeze({
@@ -58,6 +64,10 @@ const ROLES_OPTIONS = mergeRolesOptions(Workflow.ROLES_OPTIONS, {
58
64
  members: Object.keys(DEFAULT_LAYOUTS),
59
65
  });
60
66
 
67
+ function normalizeAutoQueryOptions({ setValue = true, focus = true, param = 'q', sourceParam = 'qs', ...options } = {}) {
68
+ return { setValue, focus, param, sourceParam, ...options };
69
+ }
70
+
61
71
  export default class AnswerBasedWorkflow extends Workflow {
62
72
 
63
73
  // constructor //
@@ -78,6 +88,7 @@ export default class AnswerBasedWorkflow extends Workflow {
78
88
  ...this._unsubscribes,
79
89
  this._hub.on(fields.query(), args => this._query(args)),
80
90
  this._views.get(ROLE.ANSWER).on('citation-click', event => this._onCitationClick(event)),
91
+ this._views.get(ROLE.ANSWER).on('link-click', event => this._onAnswerLinkClick(event)),
81
92
  ];
82
93
  }
83
94
 
@@ -132,10 +143,10 @@ export default class AnswerBasedWorkflow extends Workflow {
132
143
 
133
144
  // query //
134
145
  autoQuery(options = {}) {
135
- const { setValue = true, focus = true } = this._autoQuery = options;
146
+ const { setValue, focus, param, sourceParam } = this._autoQuery = normalizeAutoQueryOptions(options);
136
147
  const searchParams = new URLSearchParams(window.location.search);
137
- const q = searchParams.get('q');
138
- const qs = searchParams.get('qs');
148
+ const q = searchParams.get(param);
149
+ const qs = searchParams.get(sourceParam);
139
150
  const { layout } = this._views.get(ROLE.QUERY);
140
151
  if (layout) {
141
152
  if (q && setValue) {
@@ -219,14 +230,15 @@ export default class AnswerBasedWorkflow extends Workflow {
219
230
  if (!value || !this._autoQuery || this._autoQuery.updateUrl === false) { // explicitly false
220
231
  return;
221
232
  }
233
+ const { param } = this._autoQuery;
222
234
  const { question } = value;
223
235
  const organic = request && request.payload && request.payload._meta && request.payload._meta.question_source === ORGANIC_QUESTION_SOURCE;
224
236
 
225
237
  const url = new URL(window.location);
226
- const currentQuestion = url.searchParams.get('q');
238
+ const currentQuestion = url.searchParams.get(param);
227
239
  // TODO: review this, handle &qs=
228
240
  if (question !== currentQuestion && (!organic || this._autoQuery.updateUrl === true)) {
229
- url.searchParams.set('q', question);
241
+ url.searchParams.set(param, question);
230
242
  window.history.replaceState({}, '', url);
231
243
  }
232
244
  }
@@ -235,6 +247,7 @@ export default class AnswerBasedWorkflow extends Workflow {
235
247
  _defaultProcessInteraction(payload, args) {
236
248
  payload = super._defaultProcessInteraction(payload, args);
237
249
  payload = this._writeAskPropertiesToInteraction(payload, args);
250
+ payload = this._writeAnswerClickInteraction(payload, args);
238
251
  return payload;
239
252
  }
240
253
 
@@ -251,6 +264,24 @@ export default class AnswerBasedWorkflow extends Workflow {
251
264
  });
252
265
  }
253
266
 
267
+ _writeAnswerClickInteraction(payload, args) {
268
+ if (args.role !== ROLE.ANSWER) {
269
+ return payload;
270
+ }
271
+ console.log('writeAnswerClickInteraction', payload, args);
272
+ const { items = [] } = args;
273
+ return mergeInteraction(payload, {
274
+ context: {
275
+ custom_context: {
276
+ urls: items.map(item => item.url),
277
+ texts: items.map(item => item.text),
278
+ class_names: items.map(item => item.className),
279
+ attributes: items.map(item => item.attributes),
280
+ },
281
+ },
282
+ });
283
+ }
284
+
254
285
  _getQuestionSourceFromViewState(args) {
255
286
  const { request } = this._hub.states[fields.view(args.role)] || {};
256
287
  const { payload } = request || {};
@@ -267,7 +298,13 @@ export default class AnswerBasedWorkflow extends Workflow {
267
298
  return;
268
299
  }
269
300
  // TODO: should we track impression as well?
270
- this._trackers.sources.click([source.product_id], { manual: false });
301
+ this._views.trackers.sources.click([source.product_id]);
302
+ }
303
+
304
+ _onAnswerLinkClick(item) {
305
+ // put everything into args and let _defaultProcessInteraction() handles it
306
+ // for it's hard to make it a standard item
307
+ this._views.trackers.answer.click([], { items: [item] });
271
308
  }
272
309
 
273
310
  // helpers //
@@ -4,7 +4,7 @@ import { fields } from '../actor/index.js';
4
4
  import { ROLE, ORGANIC_QUESTION_SOURCE } from '../constants.js';
5
5
  import { OptionListLayout, ListLayout, SearchBoxLayout } from '../layout/index.js';
6
6
  import { mergeInteraction } from './processors.js';
7
- import { mergeRolesOptions } from './options/index.js';
7
+ import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
8
8
 
9
9
  const DEFAULT_API_OPTIONS = Object.freeze({
10
10
  ...AnswerBasedWorkflow.DEFAULT_API_OPTIONS,
@@ -24,10 +24,12 @@ const DEFAULT_LAYOUTS = Object.freeze({
24
24
 
25
25
  const DEFAULT_TRACKERS = Object.freeze({
26
26
  ...AnswerBasedWorkflow.DEFAULT_TRACKERS,
27
- [ROLE.RELATED_RESOURCES]: {},
27
+ [ROLE.RELATED_RESOURCES]: DEFAULT_TRACKER_OPTIONS,
28
28
  [ROLE.QUERY_SUGGESTIONS]: {
29
+ ...DEFAULT_TRACKER_OPTIONS,
29
30
  click: {
30
- validate: event => event.button === 0, // left click only
31
+ ...DEFAULT_TRACKER_OPTIONS.click,
32
+ validate: event => event.button === 0, // loosen criteria, for it's not a hyperlink
31
33
  },
32
34
  },
33
35
  });
@@ -48,7 +48,7 @@ export default class Workflow extends Component {
48
48
  constructor(args) {
49
49
  super(args.name || 'workflow', args.plugin);
50
50
 
51
- let { context, plugin, client, options } = args;
51
+ let { context, plugin, client, defaults, options } = args;
52
52
  this._context = context;
53
53
  this._plugin = plugin = plugin || context._plugin;
54
54
  this._client = client = client || context._client;
@@ -58,8 +58,8 @@ export default class Workflow extends Component {
58
58
  this._roles = args.roles;
59
59
 
60
60
  this._extensions = plugin._getExtensions(client);
61
- this._defaults = args.defaults;
62
- this._options = options || new WorkflowOptions(context && context._options, args.defaults);
61
+ this._defaults = defaults;
62
+ this._options = options || new WorkflowOptions(context && context._options, defaults);
63
63
  this._hub = injectLogger(new Hub(), (...args) => this._log(...args));
64
64
  this._sessionContext = new WeakMap();
65
65
 
@@ -3,7 +3,7 @@ import Workflow from './base.js';
3
3
  import { fields } from '../actor/index.js';
4
4
  import { ROLE, EVENT_TYPE } from '../constants.js';
5
5
  import { ListLayout, SearchBoxLayout } from '../layout/index.js';
6
- import { mergeRolesOptions } from './options/index.js';
6
+ import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
7
7
  import { enableUseLink, UseLinkMixin } from './use-link.js';
8
8
 
9
9
  const DEFAULT_API_OPTIONS = Object.freeze({
@@ -20,10 +20,15 @@ const DEFAULT_LAYOUTS = Object.freeze({
20
20
 
21
21
  const DEFAULT_TRACKERS = Object.freeze({
22
22
  ...Workflow.DEFAULT_TRACKERS,
23
- [ROLE.RELATED_QUESTIONS]: {},
24
- [ROLE.CONTAINER]: {},
23
+ [ROLE.RELATED_QUESTIONS]: DEFAULT_TRACKER_OPTIONS,
24
+ [ROLE.CONTAINER]: {
25
+ ...DEFAULT_TRACKER_OPTIONS,
26
+ itemless: true,
27
+ },
25
28
  [ROLE.QUERY]: {
26
- [EVENT_TYPE.SUBMIT]: {},
29
+ [EVENT_TYPE.SUBMIT]: {
30
+ active: true,
31
+ },
27
32
  },
28
33
  });
29
34
 
@@ -1,32 +1,80 @@
1
- import { mergeOptions } from './utils.js';
1
+ import { TRACKING_EVENT_TYPES } from '../../constants.js';
2
+ import { mergeOptions, normalizeOptions } from './utils.js';
2
3
 
3
- export function normalizeTrackersOptions(options) {
4
- if (options === undefined || options === false) {
5
- return options;
6
- }
4
+ export const DEFAULT_TRACKER_OPTIONS = Object.freeze({
5
+ active: true,
6
+ impression: Object.freeze({
7
+ active: true,
8
+ }),
9
+ viewable: Object.freeze({
10
+ active: true,
11
+ area: 0.5,
12
+ duration: 1000,
13
+ }),
14
+ click: Object.freeze({
15
+ active: true,
16
+ lenient: false,
17
+ }),
18
+ });
19
+
20
+ export function normalizeTrackersOptions(options = {}) {
21
+ options = normalizeOptions(options);
22
+ const { active, ...rest } = options;
7
23
  const normalized = {};
8
- for (const [role, args] of Object.entries(options)) {
24
+ for (const [role, args] of Object.entries(rest)) {
9
25
  normalized[role] = normalizeTrackerOptions(args);
10
26
  }
11
- return normalized;
27
+ return {
28
+ active,
29
+ ...normalized,
30
+ };
31
+ }
32
+
33
+ function normalizeTrackerOptions(options = {}) {
34
+ options = normalizeOptions(options);
35
+ const { active, ...rest } = options;
36
+ const normalized = {};
37
+ for (const [role, args] of Object.entries(rest)) {
38
+ normalized[role] = normalizeTrackerEventOptions(args);
39
+ }
40
+ return options;
12
41
  }
13
42
 
14
- function normalizeTrackerOptions(options) {
43
+ function normalizeTrackerEventOptions(options = {}) {
44
+ options = normalizeOptions(options);
15
45
  return options;
16
46
  }
17
47
 
18
48
  export function mergeTrackersOptions(...optionsList) {
49
+ // TODO: should be able to remove this
19
50
  if (optionsList[optionsList.length - 1] === false) {
20
51
  return false;
21
52
  }
22
- return mergeOptions(optionsList, (merged, options) => Object.assign(merged, {
23
- ...options,
24
- impression: mergeTrackerEventOptions(merged.impression, options.impression),
25
- viewable: mergeTrackerEventOptions(merged.viewable, options.viewable),
26
- click: mergeTrackerEventOptions(merged.click, options.click),
27
- }));
53
+ return mergeOptions(optionsList, (merged, options) => {
54
+ for (const [key, args] of Object.entries(options)) {
55
+ if (args === undefined) {
56
+ continue;
57
+ }
58
+ merged[key] = key === 'active' ? args : mergeTrackerOptions(merged[key], args);
59
+ }
60
+ return merged;
61
+ });
62
+ }
63
+
64
+ function mergeTrackerOptions(base = {}, overrides = {}) {
65
+ const merged = { ...base };
66
+ for (const [key, args] of Object.entries(overrides)) {
67
+ if (args === undefined) {
68
+ continue;
69
+ }
70
+ merged[key] = TRACKING_EVENT_TYPES.includes(key) ? mergeTrackerEventOptions(base[key], args) : args;
71
+ }
72
+ return merged;
28
73
  }
29
74
 
30
75
  function mergeTrackerEventOptions(base = {}, overrides = {}) {
31
- return (overrides === false || base === false) ? overrides : { ...base, ...overrides };
76
+ return {
77
+ ...base,
78
+ ...overrides,
79
+ };
32
80
  }
@@ -2,7 +2,7 @@ import { defineValues, API } from '@miso.ai/commons';
2
2
  import Workflow from './base.js';
3
3
  import { ListLayout } from '../layout/index.js';
4
4
  import { ROLE } from '../constants.js';
5
- import { mergeRolesOptions } from './options/index.js';
5
+ import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
6
6
  import { mergeInteraction } from './processors.js';
7
7
 
8
8
  const DEFAULT_API_OPTIONS = Object.freeze({
@@ -22,7 +22,7 @@ const DEFAULT_LAYOUTS = Object.freeze({
22
22
 
23
23
  const DEFAULT_TRACKERS = Object.freeze({
24
24
  ...Workflow.DEFAULT_TRACKERS,
25
- [ROLE.PRODUCTS]: {},
25
+ [ROLE.PRODUCTS]: DEFAULT_TRACKER_OPTIONS,
26
26
  });
27
27
 
28
28
  const DEFAULT_OPTIONS = Object.freeze({
@@ -4,7 +4,7 @@ import { fields } from '../actor/index.js';
4
4
  import { STATUS, ROLE, WORKFLOW_CONFIGURABLE } from '../constants.js';
5
5
  import { SearchBoxLayout, ListLayout, TextLayout, FacetsLayout, SelectLayout, MoreButtonLayout } from '../layout/index.js';
6
6
  import { mappingSortData, writeKeywordsToData, retainFacetCountsInData, writeExhaustionToData, concatItemsFromMoreResponse } from './processors.js';
7
- import { mergeRolesOptions, makeConfigurable } from './options/index.js';
7
+ import { mergeRolesOptions, makeConfigurable, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
8
8
 
9
9
  const DEFAULT_ROWS = 10;
10
10
  const DEFAULT_PAGE_LIMIT = 10;
@@ -32,7 +32,7 @@ const DEFAULT_LAYOUTS = Object.freeze({
32
32
 
33
33
  const DEFAULT_TRACKERS = Object.freeze({
34
34
  ...Workflow.DEFAULT_TRACKERS,
35
- [ROLE.PRODUCTS]: {},
35
+ [ROLE.PRODUCTS]: DEFAULT_TRACKER_OPTIONS,
36
36
  });
37
37
 
38
38
  const DEFAULT_PAGINATION = Object.freeze({
@@ -57,8 +57,9 @@ export default class Search extends SearchBasedWorkflow {
57
57
  this._initAutocomplete(args);
58
58
  }
59
59
 
60
- autoQuery({ setValue = true, focus = true } = {}) {
61
- const q = new URLSearchParams(window.location.search).get('q');
60
+ autoQuery({ setValue = true, focus = true, param = 'q' } = {}) {
61
+ // TODO: align implementation with AnswerBasedWorkflow
62
+ const q = new URLSearchParams(window.location.search).get(param);
62
63
  const { layout } = this._views.get(ROLE.QUERY);
63
64
  if (layout) {
64
65
  if (q && setValue) {