@miso.ai/client-sdk-ui 1.11.4-beta.0 → 1.11.4-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/cjs/actor/fields.js +0 -4
  2. package/dist/cjs/actor/filters.js +57 -11
  3. package/dist/cjs/actor/tracker.js +1 -6
  4. package/dist/cjs/actor/view.js +6 -8
  5. package/dist/cjs/actor/views.js +10 -26
  6. package/dist/cjs/constants.js +12 -2
  7. package/dist/cjs/element/role/index.js +7 -0
  8. package/dist/cjs/element/role/miso-sort.js +20 -0
  9. package/dist/cjs/layout/affiliation/affiliation.js +1 -1
  10. package/dist/cjs/layout/container/container.js +2 -2
  11. package/dist/cjs/layout/index.js +7 -0
  12. package/dist/cjs/layout/input/facets.js +2 -2
  13. package/dist/cjs/layout/input/search-box.js +1 -1
  14. package/dist/cjs/layout/input/select.js +150 -0
  15. package/dist/cjs/layout/raf.js +2 -4
  16. package/dist/cjs/layout/text/typewriter/index.js +3 -2
  17. package/dist/cjs/layout/trackable.js +3 -3
  18. package/dist/cjs/layout/triggerable.js +1 -1
  19. package/dist/cjs/util/trackers.js +2 -0
  20. package/dist/cjs/version.js +1 -1
  21. package/dist/cjs/workflow/answer-based.js +19 -3
  22. package/dist/cjs/workflow/ask.js +4 -1
  23. package/dist/cjs/workflow/base.js +27 -4
  24. package/dist/cjs/workflow/context.js +3 -3
  25. package/dist/cjs/workflow/explore.js +2 -2
  26. package/dist/cjs/workflow/hybrid-search-answer.js +9 -7
  27. package/dist/cjs/workflow/hybrid-search-results.js +18 -16
  28. package/dist/cjs/workflow/hybrid-search-views.js +5 -12
  29. package/dist/cjs/workflow/hybrid-search.js +9 -1
  30. package/dist/cjs/workflow/options/api.js +56 -0
  31. package/dist/cjs/workflow/options/configurable.js +49 -0
  32. package/dist/cjs/workflow/options/data-processor.js +23 -0
  33. package/dist/cjs/workflow/options/filters.js +18 -0
  34. package/dist/cjs/workflow/options/index.js +115 -0
  35. package/dist/cjs/workflow/options/interactions.js +44 -0
  36. package/dist/cjs/workflow/options/layouts.js +83 -0
  37. package/dist/cjs/workflow/options/options.js +154 -0
  38. package/dist/cjs/workflow/options/pagination.js +28 -0
  39. package/dist/cjs/workflow/options/roles.js +17 -0
  40. package/dist/cjs/workflow/options/trackers.js +39 -0
  41. package/dist/cjs/workflow/options/utils.js +33 -0
  42. package/dist/cjs/workflow/processors.js +39 -33
  43. package/dist/cjs/workflow/recommendation.js +2 -2
  44. package/dist/cjs/workflow/search-based.js +59 -22
  45. package/package.json +2 -2
  46. package/src/actor/fields.js +0 -4
  47. package/src/actor/filters.js +53 -12
  48. package/src/actor/tracker.js +1 -6
  49. package/src/actor/view.js +7 -8
  50. package/src/actor/views.js +9 -30
  51. package/src/constants.js +11 -0
  52. package/src/element/role/index.js +1 -0
  53. package/src/element/role/miso-sort.js +16 -0
  54. package/src/layout/affiliation/affiliation.js +1 -1
  55. package/src/layout/container/container.js +2 -2
  56. package/src/layout/index.js +1 -0
  57. package/src/layout/input/facets.js +3 -2
  58. package/src/layout/input/search-box.js +1 -1
  59. package/src/layout/input/select.js +142 -0
  60. package/src/layout/raf.js +2 -2
  61. package/src/layout/text/typewriter/index.js +3 -2
  62. package/src/layout/trackable.js +3 -3
  63. package/src/layout/triggerable.js +1 -1
  64. package/src/util/trackers.js +2 -0
  65. package/src/version.js +1 -1
  66. package/src/workflow/answer-based.js +16 -2
  67. package/src/workflow/ask.js +4 -1
  68. package/src/workflow/base.js +22 -1
  69. package/src/workflow/context.js +1 -1
  70. package/src/workflow/explore.js +1 -1
  71. package/src/workflow/hybrid-search-answer.js +8 -3
  72. package/src/workflow/hybrid-search-results.js +21 -7
  73. package/src/workflow/hybrid-search-views.js +4 -12
  74. package/src/workflow/hybrid-search.js +12 -1
  75. package/src/workflow/options/api.js +46 -0
  76. package/src/workflow/options/configurable.js +48 -0
  77. package/src/workflow/options/data-processor.js +15 -0
  78. package/src/workflow/options/filters.js +10 -0
  79. package/src/workflow/options/index.js +10 -0
  80. package/src/workflow/options/interactions.js +36 -0
  81. package/src/workflow/options/layouts.js +73 -0
  82. package/src/workflow/options/options.js +169 -0
  83. package/src/workflow/options/pagination.js +18 -0
  84. package/src/workflow/options/roles.js +12 -0
  85. package/src/workflow/options/trackers.js +32 -0
  86. package/src/workflow/options/utils.js +26 -0
  87. package/src/workflow/processors.js +30 -34
  88. package/src/workflow/recommendation.js +1 -1
  89. package/src/workflow/search-based.js +58 -13
  90. package/dist/cjs/workflow/options.js +0 -448
  91. package/src/workflow/options.js +0 -433
