@miso.ai/client-sdk-ui 1.10.0-beta.0 → 1.10.0-beta.10
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/dist/cjs/actor/autocomplete.js +157 -0
- package/dist/cjs/actor/data.js +4 -12
- package/dist/cjs/actor/fields.js +8 -0
- package/dist/cjs/actor/index.js +7 -0
- package/dist/cjs/actor/tracker.js +46 -70
- package/dist/cjs/actor/trackers.js +5 -1
- package/dist/cjs/actor/utils.js +16 -2
- package/dist/cjs/actor/view.js +14 -3
- package/dist/cjs/actor/views.js +9 -1
- package/dist/cjs/affiliation/index.js +126 -0
- package/dist/cjs/combo/ask/options.js +1 -1
- package/dist/cjs/combo/base.js +1 -1
- package/dist/cjs/constants.js +6 -3
- package/dist/cjs/defaults/ask/controls.js +1 -1
- package/dist/cjs/defaults/ask/phrases.js +1 -1
- package/dist/cjs/defaults/ask/templates.js +35 -4
- package/dist/cjs/element/role/index.js +7 -0
- package/dist/cjs/element/role/miso-affiliation.js +20 -0
- package/dist/cjs/layout/affiliation/affiliation.js +330 -0
- package/dist/cjs/layout/banner/banner.js +1 -1
- package/dist/cjs/layout/container/container.js +1 -1
- package/dist/cjs/layout/error/error.js +1 -1
- package/dist/cjs/layout/index.js +7 -0
- package/dist/cjs/layout/input/option-list.js +35 -50
- package/dist/cjs/layout/input/search-box.js +227 -129
- package/dist/cjs/layout/list/cards.js +1 -1
- package/dist/cjs/layout/list/carousel.js +5 -3
- package/dist/cjs/layout/list/collection.js +44 -49
- package/dist/cjs/layout/list/list.js +1 -1
- package/dist/cjs/layout/radio/feedback.js +1 -1
- package/dist/cjs/layout/radio/radio.js +1 -1
- package/dist/cjs/layout/raf.js +1 -1
- package/dist/cjs/layout/template.js +1 -1
- package/dist/cjs/layout/templates.js +172 -66
- package/dist/cjs/layout/text/text.js +1 -1
- package/dist/cjs/layout/text/typewriter/index.js +3 -3
- package/dist/cjs/layout/trackable.js +124 -0
- package/dist/cjs/plugin.js +1 -1
- package/dist/cjs/source/index.js +20 -8
- package/dist/cjs/util/bindings.js +58 -110
- package/dist/cjs/util/states.js +31 -24
- package/dist/cjs/util/trackers.js +75 -0
- package/dist/cjs/util/viewables.js +55 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/ask.js +60 -19
- package/dist/cjs/workflow/asks.js +1 -1
- package/dist/cjs/workflow/base.js +6 -7
- package/dist/cjs/workflow/explore.js +5 -2
- package/dist/cjs/workflow/options.js +60 -14
- package/dist/cjs/workflow/recommendation.js +2 -0
- package/dist/cjs/workflow/search.js +35 -7
- package/package.json +2 -2
- package/src/actor/autocomplete.js +131 -0
- package/src/actor/data.js +3 -10
- package/src/actor/fields.js +8 -0
- package/src/actor/index.js +1 -0
- package/src/actor/tracker.js +39 -62
- package/src/actor/trackers.js +3 -1
- package/src/actor/utils.js +14 -2
- package/src/actor/view.js +12 -1
- package/src/actor/views.js +11 -0
- package/src/affiliation/index.js +108 -0
- package/src/constants.js +10 -1
- package/src/defaults/ask/phrases.js +1 -1
- package/src/defaults/ask/templates.js +34 -2
- package/src/element/role/index.js +1 -0
- package/src/element/role/miso-affiliation.js +16 -0
- package/src/layout/affiliation/affiliation.js +295 -0
- package/src/layout/index.js +1 -0
- package/src/layout/input/option-list.js +35 -43
- package/src/layout/input/search-box.js +192 -95
- package/src/layout/list/carousel.js +4 -2
- package/src/layout/list/collection.js +42 -43
- package/src/layout/templates.js +127 -46
- package/src/layout/text/typewriter/index.js +2 -2
- package/src/layout/trackable.js +106 -0
- package/src/source/index.js +14 -1
- package/src/util/bindings.js +47 -103
- package/src/util/states.js +26 -20
- package/src/util/trackers.js +69 -0
- package/src/util/viewables.js +47 -0
- package/src/version.js +1 -1
- package/src/workflow/ask.js +37 -3
- package/src/workflow/base.js +2 -3
- package/src/workflow/explore.js +1 -1
- package/src/workflow/options.js +54 -13
- package/src/workflow/recommendation.js +1 -0
- package/src/workflow/search.js +33 -1
- package/dist/cjs/util/tracker.js +0 -348
- package/src/util/tracker.js +0 -318
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { findInAncestors, trimObj } from '@miso.ai/commons';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_TRACKER_OPTIONS = Object.freeze({
|
|
4
|
+
impression: Object.freeze({
|
|
5
|
+
}),
|
|
6
|
+
viewable: Object.freeze({
|
|
7
|
+
area: 0.5,
|
|
8
|
+
duration: 1000,
|
|
9
|
+
}),
|
|
10
|
+
click: Object.freeze({
|
|
11
|
+
lenient: false,
|
|
12
|
+
}),
|
|
13
|
+
watch: false,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function mergeOptions(def, opt) {
|
|
17
|
+
// if opt is falsy then return false, merge otherwise
|
|
18
|
+
return !!opt && { ...def, ...opt };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function normalizeTrackerOptions(options) {
|
|
22
|
+
if (options === false) {
|
|
23
|
+
return false; // turn off all tracking
|
|
24
|
+
}
|
|
25
|
+
if (options === true) {
|
|
26
|
+
options = {};
|
|
27
|
+
}
|
|
28
|
+
if (typeof options !== 'object') {
|
|
29
|
+
throw new Error(`Invalid options: ${options}`);
|
|
30
|
+
}
|
|
31
|
+
const { impression = {}, viewable = {}, click = {}, ...rest } = options;
|
|
32
|
+
return trimObj({
|
|
33
|
+
...DEFAULT_TRACKER_OPTIONS,
|
|
34
|
+
...rest,
|
|
35
|
+
impression: mergeOptions(DEFAULT_TRACKER_OPTIONS.impression, impression),
|
|
36
|
+
viewable: mergeOptions(DEFAULT_TRACKER_OPTIONS.viewable, viewable),
|
|
37
|
+
click: mergeOptions(DEFAULT_TRACKER_OPTIONS.click, click),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function validateClick(options = {}, event) {
|
|
42
|
+
if (!options) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (typeof options.validate === 'function') {
|
|
47
|
+
return options.validate(event);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (options.lenient) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// standard criteria
|
|
55
|
+
// 1. it must be a left click
|
|
56
|
+
if (event.button !== 0) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// 2. event default must not be prevented
|
|
60
|
+
if (event.defaultPrevented) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
// 3. must go through a real link
|
|
64
|
+
if (!findInAncestors(event.target, element => (element.tagName === 'A' && element.href) || undefined)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { viewable as whenViewable } from '@miso.ai/commons';
|
|
2
|
+
|
|
3
|
+
export default class Viewables {
|
|
4
|
+
|
|
5
|
+
constructor() {
|
|
6
|
+
this._entries = new WeakMap();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
isTracked(element) {
|
|
10
|
+
return this._entries.has(element);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async track(element, options = {}) {
|
|
14
|
+
if (!options) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const entry = this._entries.get(element);
|
|
18
|
+
if (entry) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const ac = new AbortController();
|
|
22
|
+
const { signal } = ac;
|
|
23
|
+
this._entries.set(element, { ac });
|
|
24
|
+
let result = false;
|
|
25
|
+
try {
|
|
26
|
+
await whenViewable(element, { ...options, signal });
|
|
27
|
+
result = true;
|
|
28
|
+
} catch (e) {
|
|
29
|
+
if (e.name !== 'AbortError') {
|
|
30
|
+
throw e;
|
|
31
|
+
}
|
|
32
|
+
} finally {
|
|
33
|
+
this._entries.delete(element);
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
untrack(element) {
|
|
39
|
+
const entry = this._entries.get(element);
|
|
40
|
+
if (!entry) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
entry.ac.abort();
|
|
44
|
+
this._entries.delete(element);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.10.0-beta.
|
|
1
|
+
export default '1.10.0-beta.10';
|
package/src/workflow/ask.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { defineValues, trimObj, API } from '@miso.ai/commons';
|
|
2
2
|
import Workflow from './base.js';
|
|
3
3
|
import { mergeApiOptions } from './options.js';
|
|
4
|
-
import
|
|
4
|
+
import * as sources from '../source/index.js';
|
|
5
|
+
import { fields, FeedbackActor, AutocompleteActor } from '../actor/index.js';
|
|
5
6
|
import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
|
|
6
|
-
import { SearchBoxLayout, OptionListLayout, ListLayout, TextLayout, TypewriterLayout, FeedbackLayout } from '../layout/index.js';
|
|
7
|
+
import { SearchBoxLayout, OptionListLayout, ListLayout, TextLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
|
|
8
|
+
import { makeConfigurable } from './options.js';
|
|
9
|
+
import { processData as processAffiliationData } from '../affiliation/index.js';
|
|
7
10
|
|
|
8
11
|
const DEFAULT_API_OPTIONS = Object.freeze({
|
|
9
12
|
group: API.GROUP.ASK,
|
|
@@ -17,6 +20,14 @@ const DEFAULT_API_OPTIONS = Object.freeze({
|
|
|
17
20
|
},
|
|
18
21
|
});
|
|
19
22
|
|
|
23
|
+
const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
|
|
24
|
+
actor: false,
|
|
25
|
+
api: {
|
|
26
|
+
group: API.GROUP.ASK,
|
|
27
|
+
name: API.NAME.AUTOCOMPLETE,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
20
31
|
const DEFAULT_LAYOUTS = Object.freeze({
|
|
21
32
|
[ROLE.QUERY]: [SearchBoxLayout.type, { placeholder: 'Ask a question' }],
|
|
22
33
|
[ROLE.QUESTION]: [TextLayout.type, { tag: 'h2' }],
|
|
@@ -25,13 +36,14 @@ const DEFAULT_LAYOUTS = Object.freeze({
|
|
|
25
36
|
[ROLE.SOURCES]: [ListLayout.type, { incremental: true, itemType: 'article', templates: { ordered: true } }],
|
|
26
37
|
[ROLE.RELATED_RESOURCES]: [ListLayout.type, { incremental: true, itemType: 'article' }],
|
|
27
38
|
[ROLE.QUERY_SUGGESTIONS]: OptionListLayout.type,
|
|
39
|
+
[ROLE.AFFILIATION]: [AffiliationLayout.type, { incremental: true, itemType: 'affiliation', link: { rel: 'noopener nofollow' } }],
|
|
28
40
|
});
|
|
29
41
|
|
|
30
42
|
const DEFAULT_TRACKERS = Object.freeze({
|
|
31
43
|
[ROLE.SOURCES]: {},
|
|
32
44
|
[ROLE.RELATED_RESOURCES]: {},
|
|
45
|
+
[ROLE.AFFILIATION]: {},
|
|
33
46
|
[ROLE.QUERY_SUGGESTIONS]: {
|
|
34
|
-
active: true, // we are tracking events at initial stage, when session is not active yet
|
|
35
47
|
click: {
|
|
36
48
|
validate: event => event.button === 0, // left click only
|
|
37
49
|
},
|
|
@@ -40,6 +52,7 @@ const DEFAULT_TRACKERS = Object.freeze({
|
|
|
40
52
|
|
|
41
53
|
const DEFAULT_OPTIONS = Object.freeze({
|
|
42
54
|
api: DEFAULT_API_OPTIONS,
|
|
55
|
+
autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
|
|
43
56
|
layouts: DEFAULT_LAYOUTS,
|
|
44
57
|
trackers: DEFAULT_TRACKERS,
|
|
45
58
|
});
|
|
@@ -60,6 +73,13 @@ export default class Ask extends Workflow {
|
|
|
60
73
|
this._feedback = new FeedbackActor(this._hub);
|
|
61
74
|
this._setSuggestedQuestions();
|
|
62
75
|
|
|
76
|
+
/*
|
|
77
|
+
this._autocomplete = new AutocompleteActor(this._hub, {
|
|
78
|
+
source: sources.api(this._client),
|
|
79
|
+
options: this._options,
|
|
80
|
+
});
|
|
81
|
+
*/
|
|
82
|
+
|
|
63
83
|
this._unsubscribes = [
|
|
64
84
|
...this._unsubscribes,
|
|
65
85
|
this._hub.on(fields.query(), payload => this.query(payload)),
|
|
@@ -152,6 +172,17 @@ export default class Ask extends Workflow {
|
|
|
152
172
|
super.restart();
|
|
153
173
|
}
|
|
154
174
|
|
|
175
|
+
/*
|
|
176
|
+
updateCompletions(event) {
|
|
177
|
+
// TODO: verify
|
|
178
|
+
this._hub.update(fields.completions(), {
|
|
179
|
+
...event,
|
|
180
|
+
source: 'manual',
|
|
181
|
+
});
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
*/
|
|
185
|
+
|
|
155
186
|
_defaultProcessData(data) {
|
|
156
187
|
data = super._defaultProcessData(data);
|
|
157
188
|
const { value, request } = data;
|
|
@@ -178,6 +209,9 @@ export default class Ask extends Workflow {
|
|
|
178
209
|
}
|
|
179
210
|
}
|
|
180
211
|
|
|
212
|
+
// affiliation
|
|
213
|
+
data = processAffiliationData(data);
|
|
214
|
+
|
|
181
215
|
// 1. put answer_stage to meta
|
|
182
216
|
// 2. mark ongoing flag
|
|
183
217
|
return {
|
package/src/workflow/base.js
CHANGED
|
@@ -42,14 +42,13 @@ export default class Workflow extends Component {
|
|
|
42
42
|
const extensions = this._extensions = plugin._getExtensions(client);
|
|
43
43
|
const options = this._options = new WorkflowOptions(context && context._options, mergeDefaults(this, defaults));
|
|
44
44
|
const hub = this._hub = injectLogger(new Hub(), (...args) => this._log(...args));
|
|
45
|
-
const source = this._source = sources.api(client);
|
|
46
45
|
const layouts = plugin.layouts;
|
|
47
46
|
|
|
48
47
|
this._sessions = new SessionMaker(hub);
|
|
49
|
-
this._data = new DataActor(hub, { source, options });
|
|
48
|
+
this._data = new DataActor(hub, { source: sources.api(client), options });
|
|
50
49
|
const views = this._views = new ViewsActor(hub, { extensions, layouts, roles, options, workflow: name });
|
|
51
|
-
this._interactions = new InteractionsActor(hub, { client, options });
|
|
52
50
|
this._trackers = new Trackers(hub, { views, options });
|
|
51
|
+
this._interactions = new InteractionsActor(hub, { client, options });
|
|
53
52
|
|
|
54
53
|
this._unsubscribes = [
|
|
55
54
|
this._hub.on(fields.response(), data => this.updateData(data)),
|
package/src/workflow/explore.js
CHANGED
|
@@ -11,7 +11,7 @@ const DEFAULT_API_OPTIONS = Object.freeze({
|
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
const DEFAULT_LAYOUTS = Object.freeze({
|
|
14
|
-
[ROLE.RELATED_QUESTIONS]: [ListLayout.type, { itemType: 'question' }],
|
|
14
|
+
[ROLE.RELATED_QUESTIONS]: [ListLayout.type, { itemType: 'question', link: { rel: 'noopener nofollow' } }],
|
|
15
15
|
[ROLE.QUERY]: [SearchBoxLayout.type, { placeholder: 'Ask a question' }],
|
|
16
16
|
});
|
|
17
17
|
|
package/src/workflow/options.js
CHANGED
|
@@ -3,6 +3,7 @@ import { ROLE } from '../constants.js';
|
|
|
3
3
|
|
|
4
4
|
// normalize //
|
|
5
5
|
export function normalizeApiOptions([name, payload] = []) {
|
|
6
|
+
// TODO: take object form as well
|
|
6
7
|
if (name === false) {
|
|
7
8
|
return { actor: false };
|
|
8
9
|
}
|
|
@@ -10,10 +11,14 @@ export function normalizeApiOptions([name, payload] = []) {
|
|
|
10
11
|
payload = name;
|
|
11
12
|
name = undefined;
|
|
12
13
|
}
|
|
14
|
+
let group = undefined;
|
|
15
|
+
if (name && name.indexOf('/') !== -1) {
|
|
16
|
+
[group, name] = name.split('/');
|
|
17
|
+
}
|
|
13
18
|
if ((name && typeof name !== 'string') || (payload !== undefined && typeof payload !== 'object')) {
|
|
14
19
|
throw new Error(`Invalid arguments for useApi(): ${name}, ${payload}`);
|
|
15
20
|
}
|
|
16
|
-
return trimObj({ name, payload });
|
|
21
|
+
return trimObj({ group, name, payload });
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
export function normalizeLayoutsOptions(options = {}) {
|
|
@@ -105,6 +110,17 @@ export function normalizeInteractionsOptions(options) {
|
|
|
105
110
|
return { ...options, preprocess };
|
|
106
111
|
}
|
|
107
112
|
|
|
113
|
+
export function normalizeAutocompleteOptions(options) {
|
|
114
|
+
if (options === undefined) {
|
|
115
|
+
throw new Error(`Expect autocomplete options to be an object or a boolean value: ${options}`);
|
|
116
|
+
}
|
|
117
|
+
if (typeof options === 'boolean') {
|
|
118
|
+
options = { actor: options };
|
|
119
|
+
}
|
|
120
|
+
const processData = normalizeDataProcessorOptions(options.processData);
|
|
121
|
+
return { ...options, processData };
|
|
122
|
+
}
|
|
123
|
+
|
|
108
124
|
// merge //
|
|
109
125
|
export function mergeApiOptions(...optionsList) {
|
|
110
126
|
if (optionsList[optionsList.length - 1] === false) {
|
|
@@ -190,6 +206,17 @@ export function mergeInteractionsOptions(...optionsList) {
|
|
|
190
206
|
}));
|
|
191
207
|
}
|
|
192
208
|
|
|
209
|
+
export function mergeAutocompleteOptions(...optionsList) {
|
|
210
|
+
if (optionsList[optionsList.length - 1] === false) {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
return mergeOptions(optionsList, (merged, options) => Object.assign(merged, {
|
|
214
|
+
...options,
|
|
215
|
+
api: mergeApiOptions(merged.api, options.api),
|
|
216
|
+
processData: mergeDataProcessorOptions(merged.processData, options.processData),
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
|
|
193
220
|
|
|
194
221
|
|
|
195
222
|
// manifest //
|
|
@@ -219,6 +246,11 @@ const FEATURES = [
|
|
|
219
246
|
normalize: normalizeInteractionsOptions,
|
|
220
247
|
merge: mergeInteractionsOptions,
|
|
221
248
|
},
|
|
249
|
+
{
|
|
250
|
+
key: 'autocomplete',
|
|
251
|
+
normalize: normalizeAutocompleteOptions,
|
|
252
|
+
merge: mergeAutocompleteOptions,
|
|
253
|
+
},
|
|
222
254
|
];
|
|
223
255
|
|
|
224
256
|
|
|
@@ -328,18 +360,27 @@ for (const { key, normalize, merge } of FEATURES) {
|
|
|
328
360
|
});
|
|
329
361
|
}
|
|
330
362
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
363
|
+
const DEFAULT_FEATURES = ['api', 'layouts', 'dataProcessor', 'trackers', 'interactions'];
|
|
364
|
+
|
|
365
|
+
export function makeConfigurable(prototype, features = DEFAULT_FEATURES) {
|
|
366
|
+
for (const feature of features) {
|
|
367
|
+
injectConfigurableFeature(prototype, feature);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function injectConfigurableFeature(prototype, feature) {
|
|
372
|
+
if (feature === 'api') {
|
|
373
|
+
Object.assign(prototype, {
|
|
374
|
+
useApi(...args) {
|
|
375
|
+
this._options.api.merge(args);
|
|
376
|
+
return this;
|
|
377
|
+
},
|
|
378
|
+
clearApi() {
|
|
379
|
+
this._options.api.set();
|
|
380
|
+
return this;
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
} else {
|
|
343
384
|
const upperCased = upperCase(feature);
|
|
344
385
|
Object.assign(prototype, {
|
|
345
386
|
[`use${upperCased}`](value) {
|
package/src/workflow/search.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { API } from '@miso.ai/commons';
|
|
2
2
|
import Workflow from './base.js';
|
|
3
3
|
import { mergeApiOptions } from './options.js';
|
|
4
|
-
import
|
|
4
|
+
import * as sources from '../source/index.js';
|
|
5
|
+
import { fields, AutocompleteActor } from '../actor/index.js';
|
|
5
6
|
import { ROLE } from '../constants.js';
|
|
6
7
|
import { ListLayout, SearchBoxLayout } from '../layout/index.js';
|
|
8
|
+
import { makeConfigurable } from './options.js';
|
|
7
9
|
|
|
8
10
|
const DEFAULT_API_OPTIONS = Object.freeze({
|
|
9
11
|
group: API.GROUP.SEARCH,
|
|
@@ -13,6 +15,19 @@ const DEFAULT_API_OPTIONS = Object.freeze({
|
|
|
13
15
|
},
|
|
14
16
|
});
|
|
15
17
|
|
|
18
|
+
const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
|
|
19
|
+
actor: false,
|
|
20
|
+
api: {
|
|
21
|
+
group: API.GROUP.SEARCH,
|
|
22
|
+
name: API.NAME.AUTOCOMPLETE,
|
|
23
|
+
payload: {
|
|
24
|
+
completion_fields: ['suggested_queries', 'title'],
|
|
25
|
+
fl: ['title', 'url', 'cover_image'],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
throttle: 300,
|
|
29
|
+
});
|
|
30
|
+
|
|
16
31
|
const DEFAULT_LAYOUTS = Object.freeze({
|
|
17
32
|
[ROLE.QUERY]: SearchBoxLayout.type,
|
|
18
33
|
[ROLE.PRODUCTS]: ListLayout.type,
|
|
@@ -24,6 +39,7 @@ const DEFAULT_TRACKERS = Object.freeze({
|
|
|
24
39
|
|
|
25
40
|
const DEFAULT_OPTIONS = Object.freeze({
|
|
26
41
|
api: DEFAULT_API_OPTIONS,
|
|
42
|
+
autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
|
|
27
43
|
layouts: DEFAULT_LAYOUTS,
|
|
28
44
|
trackers: DEFAULT_TRACKERS,
|
|
29
45
|
});
|
|
@@ -39,6 +55,11 @@ export default class Search extends Workflow {
|
|
|
39
55
|
defaults: DEFAULT_OPTIONS,
|
|
40
56
|
});
|
|
41
57
|
|
|
58
|
+
this._autocomplete = new AutocompleteActor(this._hub, {
|
|
59
|
+
source: sources.api(this._client),
|
|
60
|
+
options: this._options,
|
|
61
|
+
});
|
|
62
|
+
|
|
42
63
|
this._unsubscribes.push(this._hub.on(fields.query(), payload => this.query(payload)));
|
|
43
64
|
}
|
|
44
65
|
|
|
@@ -66,9 +87,20 @@ export default class Search extends Workflow {
|
|
|
66
87
|
return this;
|
|
67
88
|
}
|
|
68
89
|
|
|
90
|
+
updateCompletions(event) {
|
|
91
|
+
// TODO: verify
|
|
92
|
+
this._hub.update(fields.completions(), {
|
|
93
|
+
...event,
|
|
94
|
+
source: 'manual',
|
|
95
|
+
});
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
|
|
69
99
|
notifyViewUpdate(role = ROLE.PRODUCTS, ...args) {
|
|
70
100
|
super.notifyViewUpdate(role, ...args);
|
|
71
101
|
return this;
|
|
72
102
|
}
|
|
73
103
|
|
|
74
104
|
}
|
|
105
|
+
|
|
106
|
+
makeConfigurable(Search.prototype, ['autocomplete']);
|