@miso.ai/client-sdk-ui 1.11.0-beta.1 → 1.11.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/data.js +6 -7
- package/dist/cjs/actor/feedback.js +6 -39
- package/dist/cjs/actor/fields.js +14 -6
- package/dist/cjs/actor/hub.js +1 -2
- package/dist/cjs/actor/index.js +0 -7
- package/dist/cjs/actor/interactions.js +4 -15
- package/dist/cjs/actor/sessions.js +2 -33
- package/dist/cjs/actor/tracker.js +25 -26
- package/dist/cjs/actor/utils.js +0 -49
- package/dist/cjs/actor/view.js +40 -40
- package/dist/cjs/actor/views.js +32 -8
- package/dist/cjs/asset/svgs.js +18 -8
- package/dist/cjs/constants.js +18 -19
- package/dist/cjs/defaults/hybrid-search/answer-box.js +19 -3
- package/dist/cjs/defaults/hybrid-search/phrases.js +5 -5
- package/dist/cjs/defaults/hybrid-search/templates.js +37 -9
- package/dist/cjs/element/role/index.js +12 -5
- package/dist/cjs/element/role/{miso-hits.js → miso-more.js} +4 -4
- package/dist/cjs/element/role/miso-total.js +20 -0
- package/dist/cjs/layout/affiliation/affiliation.js +0 -3
- package/dist/cjs/layout/banner/banner.js +0 -4
- package/dist/cjs/layout/button/more-button.js +73 -0
- package/dist/cjs/layout/container/container.js +0 -3
- package/dist/cjs/layout/error/error.js +0 -4
- package/dist/cjs/layout/index.js +7 -0
- package/dist/cjs/layout/input/facets.js +5 -5
- package/dist/cjs/layout/input/option-list.js +0 -4
- package/dist/cjs/layout/input/search-box.js +33 -12
- package/dist/cjs/layout/list/cards.js +0 -3
- package/dist/cjs/layout/list/carousel.js +0 -3
- package/dist/cjs/layout/list/collection.js +25 -7
- package/dist/cjs/layout/list/list.js +0 -3
- package/dist/cjs/layout/radio/feedback.js +0 -3
- package/dist/cjs/layout/radio/radio.js +0 -4
- package/dist/cjs/layout/raf.js +4 -2
- package/dist/cjs/layout/text/text.js +0 -4
- package/dist/cjs/layout/text/typewriter/index.js +0 -3
- package/dist/cjs/layout/triggerable.js +79 -0
- package/dist/cjs/util/states.js +0 -15
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/answer-based.js +109 -111
- package/dist/cjs/workflow/ask.js +35 -27
- package/dist/cjs/workflow/asks.js +1 -1
- package/dist/cjs/workflow/autocompletable.js +33 -0
- package/dist/cjs/workflow/autocomplete.js +122 -0
- package/dist/cjs/workflow/base.js +169 -102
- package/dist/cjs/workflow/explore.js +26 -19
- package/dist/cjs/workflow/hybrid-search-answer.js +99 -0
- package/dist/cjs/workflow/hybrid-search-results.js +70 -0
- package/dist/cjs/workflow/hybrid-search-views.js +122 -0
- package/dist/cjs/workflow/hybrid-search.js +98 -103
- package/dist/cjs/workflow/options.js +32 -17
- package/dist/cjs/workflow/processors.js +185 -17
- package/dist/cjs/workflow/recommendation.js +36 -49
- package/dist/cjs/workflow/search-based.js +186 -0
- package/dist/cjs/workflow/search.js +21 -68
- package/package.json +2 -2
- package/src/actor/data.js +2 -4
- package/src/actor/feedback.js +6 -23
- package/src/actor/fields.js +14 -6
- package/src/actor/hub.js +1 -2
- package/src/actor/index.js +0 -1
- package/src/actor/interactions.js +4 -10
- package/src/actor/sessions.js +3 -30
- package/src/actor/tracker.js +25 -19
- package/src/actor/utils.js +0 -47
- package/src/actor/view.js +27 -15
- package/src/actor/views.js +36 -8
- package/src/asset/svgs.js +19 -7
- package/src/constants.js +25 -16
- package/src/defaults/hybrid-search/answer-box.js +17 -5
- package/src/defaults/hybrid-search/phrases.js +4 -4
- package/src/defaults/hybrid-search/templates.js +25 -9
- package/src/element/role/index.js +2 -1
- package/src/element/role/{miso-hits.js → miso-more.js} +3 -3
- package/src/element/role/miso-total.js +16 -0
- package/src/layout/affiliation/affiliation.js +1 -5
- package/src/layout/banner/banner.js +0 -5
- package/src/layout/button/more-button.js +69 -0
- package/src/layout/container/container.js +1 -5
- package/src/layout/error/error.js +0 -5
- package/src/layout/index.js +2 -1
- package/src/layout/input/facets.js +5 -6
- package/src/layout/input/option-list.js +0 -5
- package/src/layout/input/search-box.js +27 -14
- package/src/layout/list/cards.js +0 -4
- package/src/layout/list/carousel.js +0 -4
- package/src/layout/list/collection.js +22 -9
- package/src/layout/list/list.js +0 -4
- package/src/layout/radio/feedback.js +0 -4
- package/src/layout/radio/radio.js +0 -5
- package/src/layout/raf.js +2 -2
- package/src/layout/text/text.js +0 -5
- package/src/layout/text/typewriter/index.js +1 -5
- package/src/layout/trackable.js +1 -1
- package/src/layout/triggerable.js +76 -0
- package/src/util/states.js +0 -14
- package/src/version.js +1 -1
- package/src/workflow/answer-based.js +101 -77
- package/src/workflow/ask.js +33 -25
- package/src/workflow/asks.js +1 -1
- package/src/workflow/autocompletable.js +29 -0
- package/src/workflow/autocomplete.js +113 -0
- package/src/workflow/base.js +147 -93
- package/src/workflow/explore.js +23 -8
- package/src/workflow/hybrid-search-answer.js +92 -0
- package/src/workflow/hybrid-search-results.js +63 -0
- package/src/workflow/hybrid-search-views.js +124 -0
- package/src/workflow/hybrid-search.js +102 -73
- package/src/workflow/options.js +26 -11
- package/src/workflow/processors.js +165 -14
- package/src/workflow/recommendation.js +32 -33
- package/src/workflow/search-based.js +183 -0
- package/src/workflow/search.js +21 -65
- package/dist/cjs/actor/autocomplete.js +0 -160
- package/dist/cjs/workflow/utils.js +0 -42
- package/src/actor/autocomplete.js +0 -133
- package/src/workflow/utils.js +0 -29
|
@@ -40,9 +40,6 @@ function chevron(layout) {
|
|
|
40
40
|
return `<svg class="${className}__control-button" shape-rendering="geometricPrecision" stroke="currentColor" stroke-width="24" fill="#fff" viewBox="-30 -30 358 572"><path d="M285.77 441c16.24 16.17 16.32 42.46.15 58.7-16.16 16.24-42.45 16.32-58.69.16l-215-214.47c-16.24-16.16-16.32-42.45-.15-58.69L227.23 12.08c16.24-16.17 42.53-16.09 58.69.15 16.17 16.24 16.09 42.54-.15 58.7l-185.5 185.04L285.77 441z"/></svg>`;
|
|
41
41
|
}
|
|
42
42
|
class CarouselLayout extends _collection.default {
|
|
43
|
-
static get category() {
|
|
44
|
-
return super.category;
|
|
45
|
-
}
|
|
46
43
|
static get type() {
|
|
47
44
|
return TYPE;
|
|
48
45
|
}
|
|
@@ -7,6 +7,7 @@ exports.default = void 0;
|
|
|
7
7
|
var _constants = require("../../constants.js");
|
|
8
8
|
var _template = _interopRequireDefault(require("../template.js"));
|
|
9
9
|
var _trackable = require("../trackable.js");
|
|
10
|
+
var _triggerable = require("../triggerable.js");
|
|
10
11
|
var _templates = require("../templates.js");
|
|
11
12
|
const _excluded = ["templates", "itemType"];
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -21,7 +22,7 @@ function root(layout, state) {
|
|
|
21
22
|
status
|
|
22
23
|
} = state;
|
|
23
24
|
const roleAttr = role ? `data-role="${role}"` : '';
|
|
24
|
-
return `<div class="${className} ${status}" ${roleAttr}>${status === _constants.STATUS.READY ? templates[status](layout, state) : ''}</div>`;
|
|
25
|
+
return `<div class="${className} ${status}" ${roleAttr}>${status === _constants.STATUS.READY ? templates[status](layout, state) : ''}${templates.trigger(layout, state)}${templates.loadingBar(layout, state)}</div>`;
|
|
25
26
|
}
|
|
26
27
|
function ready(layout, state) {
|
|
27
28
|
const {
|
|
@@ -31,6 +32,7 @@ function ready(layout, state) {
|
|
|
31
32
|
|
|
32
33
|
// TODO: handle categories, attributes, etc. by introducing sublayout
|
|
33
34
|
if (values && values.length > 0 || state.ongoing) {
|
|
35
|
+
// TODO: ad-hoc ongoing?
|
|
34
36
|
return templates.list(layout, state, values);
|
|
35
37
|
} else {
|
|
36
38
|
return templates.empty(layout, state);
|
|
@@ -70,6 +72,18 @@ function item(layout, state, value, index) {
|
|
|
70
72
|
});
|
|
71
73
|
return `<li class="${className}__item">${body}</li>`;
|
|
72
74
|
}
|
|
75
|
+
function trigger(layout, state) {
|
|
76
|
+
const {
|
|
77
|
+
className
|
|
78
|
+
} = layout;
|
|
79
|
+
return `<div class="${className}__trigger" data-role="trigger"></div>`;
|
|
80
|
+
}
|
|
81
|
+
function loadingBar(layout, state) {
|
|
82
|
+
const {
|
|
83
|
+
className
|
|
84
|
+
} = layout;
|
|
85
|
+
return `<div class="${className}__loading-bar"></div>`;
|
|
86
|
+
}
|
|
73
87
|
|
|
74
88
|
// TODO: let templates.js control what to be included here
|
|
75
89
|
|
|
@@ -95,12 +109,11 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
95
109
|
ctaBlock: _templates.ctaBlock,
|
|
96
110
|
cta: _templates.cta,
|
|
97
111
|
imageBlock: _templates.imageBlock,
|
|
98
|
-
indexBlock: _templates.indexBlock
|
|
112
|
+
indexBlock: _templates.indexBlock,
|
|
113
|
+
trigger,
|
|
114
|
+
loadingBar
|
|
99
115
|
});
|
|
100
116
|
class CollectionLayout extends _template.default {
|
|
101
|
-
static get category() {
|
|
102
|
-
return _constants.LAYOUT_CATEGORY.LIST;
|
|
103
|
-
}
|
|
104
117
|
static get defaultTemplates() {
|
|
105
118
|
return DEFAULT_TEMPLATES;
|
|
106
119
|
}
|
|
@@ -115,6 +128,7 @@ class CollectionLayout extends _template.default {
|
|
|
115
128
|
itemType
|
|
116
129
|
}, options));
|
|
117
130
|
this._initTrackable();
|
|
131
|
+
this._initTriggerable();
|
|
118
132
|
}
|
|
119
133
|
initialize(view) {
|
|
120
134
|
this._unsubscribes.push(view.proxyElement.on('click', this._onClick.bind(this)));
|
|
@@ -133,7 +147,7 @@ class CollectionLayout extends _template.default {
|
|
|
133
147
|
}
|
|
134
148
|
_shallRenderIncrementally(state, rendered) {
|
|
135
149
|
// TODO: compare item ids as well
|
|
136
|
-
return this.options.incremental && rendered && rendered.value && rendered.value.length > 0 && state.
|
|
150
|
+
return this.options.incremental && rendered && rendered.value && rendered.value.length > 0 && state.value && state.value.length >= rendered.value.length && state.session && rendered.session && state.session.id === rendered.session.id;
|
|
137
151
|
}
|
|
138
152
|
_html(state, rendered, incremental) {
|
|
139
153
|
if (incremental) {
|
|
@@ -170,9 +184,11 @@ class CollectionLayout extends _template.default {
|
|
|
170
184
|
}
|
|
171
185
|
_afterRender(element, state) {
|
|
172
186
|
this._syncBindings(element, state);
|
|
187
|
+
this._syncTrigger(element, state);
|
|
173
188
|
}
|
|
174
189
|
_unrender() {
|
|
175
190
|
this._clearBindings();
|
|
191
|
+
this._untrackTrigger();
|
|
176
192
|
}
|
|
177
193
|
_getItems(state) {
|
|
178
194
|
return state.value;
|
|
@@ -212,9 +228,11 @@ class CollectionLayout extends _template.default {
|
|
|
212
228
|
}
|
|
213
229
|
destroy() {
|
|
214
230
|
this._destroyTrackable();
|
|
231
|
+
this._destroyTriggerable();
|
|
215
232
|
this._view = undefined;
|
|
216
233
|
super.destroy();
|
|
217
234
|
}
|
|
218
235
|
}
|
|
219
236
|
exports.default = CollectionLayout;
|
|
220
|
-
(0, _trackable.makeTrackable)(CollectionLayout.prototype);
|
|
237
|
+
(0, _trackable.makeTrackable)(CollectionLayout.prototype);
|
|
238
|
+
(0, _triggerable.makeTriggerable)(CollectionLayout.prototype);
|
|
@@ -11,9 +11,6 @@ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t =
|
|
|
11
11
|
const TYPE = 'list';
|
|
12
12
|
const DEFAULT_CLASSNAME = 'miso-list';
|
|
13
13
|
class ListLayout extends _collection.default {
|
|
14
|
-
static get category() {
|
|
15
|
-
return super.category;
|
|
16
|
-
}
|
|
17
14
|
static get type() {
|
|
18
15
|
return TYPE;
|
|
19
16
|
}
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _commons = require("@miso.ai/commons");
|
|
8
|
-
var _constants = require("../../constants.js");
|
|
9
8
|
var _template = _interopRequireDefault(require("../template.js"));
|
|
10
9
|
var _templates = require("../templates.js");
|
|
11
10
|
const _excluded = ["className", "templates", "field", "defaultValue"];
|
|
@@ -40,9 +39,6 @@ const DEFAULT_TEMPLATES = Object.freeze(Object.assign({}, (0, _templates.require
|
|
|
40
39
|
option
|
|
41
40
|
}));
|
|
42
41
|
class RadioLayout extends _template.default {
|
|
43
|
-
static get category() {
|
|
44
|
-
return _constants.LAYOUT_CATEGORY.RADIO;
|
|
45
|
-
}
|
|
46
42
|
static get defaultTemplates() {
|
|
47
43
|
return DEFAULT_TEMPLATES;
|
|
48
44
|
}
|
package/dist/cjs/layout/raf.js
CHANGED
|
@@ -5,19 +5,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _commons = require("@miso.ai/commons");
|
|
8
|
-
const _excluded = ["role", "workflow"];
|
|
8
|
+
const _excluded = ["role", "workflow", "workflowOptions"];
|
|
9
9
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
|
|
10
10
|
class RafLayout {
|
|
11
11
|
constructor() {
|
|
12
12
|
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
13
13
|
let {
|
|
14
14
|
role,
|
|
15
|
-
workflow
|
|
15
|
+
workflow,
|
|
16
|
+
workflowOptions
|
|
16
17
|
} = _ref,
|
|
17
18
|
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
18
19
|
(0, _commons.defineValues)(this, {
|
|
19
20
|
role,
|
|
20
21
|
workflow,
|
|
22
|
+
workflowOptions,
|
|
21
23
|
options
|
|
22
24
|
});
|
|
23
25
|
this._unsubscribes = [];
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _commons = require("@miso.ai/commons");
|
|
8
|
-
var _constants = require("../../constants.js");
|
|
9
8
|
var _template = _interopRequireDefault(require("../template.js"));
|
|
10
9
|
const _excluded = ["className", "templates", "tag"];
|
|
11
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -60,9 +59,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
60
59
|
root
|
|
61
60
|
});
|
|
62
61
|
class TextLayout extends _template.default {
|
|
63
|
-
static get category() {
|
|
64
|
-
return _constants.LAYOUT_CATEGORY.TEXT;
|
|
65
|
-
}
|
|
66
62
|
static get type() {
|
|
67
63
|
return TYPE;
|
|
68
64
|
}
|
|
@@ -15,9 +15,6 @@ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t =
|
|
|
15
15
|
const TYPE = 'typewriter';
|
|
16
16
|
const DEFAULT_CLASSNAME = 'miso-typewriter';
|
|
17
17
|
class TypewriterLayout extends _progressive.default {
|
|
18
|
-
static get category() {
|
|
19
|
-
return _constants.LAYOUT_CATEGORY.TEXT;
|
|
20
|
-
}
|
|
21
18
|
static get type() {
|
|
22
19
|
return TYPE;
|
|
23
20
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TriggerableMixin = void 0;
|
|
7
|
+
exports.makeTriggerable = makeTriggerable;
|
|
8
|
+
var _commons = require("@miso.ai/commons");
|
|
9
|
+
var _constants = require("../constants.js");
|
|
10
|
+
var _index = require("../actor/index.js");
|
|
11
|
+
function makeTriggerable(prototype) {
|
|
12
|
+
(0, _commons.mixin)(prototype, TriggerableMixin.prototype);
|
|
13
|
+
}
|
|
14
|
+
class TriggerableMixin {
|
|
15
|
+
_initTriggerable() {
|
|
16
|
+
this._trigger = undefined;
|
|
17
|
+
}
|
|
18
|
+
_syncTrigger(element, state) {
|
|
19
|
+
if (!this.options.infiniteScroll) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const workflowPaginationOptions = this.workflowOptions.pagination;
|
|
23
|
+
if (!workflowPaginationOptions.active || workflowPaginationOptions.mode !== 'infiniteScroll') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// only track trigger when ready
|
|
27
|
+
if (state.status === _constants.STATUS.READY) {
|
|
28
|
+
this._trackTrigger(element);
|
|
29
|
+
} else {
|
|
30
|
+
this._untrackTrigger();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async _trackTrigger(element) {
|
|
34
|
+
if (this._trigger) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const triggerElement = element.querySelector('[data-role="trigger"]');
|
|
38
|
+
if (!triggerElement) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const ac = new AbortController();
|
|
42
|
+
this._trigger = Object.freeze({
|
|
43
|
+
element: triggerElement,
|
|
44
|
+
ac
|
|
45
|
+
});
|
|
46
|
+
let result = false;
|
|
47
|
+
try {
|
|
48
|
+
await (0, _commons.viewable)(triggerElement, {
|
|
49
|
+
area: 1,
|
|
50
|
+
duration: 0,
|
|
51
|
+
signal: ac.signal
|
|
52
|
+
});
|
|
53
|
+
result = true;
|
|
54
|
+
} catch (e) {
|
|
55
|
+
if (e.name !== 'AbortError') {
|
|
56
|
+
throw e;
|
|
57
|
+
}
|
|
58
|
+
} finally {
|
|
59
|
+
this._trigger = undefined;
|
|
60
|
+
}
|
|
61
|
+
if (result) {
|
|
62
|
+
this._onTrigger();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
_onTrigger() {
|
|
66
|
+
this._view.hub.trigger(_index.fields.more());
|
|
67
|
+
}
|
|
68
|
+
_untrackTrigger() {
|
|
69
|
+
if (!this._trigger) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this._trigger.ac && this._trigger.ac.abort();
|
|
73
|
+
this._trigger = undefined;
|
|
74
|
+
}
|
|
75
|
+
_destroyTriggerable() {
|
|
76
|
+
this._untrackTrigger();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.TriggerableMixin = TriggerableMixin;
|
package/dist/cjs/util/states.js
CHANGED
|
@@ -15,21 +15,6 @@ const {
|
|
|
15
15
|
UNTRACKED,
|
|
16
16
|
TRIGGERED
|
|
17
17
|
} = _constants.TRACKING_STATUS;
|
|
18
|
-
|
|
19
|
-
/*
|
|
20
|
-
const STATES = {
|
|
21
|
-
NEW: Object.freeze({
|
|
22
|
-
[IMPRESSION]: UNTRACKED,
|
|
23
|
-
[VIEWABLE]: UNTRACKED,
|
|
24
|
-
}),
|
|
25
|
-
UNTRACKED: Object.freeze({
|
|
26
|
-
[IMPRESSION]: UNTRACKED,
|
|
27
|
-
[VIEWABLE]: UNTRACKED,
|
|
28
|
-
[CLICK]: UNTRACKED,
|
|
29
|
-
}),
|
|
30
|
-
};
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
18
|
const UNTRACKED_STATES = Object.freeze({
|
|
34
19
|
[IMPRESSION]: UNTRACKED,
|
|
35
20
|
[VIEWABLE]: UNTRACKED,
|
package/dist/cjs/version.js
CHANGED
|
@@ -6,24 +6,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _commons = require("@miso.ai/commons");
|
|
8
8
|
var _base = _interopRequireDefault(require("./base.js"));
|
|
9
|
-
var _options = require("./options.js");
|
|
10
9
|
var _index = require("../actor/index.js");
|
|
11
10
|
var _constants = require("../constants.js");
|
|
12
11
|
var _index2 = require("../layout/index.js");
|
|
13
12
|
var _index3 = require("../affiliation/index.js");
|
|
13
|
+
var _options = require("./options.js");
|
|
14
14
|
var _processors = require("./processors.js");
|
|
15
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const DEFAULT_API_OPTIONS = Object.freeze({
|
|
16
|
+
const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_API_OPTIONS, {
|
|
19
17
|
group: _commons.API.GROUP.ASK,
|
|
20
|
-
payload: {
|
|
18
|
+
payload: Object.assign({}, _base.default.DEFAULT_API_OPTIONS.payload, {
|
|
21
19
|
source_fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at'],
|
|
22
20
|
cite_link: 1,
|
|
23
21
|
cite_start: '[',
|
|
24
22
|
cite_end: ']'
|
|
25
|
-
}
|
|
26
|
-
});
|
|
23
|
+
})
|
|
24
|
+
}));
|
|
27
25
|
const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
|
|
28
26
|
actor: false,
|
|
29
27
|
api: {
|
|
@@ -31,7 +29,7 @@ const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
|
|
|
31
29
|
name: _commons.API.NAME.AUTOCOMPLETE
|
|
32
30
|
}
|
|
33
31
|
});
|
|
34
|
-
const DEFAULT_LAYOUTS = Object.freeze({
|
|
32
|
+
const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _base.default.DEFAULT_LAYOUTS, {
|
|
35
33
|
[_constants.ROLE.QUERY]: [_index2.SearchBoxLayout.type, {
|
|
36
34
|
placeholder: 'Ask a question'
|
|
37
35
|
}],
|
|
@@ -54,16 +52,21 @@ const DEFAULT_LAYOUTS = Object.freeze({
|
|
|
54
52
|
rel: 'noopener nofollow'
|
|
55
53
|
}
|
|
56
54
|
}]
|
|
57
|
-
});
|
|
58
|
-
const DEFAULT_TRACKERS = Object.freeze({
|
|
55
|
+
}));
|
|
56
|
+
const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _base.default.DEFAULT_TRACKERS, {
|
|
59
57
|
[_constants.ROLE.SOURCES]: {},
|
|
60
|
-
[_constants.ROLE.AFFILIATION]: {}
|
|
61
|
-
}
|
|
62
|
-
|
|
58
|
+
[_constants.ROLE.AFFILIATION]: {},
|
|
59
|
+
[_constants.ROLE.PRODUCTS]: {}
|
|
60
|
+
}));
|
|
61
|
+
const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_OPTIONS, {
|
|
63
62
|
api: DEFAULT_API_OPTIONS,
|
|
64
63
|
autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
|
|
65
64
|
layouts: DEFAULT_LAYOUTS,
|
|
66
65
|
trackers: DEFAULT_TRACKERS
|
|
66
|
+
}));
|
|
67
|
+
const ROLES_OPTIONS = (0, _options.mergeRolesOptions)(_base.default.ROLES_OPTIONS, {
|
|
68
|
+
main: _constants.ROLE.ANSWER,
|
|
69
|
+
members: Object.keys(DEFAULT_LAYOUTS)
|
|
67
70
|
});
|
|
68
71
|
class AnswerBasedWorkflow extends _base.default {
|
|
69
72
|
// constructor //
|
|
@@ -75,16 +78,19 @@ class AnswerBasedWorkflow extends _base.default {
|
|
|
75
78
|
_initActors(args) {
|
|
76
79
|
super._initActors(args);
|
|
77
80
|
this._feedback = new _index.FeedbackActor(this._hub);
|
|
78
|
-
/*
|
|
79
|
-
this._autocomplete = new AutocompleteActor(this._hub, {
|
|
80
|
-
source: sources.api(this._client),
|
|
81
|
-
options: this._options,
|
|
82
|
-
});
|
|
83
|
-
*/
|
|
84
81
|
}
|
|
85
82
|
_initSubscriptions(args) {
|
|
86
83
|
super._initSubscriptions(args);
|
|
87
|
-
this._unsubscribes = [...this._unsubscribes, this._hub.on(_index.fields.query(), args => this._query(args)), this.
|
|
84
|
+
this._unsubscribes = [...this._unsubscribes, this._hub.on(_index.fields.query(), args => this._query(args)), this._views.get(_constants.ROLE.ANSWER).on('citation-click', event => this._onCitationClick(event))];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// configuration //
|
|
88
|
+
useLink(fn) {
|
|
89
|
+
if (typeof fn !== 'function' && fn !== false) {
|
|
90
|
+
throw new Error('useLink(fn) expects fn to be a function or false');
|
|
91
|
+
}
|
|
92
|
+
this._linkFn = fn;
|
|
93
|
+
return this;
|
|
88
94
|
}
|
|
89
95
|
|
|
90
96
|
// lifecycle //
|
|
@@ -93,26 +99,29 @@ class AnswerBasedWorkflow extends _base.default {
|
|
|
93
99
|
if (this._questionId) {
|
|
94
100
|
this._questionId = undefined;
|
|
95
101
|
}
|
|
96
|
-
// interrupt event
|
|
97
|
-
// TODO: move to workflow base
|
|
98
|
-
const {
|
|
99
|
-
session,
|
|
100
|
-
status,
|
|
101
|
-
ongoing
|
|
102
|
-
} = this._hub.states[_index.fields.view(_constants.ROLE.ANSWER)] || {};
|
|
103
|
-
if (session && status !== _constants.STATUS.INITIAL && (status !== _constants.STATUS.READY || ongoing)) {
|
|
104
|
-
// it's interrupted by a new question
|
|
105
|
-
const state = Object.freeze({
|
|
106
|
-
session,
|
|
107
|
-
status,
|
|
108
|
-
ongoing
|
|
109
|
-
});
|
|
110
|
-
this._emit('interrupt', state);
|
|
111
|
-
this._emit('finally', state);
|
|
112
|
-
}
|
|
113
102
|
// restart
|
|
114
103
|
super.restart();
|
|
115
104
|
}
|
|
105
|
+
_emitInterruptEventIfNecessary() {
|
|
106
|
+
const state = this._hub.states[_index.fields.view(this._roles.main)] || {};
|
|
107
|
+
if (state.session && state.status !== _constants.STATUS.INITIAL && (state.status !== _constants.STATUS.READY || state.ongoing)) {
|
|
108
|
+
// it's interrupted by a new question
|
|
109
|
+
this._emitLifecycleEvent('interrupt', state);
|
|
110
|
+
this._emitLifecycleEvent('finally', state);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
_onMainViewUpdate(state) {
|
|
114
|
+
const {
|
|
115
|
+
status
|
|
116
|
+
} = state;
|
|
117
|
+
const done = status === _constants.STATUS.READY && !state.ongoing;
|
|
118
|
+
const erroneous = status === _constants.STATUS.ERRONEOUS;
|
|
119
|
+
const eventName = done ? 'done' : erroneous ? 'error' : status;
|
|
120
|
+
this._emitLifecycleEvent(eventName, state);
|
|
121
|
+
if (done || erroneous) {
|
|
122
|
+
this._emitLifecycleEvent('finally', state);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
116
125
|
|
|
117
126
|
// properties //
|
|
118
127
|
get questionId() {
|
|
@@ -156,55 +165,58 @@ class AnswerBasedWorkflow extends _base.default {
|
|
|
156
165
|
}
|
|
157
166
|
_query() {
|
|
158
167
|
let args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
168
|
+
if (this._linkFn) {
|
|
169
|
+
this._submit(args);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
159
172
|
// start a new session
|
|
160
173
|
this.restart();
|
|
161
174
|
|
|
162
|
-
// keep track of question source on this session
|
|
163
|
-
|
|
164
|
-
session
|
|
165
|
-
} = this;
|
|
166
|
-
session.meta.question_source = args.questionSource || _constants.ORGANIC_QUESTION_SOURCE; // might be null, not undefined
|
|
175
|
+
// keep track of question source on this session, for suggested questions interactions
|
|
176
|
+
this._writeQuestionSourceToSession(args);
|
|
167
177
|
|
|
168
178
|
// build payload and trigger request
|
|
169
179
|
const payload = this._buildPayload(args);
|
|
170
|
-
|
|
171
|
-
payload
|
|
172
|
-
session
|
|
180
|
+
this._request({
|
|
181
|
+
payload
|
|
173
182
|
});
|
|
174
|
-
this._request(event);
|
|
175
183
|
}
|
|
176
|
-
|
|
177
|
-
this.
|
|
184
|
+
_submit(args) {
|
|
185
|
+
if (!this._linkFn) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// TODO: we want a submit event, but only with linkFn
|
|
189
|
+
const url = this._linkFn(args.q);
|
|
190
|
+
window.open(url, '_blank');
|
|
191
|
+
}
|
|
192
|
+
_writeQuestionSourceToSession(args) {
|
|
193
|
+
this.session.meta.question_source = args.qs || _constants.ORGANIC_QUESTION_SOURCE; // might be null, not undefined
|
|
178
194
|
}
|
|
179
195
|
_buildPayload() {
|
|
180
196
|
throw new Error(`Not implemented`);
|
|
181
197
|
}
|
|
182
198
|
|
|
183
|
-
// autocomplete //
|
|
184
|
-
/*
|
|
185
|
-
updateCompletions(event) {
|
|
186
|
-
// TODO: verify
|
|
187
|
-
this._hub.update(fields.data(DATA_ASPECT.AUTOCOMPLETE), {
|
|
188
|
-
...event,
|
|
189
|
-
source: 'manual',
|
|
190
|
-
});
|
|
191
|
-
return this;
|
|
192
|
-
}
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
199
|
// data //
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
200
|
+
_updateData(data) {
|
|
201
|
+
// if it's the head response, write question id and return
|
|
202
|
+
if (data.value && !data.value.answer_stage) {
|
|
203
|
+
this._handleHeadResponse(data);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
super._updateData(data);
|
|
201
207
|
|
|
202
208
|
// update URL if autoQuery.updateUrl is not false
|
|
203
209
|
this._updateUrlIfNecessary(data);
|
|
204
|
-
|
|
205
|
-
|
|
210
|
+
}
|
|
211
|
+
_handleHeadResponse(data) {
|
|
212
|
+
// capture question ID and register at context
|
|
213
|
+
this._writeQuestionIdFromData(data);
|
|
214
|
+
}
|
|
215
|
+
_defaultProcessData(data) {
|
|
216
|
+
data = super._defaultProcessData(data);
|
|
206
217
|
data = (0, _index3.processData)(data);
|
|
207
|
-
|
|
218
|
+
data = (0, _processors.writeAnswerStageToMeta)(data);
|
|
219
|
+
return data;
|
|
208
220
|
}
|
|
209
221
|
_writeQuestionIdFromData(_ref) {
|
|
210
222
|
let {
|
|
@@ -241,53 +253,40 @@ class AnswerBasedWorkflow extends _base.default {
|
|
|
241
253
|
}
|
|
242
254
|
|
|
243
255
|
// interactions //
|
|
244
|
-
|
|
245
|
-
payload = super.
|
|
256
|
+
_defaultProcessInteraction(payload, args) {
|
|
257
|
+
payload = super._defaultProcessInteraction(payload, args);
|
|
258
|
+
payload = this._writeAskPropertiesToInteraction(payload, args);
|
|
259
|
+
return payload;
|
|
260
|
+
}
|
|
261
|
+
_writeAskPropertiesToInteraction() {
|
|
262
|
+
let payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
263
|
+
let args = arguments.length > 1 ? arguments[1] : undefined;
|
|
264
|
+
const question_source = this._getQuestionSourceFromViewState(args);
|
|
265
|
+
const question_id = this.questionId;
|
|
266
|
+
return (0, _processors.mergeInteraction)(payload, {
|
|
267
|
+
context: {
|
|
268
|
+
custom_context: {
|
|
269
|
+
question_source,
|
|
270
|
+
question_id
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
_getQuestionSourceFromViewState(args) {
|
|
246
276
|
const {
|
|
247
|
-
|
|
248
|
-
} =
|
|
277
|
+
request
|
|
278
|
+
} = this._hub.states[_index.fields.view(args.role)] || {};
|
|
249
279
|
const {
|
|
250
|
-
|
|
251
|
-
} =
|
|
252
|
-
|
|
253
|
-
questionId
|
|
254
|
-
} = this;
|
|
255
|
-
return Object.assign({}, payload, {
|
|
256
|
-
context: Object.assign({}, context, {
|
|
257
|
-
custom_context: (0, _commons.trimObj)(Object.assign({
|
|
258
|
-
question_id: questionId
|
|
259
|
-
}, custom_context))
|
|
260
|
-
})
|
|
261
|
-
});
|
|
280
|
+
payload
|
|
281
|
+
} = request || {};
|
|
282
|
+
return payload && payload._meta && payload._meta.question_source || undefined;
|
|
262
283
|
}
|
|
263
284
|
|
|
264
285
|
// handlers //
|
|
265
|
-
|
|
266
|
-
let {
|
|
267
|
-
session,
|
|
268
|
-
status,
|
|
269
|
-
ongoing
|
|
270
|
-
} = _ref3;
|
|
271
|
-
if (status === _constants.STATUS.INITIAL) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
const done = status === _constants.STATUS.READY && !ongoing;
|
|
275
|
-
const erroneous = status === _constants.STATUS.ERRONEOUS;
|
|
276
|
-
const eventName = done ? 'done' : erroneous ? 'error' : status;
|
|
277
|
-
const state = Object.freeze({
|
|
278
|
-
session,
|
|
279
|
-
status,
|
|
280
|
-
ongoing
|
|
281
|
-
});
|
|
282
|
-
this._emit(eventName, state);
|
|
283
|
-
if (done || erroneous) {
|
|
284
|
-
this._emit('finally', state);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
_onCitationClick(_ref4) {
|
|
286
|
+
_onCitationClick(_ref3) {
|
|
288
287
|
let {
|
|
289
288
|
index
|
|
290
|
-
} =
|
|
289
|
+
} = _ref3;
|
|
291
290
|
const {
|
|
292
291
|
value
|
|
293
292
|
} = this.states[_index.fields.data()] || {};
|
|
@@ -323,13 +322,12 @@ class AnswerBasedWorkflow extends _base.default {
|
|
|
323
322
|
super._destroy(options);
|
|
324
323
|
}
|
|
325
324
|
}
|
|
326
|
-
|
|
327
|
-
// makeConfigurable(AnswerBasedWorkflow.prototype, ['autocomplete']);
|
|
328
325
|
exports.default = AnswerBasedWorkflow;
|
|
329
326
|
Object.assign(AnswerBasedWorkflow, {
|
|
330
327
|
DEFAULT_API_OPTIONS,
|
|
331
328
|
DEFAULT_AUTOCOMPLETE_OPTIONS,
|
|
332
329
|
DEFAULT_LAYOUTS,
|
|
333
330
|
DEFAULT_TRACKERS,
|
|
334
|
-
DEFAULT_OPTIONS
|
|
331
|
+
DEFAULT_OPTIONS,
|
|
332
|
+
ROLES_OPTIONS
|
|
335
333
|
});
|