@@ -0,0 +1,32 @@
1
+ import { mergeOptions } from './utils.js';
2
+
3
+ export function normalizeTrackersOptions(options) {
4
+ if (options === undefined || options === false) {
5
+ return options;
6
+ }
7
+ const normalized = {};
8
+ for (const [role, args] of Object.entries(options)) {
9
+ normalized[role] = normalizeTrackerOptions(args);
10
+ }
11
+ return normalized;
12
+ }
13
+
14
+ function normalizeTrackerOptions(options) {
15
+ return options;
16
+ }
17
+
18
+ export function mergeTrackersOptions(...optionsList) {
19
+ if (optionsList[optionsList.length - 1] === false) {
20
+ return false;
21
+ }
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
+ }));
28
+ }
29
+
30
+ function mergeTrackerEventOptions(base = {}, overrides = {}) {
31
+ return (overrides === false || base === false) ? overrides : { ...base, ...overrides };
32
+ }
@@ -0,0 +1,26 @@
1
+ import { trimObj } from '@miso.ai/commons';
2
+
3
+ export function concatArrays(a0, a1) {
4
+ return (a0 && a0.length) ? (a1 && a1.length) ? [...a0, ...a1] : a0 : a1;
5
+ }
6
+
7
+ export function mergeOptions(optionsList, merge) {
8
+ let merged = {};
9
+ for (const options of optionsList) {
10
+ if (!options) {
11
+ continue;
12
+ }
13
+ merged = merge(merged, options);
14
+ }
15
+ return trimObj(merged);
16
+ }
17
+
18
+ export function normalizeOptions(options) {
19
+ if (options === undefined) {
20
+ throw new Error(`Expect options to be an object or a boolean value: ${options}`);
21
+ }
22
+ if (typeof options === 'boolean') {
23
+ options = { active: options };
24
+ }
25
+ return options;
26
+ }
@@ -1,5 +1,35 @@
1
1
  import { trimObj } from '@miso.ai/commons';
2
2
  import { STATUS, ROLE, EVENT_TYPE, isPerformanceEventType, isProductRole } from '../constants.js';
3
+ import { fields } from '../actor/index.js';
4
+
5
+ // role mappings //
6
+ export function mappingSortData(_, { hub, workflowOptions = {} } = {}) {
7
+ const { sort: { options = [] } = {} } = workflowOptions.filters || {};
8
+ if (!options.length) {
9
+ return [];
10
+ }
11
+ const { sort } = hub.states[fields.filters()] || {};
12
+ const selectedField = (sort && sort.field) || findDefaultSortOption(options).field;
13
+ if (!selectedField) {
14
+ return options;
15
+ }
16
+ // mark selected
17
+ return options.map(option => {
18
+ return {
19
+ ...option,
20
+ selected: option.field === selectedField,
21
+ };
22
+ });
23
+ }
24
+
25
+ function findDefaultSortOption(options) {
26
+ for (const option of options) {
27
+ if (option.default) {
28
+ return option;
29
+ }
30
+ }
31
+ return options[0];
32
+ }
3
33
 
