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

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 (87) hide show
  1. package/dist/cjs/actor/filters.js +57 -11
  2. package/dist/cjs/actor/tracker.js +1 -6
  3. package/dist/cjs/actor/view.js +6 -8
  4. package/dist/cjs/actor/views.js +10 -26
  5. package/dist/cjs/constants.js +12 -2
  6. package/dist/cjs/element/role/index.js +7 -0
  7. package/dist/cjs/element/role/miso-sort.js +20 -0
  8. package/dist/cjs/layout/affiliation/affiliation.js +1 -1
  9. package/dist/cjs/layout/container/container.js +2 -2
  10. package/dist/cjs/layout/index.js +7 -0
  11. package/dist/cjs/layout/input/facets.js +2 -2
  12. package/dist/cjs/layout/input/search-box.js +1 -1
  13. package/dist/cjs/layout/input/select.js +150 -0
  14. package/dist/cjs/layout/raf.js +2 -4
  15. package/dist/cjs/layout/trackable.js +3 -3
  16. package/dist/cjs/layout/triggerable.js +1 -1
  17. package/dist/cjs/util/trackers.js +2 -0
  18. package/dist/cjs/version.js +1 -1
  19. package/dist/cjs/workflow/answer-based.js +2 -2
  20. package/dist/cjs/workflow/ask.js +4 -1
  21. package/dist/cjs/workflow/base.js +4 -4
  22. package/dist/cjs/workflow/context.js +3 -3
  23. package/dist/cjs/workflow/explore.js +2 -2
  24. package/dist/cjs/workflow/hybrid-search-answer.js +9 -7
  25. package/dist/cjs/workflow/hybrid-search-results.js +18 -16
  26. package/dist/cjs/workflow/hybrid-search-views.js +5 -12
  27. package/dist/cjs/workflow/hybrid-search.js +2 -2
  28. package/dist/cjs/workflow/options/api.js +56 -0
  29. package/dist/cjs/workflow/options/configurable.js +49 -0
  30. package/dist/cjs/workflow/options/data-processor.js +23 -0
  31. package/dist/cjs/workflow/options/filters.js +18 -0
  32. package/dist/cjs/workflow/options/index.js +115 -0
  33. package/dist/cjs/workflow/options/interactions.js +44 -0
  34. package/dist/cjs/workflow/options/layouts.js +83 -0
  35. package/dist/cjs/workflow/options/options.js +154 -0
  36. package/dist/cjs/workflow/options/pagination.js +28 -0
  37. package/dist/cjs/workflow/options/roles.js +17 -0
  38. package/dist/cjs/workflow/options/trackers.js +39 -0
  39. package/dist/cjs/workflow/options/utils.js +33 -0
  40. package/dist/cjs/workflow/processors.js +39 -33
  41. package/dist/cjs/workflow/recommendation.js +2 -2
  42. package/dist/cjs/workflow/search-based.js +59 -22
  43. package/package.json +2 -2
  44. package/src/actor/filters.js +53 -12
  45. package/src/actor/tracker.js +1 -6
  46. package/src/actor/view.js +7 -8
  47. package/src/actor/views.js +9 -30
  48. package/src/constants.js +11 -0
  49. package/src/element/role/index.js +1 -0
  50. package/src/element/role/miso-sort.js +16 -0
  51. package/src/layout/affiliation/affiliation.js +1 -1
  52. package/src/layout/container/container.js +2 -2
  53. package/src/layout/index.js +1 -0
  54. package/src/layout/input/facets.js +3 -2
  55. package/src/layout/input/search-box.js +1 -1
  56. package/src/layout/input/select.js +142 -0
  57. package/src/layout/raf.js +2 -2
  58. package/src/layout/trackable.js +3 -3
  59. package/src/layout/triggerable.js +1 -1
  60. package/src/util/trackers.js +2 -0
  61. package/src/version.js +1 -1
  62. package/src/workflow/answer-based.js +1 -1
  63. package/src/workflow/ask.js +4 -1
  64. package/src/workflow/base.js +1 -1
  65. package/src/workflow/context.js +1 -1
  66. package/src/workflow/explore.js +1 -1
  67. package/src/workflow/hybrid-search-answer.js +8 -3
  68. package/src/workflow/hybrid-search-results.js +21 -7
  69. package/src/workflow/hybrid-search-views.js +4 -12
  70. package/src/workflow/hybrid-search.js +3 -3
  71. package/src/workflow/options/api.js +46 -0
  72. package/src/workflow/options/configurable.js +48 -0
  73. package/src/workflow/options/data-processor.js +15 -0
  74. package/src/workflow/options/filters.js +10 -0
  75. package/src/workflow/options/index.js +10 -0
  76. package/src/workflow/options/interactions.js +36 -0
  77. package/src/workflow/options/layouts.js +73 -0
  78. package/src/workflow/options/options.js +169 -0
  79. package/src/workflow/options/pagination.js +18 -0
  80. package/src/workflow/options/roles.js +12 -0
  81. package/src/workflow/options/trackers.js +32 -0
  82. package/src/workflow/options/utils.js +26 -0
  83. package/src/workflow/processors.js +30 -34
  84. package/src/workflow/recommendation.js +1 -1
  85. package/src/workflow/search-based.js +58 -13
  86. package/dist/cjs/workflow/options.js +0 -448
  87. package/src/workflow/options.js +0 -433