4
34
  // data //
5
35
  export function getRevision(data) {
@@ -79,40 +109,6 @@ export function writeAnswerStageToMeta(data) {
79
109
  };
80
110
  }
81
111
 
82
- export function writeFiltersToPayload(payload = {}, filters) {
83
- return trimObj({
84
- ...payload,
85
- ...composeFiltersPayload(filters),
86
- });
87
- }
88
-
89
- function composeFiltersPayload(filters) {
90
- if (!filters) {
91
- return undefined;
92
- }
93
- const { facets } = filters;
94
- return trimObj({
95
- facet_filters: composeFacetFilters(facets),
96
- });
97
- }
98
-
99
- function composeFacetFilters(facets) {
100
- if (!facets) {
101
- return undefined;
102
- }
103
- const filters = {};
104
- for (const field in facets) {
105
- const values = facets[field];
106
- if (!values || !values.length) {
107
- continue; // just in case
108
- }
109
- filters[field] = {
110
- terms: values,
111
- };
112
- }
113
- return Object.keys(filters).length ? filters : undefined;
114
- }
115
-
116
112
  export function retainFacetCountsInData(data, currentFacetCounts) {
117
113
  if (!currentFacetCounts) {
118
114
  return data;
@@ -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.js';
5
+ import { mergeRolesOptions } from './options/index.js';
6
6
  import { mergeInteraction } from './processors.js';
7
7
 
8
8
  const DEFAULT_API_OPTIONS = Object.freeze({
@@ -1,10 +1,10 @@
1
- import { API } from '@miso.ai/commons';
1
+ import { API, asArray, trimObj } from '@miso.ai/commons';
2
2
  import Workflow from './base.js';
3
3
  import { fields } from '../actor/index.js';
4
- import { STATUS, ROLE } from '../constants.js';
5
- import { SearchBoxLayout, ListLayout, TextLayout, FacetsLayout, MoreButtonLayout } from '../layout/index.js';
6
- import { writeKeywordsToData, writeFiltersToPayload, retainFacetCountsInData, writeExhaustionToData, concatItemsFromMoreResponse } from './processors.js';
7
- import { mergeRolesOptions, makeConfigurable } from './options.js';
4
+ import { STATUS, ROLE, WORKFLOW_CONFIGURABLE } from '../constants.js';
5
+ import { SearchBoxLayout, ListLayout, TextLayout, FacetsLayout, SelectLayout, MoreButtonLayout } from '../layout/index.js';
6
+ import { mappingSortData, writeKeywordsToData, retainFacetCountsInData, writeExhaustionToData, concatItemsFromMoreResponse } from './processors.js';
7
+ import { mergeRolesOptions, makeConfigurable } from './options/index.js';
8
8
 
9
9
  const DEFAULT_ROWS = 10;
10
10
  const DEFAULT_PAGE_LIMIT = 10;
@@ -26,6 +26,7 @@ const DEFAULT_LAYOUTS = Object.freeze({
26
26
  [ROLE.KEYWORDS]: [TextLayout.type, { raw: true }],
27
27
  [ROLE.TOTAL]: [TextLayout.type, { raw: true, format: 'number' }],
28
28
  [ROLE.FACETS]: [FacetsLayout.type],
29
+ [ROLE.SORT]: [SelectLayout.type],
29
30
  [ROLE.MORE]: [MoreButtonLayout.type],
30
31
  });
31
32
 
@@ -53,6 +54,7 @@ const ROLES_OPTIONS = mergeRolesOptions(Workflow.ROLES_OPTIONS, {
53
54
  members: Object.keys(DEFAULT_LAYOUTS),
54
55
  mappings: {
55
56
  [ROLE.FACETS]: 'facet_counts',
57
+ [ROLE.SORT]: mappingSortData,
56
58
  },
57
59
  });
58
60
 
@@ -63,8 +65,9 @@ export default class SearchBasedWorkflow extends Workflow {
63
65
  this._unsubscribes = [
64
66
  ...this._unsubscribes,
65
67
  this._hub.on(fields.query(), args => this._query(args)),
66
- this._hub.on(fields.filters(), filters => this._refine(filters)),
68
+ this._hub.on(fields.filters(), () => this._refine()),
67
69
  this._hub.on(fields.more(), () => this._more()),
70
+ this._views.get(ROLE.SORT).on('select', event => this._handleSortSelect(event)),
68
71
  ];
69
72
  }
70
73
 
@@ -104,7 +107,7 @@ export default class SearchBasedWorkflow extends Workflow {
104
107
  this._request({ payload });
105
108
  }
106
109
 
107
- _refine(filters) {
110
+ _refine() {
108
111
  // remember current facet_counts
109
112
  const { facet_counts } = this._hub.states[fields.data()].value || {};
110
113
  this._currentFacetCounts = facet_counts;
@@ -114,7 +117,7 @@ export default class SearchBasedWorkflow extends Workflow {
114
117
 
115
118
  // payload
116
119
  const query = this._getQuery();
117
- const payload = this._buildPayload({ ...query, filters });
120
+ const payload = this._buildPayload(query);
118
121
 
119
122
  this._request({ payload });
120
123
  }
@@ -134,8 +137,7 @@ export default class SearchBasedWorkflow extends Workflow {
134
137
 
135
138
  // payload
136
139
  const query = this._getQuery();
137
- const filters = this._hub.states[fields.filters()]; // get stored filters
138
- let payload = this._buildPayload({ ...query, filters });
140
+ let payload = this._buildPayload(query);
139
141
  payload = this._processPayloadForMoreRequest(payload);
140
142
 
141
143
  this._request({ payload });
@@ -150,12 +152,46 @@ export default class SearchBasedWorkflow extends Workflow {
150
152
  return this._options.resolved.api.payload.rows;
151
153
  }
152
154
 
153
- _buildPayload({ filters, ...payload } = {}) {
154
- payload = writeFiltersToPayload(payload, filters);
155
+ _buildPayload(payload) {
156
+ payload = this._writeFiltersToPayload(payload);
155
157
  payload = this._writePageInfoToPayload(payload);
156
158
  return payload;
157
159
  }
158
160
 
161
+ _writeFiltersToPayload(payload) {
162
+ const filters = this._hub.states[fields.filters()];
163
+ const { facets, sort } = filters || {};
164
+ return trimObj({
165
+ ...payload,
166
+ facet_filters: this._buildFacetFilters(facets),
167
+ order_by: this._buildOrderBy(sort),
168
+ });
169
+ }
170
+
171
+ _buildFacetFilters(facets) {
172
+ if (!facets) {
173
+ return undefined;
174
+ }
175
+ const filters = {};
176
+ for (const field in facets) {
177
+ const values = facets[field];
178
+ if (!values || !values.length) {
179
+ continue; // just in case
180
+ }
181
+ filters[field] = {
182
+ terms: values,
183
+ };
184
+ }
185
+ return Object.keys(filters).length ? filters : undefined;
186
+ }
187
+
188
+ _buildOrderBy(sort) {
189
+ if (!sort) {
190
+ return undefined;
191
+ }
192
+ return asArray(sort);
193
+ }
194
+
159
195
  _writePageInfoToPayload(payload) {
160
196
  return {
161
197
  ...payload,
@@ -208,9 +244,18 @@ export default class SearchBasedWorkflow extends Workflow {
208
244
  return concatItemsFromMoreResponse(currentData, data, { role: this._roles.main });
209
245
  }
210
246
 
247
+ // view actions //
248
+ _handleSortSelect({ value } = {}) {
249
+ if (!value) {
250
+ return;
251
+ }
252
+ this._views.filters.update({ sort: value });
253
+ this._views.filters.apply();
254
+ }
255
+
211
256
  }
212
257
 
213
- makeConfigurable(SearchBasedWorkflow.prototype, ['pagination']);
258
+ makeConfigurable(SearchBasedWorkflow.prototype, [WORKFLOW_CONFIGURABLE.PAGINATION, WORKFLOW_CONFIGURABLE.FILTERS]);
214
259
 
215
260
  Object.assign(SearchBasedWorkflow, {
216
261
  DEFAULT_API_OPTIONS,