package/src/actor/view.js CHANGED
@@ -97,13 +97,17 @@ export default class ViewActor {
97
97
  }
98
98
  if (!this._tracker) {
99
99
  const { hub } = this;
100
- this._tracker = new Tracker({ hub, role, options: () => this._getTrackerOptions() });
100
+ this._tracker = new Tracker({ hub, role });
101
101
  }
102
102
  return this._tracker;
103
103
  }
104
104
 
105
105
  get workflowOptions() {
106
- return this._views._getWorkflowOptions();
106
+ return this._views._options.resolved;
107
+ }
108
+
109
+ get trackerOptions() {
110
+ return this._views._getTrackerOptions(this.role);
107
111
  }
108
112
 
109
113
  get filters() {
@@ -154,15 +158,10 @@ export default class ViewActor {
154
158
  this.hub.update(fields.view(role), state, { silent });
155
159
  }
156
160
 
157
- _getTrackerOptions() {
158
- // used by tracker to expose tracker options to layout
159
- return this._views._getTrackerOptions(this.role);
160
- }
161
-
162
161
  _sliceData(data) {
163
162
  const { value, error, status, meta, ...rest } = data;
164
163
  const sliced = {
165
- value: this._mapping(data),
164
+ value: this._mapping(data, this),
166
165
  status,
167
166
  data: value,
168
167
  meta,
@@ -44,15 +44,9 @@ export default class ViewsActor {
44
44
  this._unsubscribes = [
45
45
  () => window.removeEventListener('resize', syncSize),
46
46
  hub.on(fields.data(), data => this.refresh({ data })),
47
- options.on('autocomplete', () => this._syncAutocompleteOptions()),
48
- options.on('pagination', () => this._syncPaginationOptions()),
49
- options.on('trackers', () => this._syncTrackers()),
50
47
  options.on('layouts', () => this._syncLayouts()),
51
48
  ];
52
49
 
53
- this._syncAutocompleteOptions();
54
- this._syncPaginationOptions();
55
- this._syncTrackers();
56
50
  this._syncLayouts();
57
51
  }
58
52
 
@@ -150,13 +144,16 @@ export default class ViewsActor {
150
144
  } else {
151
145
  for (let [role, [name, options]] of Object.entries(layouts)) {
152
146
  // TODO: try to omit if unchanged
153
- const fn = () => this._layoutFactory.create(name, { ...options, role, workflow: this._workflowName, workflowOptions: this._getWorkflowOptions() });
147
+ const fn = () => this._layoutFactory.create(name, { ...options, role, workflow: this._workflowName });
154
148
  if (role === ROLE.CONTAINER) {
155
149
  for (const view of this._containers.values()) {
156
150
  view.layout = fn();
157
151
  }
158
152
  } else {
159
- this.get(role).layout = fn();
153
+ const view = this.get(role);
154
+ if (view) {
155
+ view.layout = fn();
156
+ }
160
157
  }
161
158
  }
162
159
  }
@@ -168,11 +165,11 @@ export default class ViewsActor {
168
165
  return undefined;
169
166
  }
170
167
  const [name, options] = args;
171
- return this._layoutFactory.create(name, { ...options, role, workflow: this._workflowName, workflowOptions: this._getWorkflowOptions() });
168
+ return this._layoutFactory.create(name, { ...options, role, workflow: this._workflowName });
172
169
  }
173
170
 
174
171
  get(role) {
175
- return this._views[role] || (this._views[role] = new ViewActor(this, role));
172
+ return this._views[role];
176
173
  }
177
174
 
178
175
  get views() {
@@ -218,12 +215,9 @@ export default class ViewsActor {
218
215
  return data || this._hub.states[fields.data()];
219
216
  }
220
217
 
221
- _syncTrackers() {
222
- this._trackerOptions = this._options.resolved.trackers;
223
- }
224
-
225
218
  _getTrackerOptions(role) {
226
- return normalizeTrackerOptions((this._trackerOptions && this._trackerOptions[role]) || false);
219
+ const allTrackerOptions = this._options.resolved.trackers;
220
+ return normalizeTrackerOptions((allTrackerOptions && allTrackerOptions[role]) || false);
227
221
  }
228
222
 
229
223
  _getContainerTracker() {
@@ -235,21 +229,6 @@ export default class ViewsActor {
235
229
  return this._containerTracker;
236
230
  }
237
231
 
238
- _syncAutocompleteOptions() {
239
- this._autocompleteOptions = this._options.resolved.autocomplete;
240
- }
241
-
242
- _syncPaginationOptions() {
243
- this._paginationOptions = this._options.resolved.pagination;
244
- }
245
-
246
- _getWorkflowOptions() {
247
- return trimObj({
248
- autocomplete: this._autocompleteOptions,
249
- pagination: this._paginationOptions,
250
- });
251
- }
252
-
253
232
  _error(e) {
254
233
  // TODO: hub trigger error event
255
234
  console.error(e);
package/src/constants.js CHANGED
@@ -24,6 +24,7 @@ export const ROLE = Object.freeze({
24
24
  FACETS: 'facets',
25
25
  TOTAL: 'total',
26
26
  MORE: 'more',
27
+ SORT: 'sort',
27
28
  ERROR: 'error',
28
29
  });
29
30
 
@@ -114,3 +115,13 @@ export function validateTrackingStatus(value) {
114
115
  throw new Error(`Unrecognized tracking status: ${value}`);
115
116
  }
116
117
  }
118
+
119
+ export const WORKFLOW_CONFIGURABLE = Object.freeze({
120
+ API: 'api',
121
+ LAYOUTS: 'layouts',
122
+ DATA_PROCESSOR: 'dataProcessor',
123
+ TRACKERS: 'trackers',
124
+ INTERACTIONS: 'interactions',
125
+ FILTERS: 'filters',
126
+ PAGINATION: 'pagination',
127
+ });
@@ -14,4 +14,5 @@ export { default as MisoKeywordsElement } from './miso-keywords.js';
14
14
  export { default as MisoTotalElement } from './miso-total.js';
15
15
  export { default as MisoFacetsElement } from './miso-facets.js';
16
16
  export { default as MisoMoreElement } from './miso-more.js';
17
+ export { default as MisoSortElement } from './miso-sort.js';
17
18
  export { default as MisoErrorElement } from './miso-error.js';
@@ -0,0 +1,16 @@
1
+ import MisoComponentElement from './miso-component.js';
2
+ import { ROLE } from '../../constants.js';
3
+
4
+ export default class MisoSortElement extends MisoComponentElement {
5
+
6
+ constructor() {
7
+ super({
8
+ role: ROLE.SORT,
9
+ });
10
+ }
11
+
12
+ static get tagName() {
13
+ return 'miso-sort';
14
+ }
15
+
16
+ }
@@ -165,7 +165,7 @@ export default class AffiliationLayout extends CollectionLayout {
165
165
 
166
166
  initialize(view) {
167
167
  super.initialize(view);
168
- const { viewable: options } = this._view.tracker.options || {};
168
+ const { viewable: options } = this._view.trackerOptions || {};
169
169
  this._viewable = new CarouselItemViewabilityObserver(this._onViewable.bind(this), options);
170
170
  }
171
171
 
@@ -82,7 +82,7 @@ export default class ContainerLayout extends RafLayout {
82
82
  }
83
83
 
84
84
  _trackImpression() {
85
- const { impression: options } = this._view.tracker.options || {};
85
+ const { impression: options } = this._view.trackerOptions || {};
86
86
  if (!options) {
87
87
  return;
88
88
  }
@@ -94,7 +94,7 @@ export default class ContainerLayout extends RafLayout {
94
94
  }
95
95
 
96
96
  async _trackViewable(element) {
97
- const { viewable: options } = this._view.tracker.options || {};
97
+ const { viewable: options } = this._view.trackerOptions || {};
98
98
  if (!options) {
99
99
  return;
100
100
  }
@@ -13,4 +13,5 @@ export { default as TextLayout } from './text/text.js';
13
13
  export { default as TypewriterLayout } from './text/typewriter/index.js';
14
14
  export { default as AffiliationLayout } from './affiliation/affiliation.js';
15
15
  export { default as FacetsLayout } from './input/facets.js';
16
+ export { default as SelectLayout } from './input/select.js';
16
17
  export { default as MoreButtonLayout } from './button/more-button.js';
@@ -1,4 +1,5 @@
1
1
  import { escapeHtml } from '@miso.ai/commons';
2
+ import { fields } from '../../actor/index.js';
2
3
  import TemplateBasedLayout from '../template.js';
3
4
  import Bindings from '../../util/bindings.js';
4
5
 
@@ -109,7 +110,7 @@ export default class FacetsLayout extends TemplateBasedLayout {
109
110
  }
110
111
 
111
112
  initialize(view) {
112
- const { proxyElement, hub, filters } = view;
113
+ const { proxyElement, filters } = view;
113
114
  this._unsubscribes = [
114
115
  ...this._unsubscribes,
115
116
  proxyElement.on('click', (e) => this._handleClick(e)),
@@ -132,7 +133,7 @@ export default class FacetsLayout extends TemplateBasedLayout {
132
133
  }
133
134
 
134
135
  _syncSelections() {
135
- const selectedValues = getSelectedValues(this._view.filters.states.facets);
136
+ const selectedValues = getSelectedValues(this._view.hub.states[fields.filters()].facets);
136
137
  for (const { value: { field, value }, element } of this._bindings.entries) {
137
138
  this._setSelected(element, selectedValues[field] && selectedValues[field].has(value));
138
139
  }
@@ -338,7 +338,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
338
338
  }
339
339
 
340
340
  _trackSubmit(value) {
341
- const { [EVENT_TYPE.SUBMIT]: options } = this._view.tracker.options || {};
341
+ const { [EVENT_TYPE.SUBMIT]: options } = this._view.trackerOptions || {};
342
342
  if (!options) {
343
343
  return;
344
344
  }
@@ -0,0 +1,142 @@
1
+ import { escapeHtml, kebabOrSnakeToHuman } from '@miso.ai/commons';
2
+ import TemplateBasedLayout from '../template.js';
3
+ import { makeTrackable } from '../trackable.js';
4
+
5
+ const TYPE = 'select';
6
+ const DEFAULT_CLASSNAME = 'miso-select';
7
+
8
+ function root(layout, state) {
9
+ const { className, role, templates } = layout;
10
+ const roleAttr = role ? `data-role="${role}"` : '';
11
+ const values = layout._getItems(state);
12
+ const selected = values.find(value => value.selected) || values[0];
13
+ return `
14
+ <div class="${className}" ${roleAttr}>
15
+ ${templates.button(layout, selected)}
16
+ ${templates.options(layout, state)}
17
+ </div>`;
18
+ }
19
+
20
+ function button(layout, value) {
21
+ const { className, templates } = layout;
22
+ return `<button class="${className}__button" data-role="button" tabindex="0">${templates.text(layout, value)}</button>`;
23
+ }
24
+
25
+ function options(layout, state) {
26
+ const { className, templates } = layout;
27
+ const values = layout._getItems(state);
28
+ return `<ul class="${className}__options">${values.map((value, index) => templates.option(layout, value, { index })).join('')}</ul>`;
29
+ }
30
+
31
+ function option(layout, value) {
32
+ const { className, templates } = layout;
33
+ const selectedClass = value.selected ? 'selected' : '';
34
+ return `<li class="${className}__option ${selectedClass}" data-role="option" tabindex="0">${templates.text(layout, value)}</li>`;
35
+ }
36
+
37
+ function text(layout, value) {
38
+ return escapeHtml(value && value.text && kebabOrSnakeToHuman(value.text) || value || '');
39
+ }
40
+
41
+ const DEFAULT_TEMPLATES = Object.freeze({
42
+ root,
43
+ button,
44
+ options,
45
+ option,
46
+ text,
47
+ });
48
+
49
+ export default class SelectLayout extends TemplateBasedLayout {
50
+
51
+ static get type() {
52
+ return TYPE;
53
+ }
54
+
55
+ static get defaultTemplates() {
56
+ return DEFAULT_TEMPLATES;
57
+ }
58
+
59
+ static get defaultClassName() {
60
+ return DEFAULT_CLASSNAME;
61
+ }
62
+
63
+ constructor({ className = DEFAULT_CLASSNAME, templates, ...options } = {}) {
64
+ super({
65
+ className,
66
+ templates: { ...DEFAULT_TEMPLATES, ...templates },
67
+ ...options,
68
+ });
69
+ this._initTrackable();
70
+ }
71
+
72
+ initialize(view) {
73
+ const { proxyElement } = view;
74
+ this._unsubscribes = [
75
+ ...this._unsubscribes,
76
+ proxyElement.on('click', (e) => this._handleClick(e)),
77
+ ];
78
+ }
79
+
80
+ _afterRender(element, state) {
81
+ this._syncBindings(element, state);
82
+
83
+ }
84
+
85
+ _unrender() {
86
+ this._clearBindings();
87
+ }
88
+
89
+ _getItems(state) {
90
+ return state.value || [];
91
+ }
92
+
93
+ _getOptionsElement(element) {
94
+ return element.querySelector(`[data-role="options"]`);
95
+ }
96
+
97
+ _getItemElements(element) {
98
+ return element ? Array.from(element.querySelectorAll(`[data-role="option"]`)) : [];
99
+ }
100
+
101
+ _handleClick(event) {
102
+ if (!this._element) {
103
+ return;
104
+ }
105
+ for (let element = event.target; element && element !== this._element; element = element.parentElement) {
106
+ const { role } = element.dataset;
107
+ switch (role) {
108
+ case 'button':
109
+ this._toggle();
110
+ break;
111
+ case 'option':
112
+ const binding = this._bindings.get(element);
113
+ this._select(binding && binding.value);
114
+ break;
115
+ }
116
+ }
117
+ }
118
+
119
+ _toggle() {
120
+ if (!this._element) {
121
+ return;
122
+ }
123
+ const child = this._element.children[0];
124
+ child && child.classList.toggle('open');
125
+ }
126
+
127
+ async _select(value) {
128
+ if (!value) {
129
+ return;
130
+ }
131
+ // TODO: reflect selection right away
132
+ this._view._events.emit('select', { value });
133
+ }
134
+
135
+ destroy() {
136
+ this._destroyTrackable();
137
+ super.destroy();
138
+ }
139
+
140
+ }
141
+
142
+ makeTrackable(SelectLayout.prototype);
package/src/layout/raf.js CHANGED
@@ -2,8 +2,8 @@ import { defineValues, requestAnimationFrame as raf, capture } from '@miso.ai/co
2
2
 
3
3
  export default class RafLayout {
4
4
 
5
- constructor({ role, workflow, workflowOptions, ...options } = {}) {
6
- defineValues(this, { role, workflow, workflowOptions, options });
5
+ constructor({ role, workflow, ...options } = {}) {
6
+ defineValues(this, { role, workflow, options });
7
7
  this._unsubscribes = [];
8
8
  this._rendered = new WeakMap();
9
9
  this._element = undefined;
@@ -51,7 +51,7 @@ export class TrackableMixin {
51
51
  if (entries.length === 0) {
52
52
  return;
53
53
  }
54
- const { impression: options } = this._view.tracker.options || {};
54
+ const { impression: options } = this._view.trackerOptions || {};
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.tracker.options || {};
71
+ const { viewable: options } = this._view.trackerOptions || {};
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.tracker.options || {};
81
+ const { click: options } = this._view.trackerOptions || {};
82
82
  if (validateClick(options, event, binding)) {
83
83
  this._view.tracker.click([binding.value]);
84
84
  }
@@ -16,7 +16,7 @@ export class TriggerableMixin {
16
16
  if (!this.options.infiniteScroll) {
17
17
  return;
18
18
  }
19
- const workflowPaginationOptions = this.workflowOptions.pagination;
19
+ const workflowPaginationOptions = this._view.workflowOptions.pagination;
20
20
  if (!workflowPaginationOptions.active || workflowPaginationOptions.mode !== 'infiniteScroll') {
21
21
  return;
22
22
  }
@@ -1,5 +1,7 @@
1
1
  import { findInAncestors, trimObj } from '@miso.ai/commons';
2
2
 
3
+ // TODO: think about how to incorporate this with workflow options
4
+
3
5
  const DEFAULT_TRACKER_OPTIONS = Object.freeze({
4
6
  impression: Object.freeze({
5
7
  }),
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export default '1.11.4-beta.1';
1
+ export default '1.11.4-beta.3';
@@ -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.js';
7
+ import { mergeRolesOptions } from './options/index.js';
8
8
  import { writeAnswerStageToMeta, mergeInteraction } from './processors.js';
9
9
  import { enableUseLink } from './use-link.js';
10
10
 
@@ -4,6 +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
8
 
8
9
  const DEFAULT_API_OPTIONS = Object.freeze({
9
10
  ...AnswerBasedWorkflow.DEFAULT_API_OPTIONS,
@@ -38,7 +39,9 @@ const DEFAULT_OPTIONS = Object.freeze({
38
39
  trackers: DEFAULT_TRACKERS,
39
40
  });
40
41
 
41
- const ROLES_OPTIONS = AnswerBasedWorkflow.ROLES_OPTIONS;
42
+ const ROLES_OPTIONS = mergeRolesOptions(AnswerBasedWorkflow.ROLES_OPTIONS, {
43
+ members: Object.keys(DEFAULT_LAYOUTS),
44
+ });
42
45
 
43
46
  export default class Ask extends AnswerBasedWorkflow {
44
47
 
@@ -3,7 +3,7 @@ import { Hub, SessionMaker, DataActor, ViewsActor, InteractionsActor, fields } f
3
3
  import * as sources from '../source.js';
4
4
  import { STATUS, ROLE } from '../constants.js';
5
5
  import { ContainerLayout, ErrorLayout } from '../layout/index.js';
6
- import { WorkflowOptions, mergeApiOptions, makeConfigurable } from './options.js';
6
+ import { WorkflowOptions, mergeApiOptions, makeConfigurable } from './options/index.js';
7
7
  import { getRevision, writeDataStatus, writeMisoIdToMeta, buildBaseInteraction, writeAffiliationInfoToInteraction, mergeInteraction } from './processors.js';
8
8
 
9
9
  // TODO: just bury this into hub
@@ -1,5 +1,5 @@
1
1
  import { Component } from '@miso.ai/commons';
2
- import { WorkflowContextOptions, makeConfigurable } from './options.js';
2
+ import { WorkflowContextOptions, makeConfigurable } from './options/index.js';
3
3
 
4
4
  export default class WorkflowContext extends Component {
5
5
 
@@ -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.js';
6
+ import { mergeRolesOptions } from './options/index.js';
7
7
  import { enableUseLink, UseLinkMixin } from './use-link.js';
8
8
 
9
9
  const DEFAULT_API_OPTIONS = Object.freeze({
@@ -1,6 +1,6 @@
1
1
  import AnswerBasedWorkflow from './answer-based.js';
2
2
  import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
3
- import { mergeRolesOptions } from './options.js';
3
+ import { mergeRolesOptions } from './options/index.js';
4
4
  import { writeKeywordsToData } from './processors.js';
5
5
  import { makeAutocompletable } from './autocompletable.js';
6
6
 
@@ -42,10 +42,15 @@ export default class HybridSearchAnswer extends AnswerBasedWorkflow {
42
42
  }
43
43
 
44
44
  // query //
45
- _buildPayload({ q, qs, ...payload } = {}) {
45
+ _buildPayload(payload) {
46
+ payload = this._writeQuestionSourceToPayload(payload);
47
+ payload = this._superworkflow._results._writeFiltersToPayload(payload);
48
+ return payload;
49
+ }
50
+
51
+ _writeQuestionSourceToPayload({ qs, ...payload } = {}) {
46
52
  return {
47
53
  ...payload,
48
- q, // q, not question
49
54
  _meta: {
50
55
  ...payload._meta,
51
56
  question_source: qs || ORGANIC_QUESTION_SOURCE, // might be null, not undefined
@@ -2,11 +2,12 @@ import { trimObj } from '@miso.ai/commons';
2
2
  import SearchBasedWorkflow from './search-based.js';
3
3
  import { fields } from '../actor/index.js';
4
4
  import { ROLE } from '../constants.js';
5
- import { mergeRolesOptions } from './options.js';
6
5
 
7
- const ROLES_OPTIONS = mergeRolesOptions(SearchBasedWorkflow.ROLES_OPTIONS, {
8
- members: [ROLE.PRODUCTS, ROLE.KEYWORDS, ROLE.TOTAL, ROLE.FACETS, ROLE.MORE],
9
- });
6
+ // we want to override members, not adding to it
7
+ const ROLES_OPTIONS = {
8
+ ...SearchBasedWorkflow.ROLES_OPTIONS,
9
+ members: [ROLE.PRODUCTS, ROLE.KEYWORDS, ROLE.TOTAL, ROLE.FACETS, ROLE.SORT, ROLE.MORE, ROLE.ERROR],
10
+ };
10
11
 
11
12
  export default class HybridSearchResults extends SearchBasedWorkflow {
12
13
 
@@ -41,14 +42,23 @@ export default class HybridSearchResults extends SearchBasedWorkflow {
41
42
  return this._superworkflow._answer._hub.states[fields.query()];
42
43
  }
43
44
 
44
- _buildPayload({ filters, ...payload } = {}) {
45
+ _buildPayload(payload) {
45
46
  // borrow the work from the sibling
46
- payload = this._superworkflow._answer._buildPayload(payload);
47
- payload = SearchBasedWorkflow.prototype._buildPayload.call(this, { filters, ...payload });
47
+ payload = this._superworkflow._answer._writeQuestionSourceToPayload(payload);
48
+ payload = this._writeFiltersToPayload(payload);
49
+ payload = this._writePageInfoToPayload(payload);
48
50
  payload = this._writeQuestionIdToPayload(payload);
49
51
  return { ...payload, answer: false };
50
52
  }
51
53
 
54
+ _buildOrderBy(sort) {
55
+ if (!sort) {
56
+ return undefined;
57
+ }
58
+ // works differently than search
59
+ return sort.field;
60
+ }
61
+
52
62
  _writeQuestionIdToPayload(payload) {
53
63
  return {
54
64
  ...payload,
@@ -60,3 +70,7 @@ export default class HybridSearchResults extends SearchBasedWorkflow {
60
70
  }
61
71
 
62
72
  }
73
+
74
+ Object.assign(HybridSearchResults, {
75
+ ROLES_OPTIONS,
76
+ });
@@ -1,17 +1,9 @@
1
1
  import { ROLE } from '../constants.js';
2
+ import HybridSearchResults from './hybrid-search-results.js';
2
3
 
3
4
  function getSubworkflowByRole(role) {
4
5
  // TODO: ROLE.ERROR
5
- switch (role) {
6
- case ROLE.PRODUCTS:
7
- case ROLE.TOTAL:
8
- case ROLE.FACETS:
9
- case ROLE.KEYWORDS:
10
- case ROLE.MORE:
11
- return 'results';
12
- default:
13
- return 'answer';
14
- }
6
+ return HybridSearchResults.ROLES_OPTIONS.members.includes(role) ? 'results' : 'answer';
15
7
  }
16
8
 
17
9
  export default class HybridSearchViewsActor {
@@ -102,10 +94,10 @@ export default class HybridSearchViewsActor {
102
94
  // find the conflicting element
103
95
  for (const component of container.components) {
104
96
  if (otherSubviews.containsElement(component)) {
105
- throw new Error(`<${container.tagName}> cannot contain both <${component.tagName}> and <${child.tagName}>, for they don't share the same data lifecycle.`);
97
+ throw new Error(`<${container.tagName.toLowerCase()}> cannot contain both <${component.tagName.toLowerCase()}> and <${child.tagName.toLowerCase()}>, for they don't share the same data lifecycle.`);
106
98
  }
107
99
  }
108
- throw new Error(`Failed to add container <${container.tagName}> with child component <${child.tagName}>.`);
100
+ throw new Error(`Failed to add container <${container.tagName.toLowerCase()}> with child component <${child.tagName.toLowerCase()}>.`);
109
101
  }
110
102
  }
111
103
  // add the container to the subviews
@@ -3,12 +3,12 @@ import { InteractionsActor } from '../actor/index.js';
3
3
  import Workflow from './base.js';
4
4
  import SearchBasedWorkflow from './search-based.js';
5
5
  import AnswerBasedWorkflow from './answer-based.js';
6
- import { ROLE } from '../constants.js';
6
+ import { ROLE, WORKFLOW_CONFIGURABLE } from '../constants.js';
7
7
  import { SearchBoxLayout, TextLayout } from '../layout/index.js';
8
8
  import HybridSearchAnswer from './hybrid-search-answer.js';
9
9
  import HybridSearchResults from './hybrid-search-results.js';
10
10
  import HybridSearchViewsActor from './hybrid-search-views.js';
11
- import { makeConfigurable } from './options.js';
11
+ import { makeConfigurable } from './options/index.js';
12
12
 
13
13
  const DEFAULT_API_OPTIONS = Object.freeze({
14
14
  group: API.GROUP.ASK,
@@ -162,4 +162,4 @@ export default class HybridSearch extends Workflow {
162
162
 
163
163
  }
164
164
 
165
- makeConfigurable(HybridSearch.prototype, ['pagination']);
165
+ makeConfigurable(HybridSearch.prototype, [WORKFLOW_CONFIGURABLE.PAGINATION, WORKFLOW_CONFIGURABLE.FILTERS]);