@miso.ai/client-sdk-ui 1.12.2 → 1.12.3-beta.1
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 +4 -16
- package/dist/cjs/constants.js +8 -3
- package/dist/cjs/defaults/ask/phrases.js +7 -3
- package/dist/cjs/defaults/ask/templates.js +19 -19
- package/dist/cjs/defaults/common/templates.js +6 -4
- package/dist/cjs/element/context/miso-follow-ups.js +45 -13
- package/dist/cjs/element/role/index.js +7 -0
- package/dist/cjs/element/role/miso-follow-up-questions.js +20 -0
- package/dist/cjs/layout/input/option-list.js +4 -5
- package/dist/cjs/layout/text/typewriter/index.js +19 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/answer-based.js +12 -7
- package/dist/cjs/workflow/ask.js +66 -5
- package/dist/cjs/workflow/asks.js +2 -1
- package/dist/cjs/workflow/base.js +19 -8
- package/dist/cjs/workflow/explore.js +2 -2
- package/dist/cjs/workflow/hybrid-search-answer.js +3 -3
- package/dist/cjs/workflow/hybrid-search-results.js +2 -2
- package/dist/cjs/workflow/processors.js +45 -1
- package/dist/cjs/workflow/search-based.js +26 -3
- package/package.json +2 -2
- package/src/actor/data.js +2 -10
- package/src/constants.js +8 -1
- package/src/defaults/ask/phrases.js +5 -2
- package/src/defaults/ask/templates.js +12 -12
- package/src/defaults/common/templates.js +6 -6
- package/src/element/context/miso-follow-ups.js +36 -11
- package/src/element/role/index.js +1 -0
- package/src/element/role/miso-follow-up-questions.js +16 -0
- package/src/layout/input/option-list.js +3 -4
- package/src/layout/text/typewriter/index.js +14 -1
- package/src/version.js +1 -1
- package/src/workflow/answer-based.js +13 -8
- package/src/workflow/ask.js +48 -5
- package/src/workflow/asks.js +2 -1
- package/src/workflow/base.js +16 -8
- package/src/workflow/explore.js +2 -2
- package/src/workflow/hybrid-search-answer.js +4 -4
- package/src/workflow/hybrid-search-results.js +2 -2
- package/src/workflow/processors.js +40 -2
- package/src/workflow/search-based.js +26 -4
|
@@ -90,7 +90,7 @@ class Workflow extends _commons.Component {
|
|
|
90
90
|
_initSubscriptions({
|
|
91
91
|
roles
|
|
92
92
|
}) {
|
|
93
|
-
this._unsubscribes = [this._hub.on(_index.fields.response(), data => this.updateData(data)), this._hub.on(_index.fields.tracker(), args => this._onTracker(args))];
|
|
93
|
+
this._unsubscribes = [this._hub.on(_index.fields.session(), session => this._onSession(session)), this._hub.on(_index.fields.response(), data => this.updateData(data)), this._hub.on(_index.fields.tracker(), args => this._onTracker(args))];
|
|
94
94
|
if (roles.main) {
|
|
95
95
|
this._unsubscribes.push(this._hub.on(_index.fields.view(roles.main), state => this._onMainViewUpdate(state)));
|
|
96
96
|
}
|
|
@@ -166,6 +166,11 @@ class Workflow extends _commons.Component {
|
|
|
166
166
|
this._emitLifecycleEvent('finally', state);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
+
_onSession(session) {
|
|
170
|
+
this.updateData({
|
|
171
|
+
session
|
|
172
|
+
});
|
|
173
|
+
}
|
|
169
174
|
_onMainViewUpdate(state) {
|
|
170
175
|
const {
|
|
171
176
|
status
|
|
@@ -202,10 +207,14 @@ class Workflow extends _commons.Component {
|
|
|
202
207
|
const {
|
|
203
208
|
session
|
|
204
209
|
} = this;
|
|
205
|
-
const
|
|
210
|
+
const request = (0, _index3.mergeApiOptions)(this._options.resolved.api, options);
|
|
211
|
+
this.updateData({
|
|
212
|
+
session,
|
|
213
|
+
request
|
|
214
|
+
});
|
|
215
|
+
this._hub.update(_index.fields.request(), Object.assign({}, request, {
|
|
206
216
|
session
|
|
207
217
|
}));
|
|
208
|
-
this._hub.update(_index.fields.request(), event);
|
|
209
218
|
}
|
|
210
219
|
|
|
211
220
|
// data //
|
|
@@ -238,13 +247,15 @@ class Workflow extends _commons.Component {
|
|
|
238
247
|
return this;
|
|
239
248
|
}
|
|
240
249
|
_updateData(data) {
|
|
241
|
-
|
|
250
|
+
const oldData = this._hub.states[_index.fields.data()];
|
|
251
|
+
data = this._defaultProcessData(data, oldData);
|
|
242
252
|
for (const process of this._options.resolved.dataProcessor) {
|
|
243
|
-
data = process(data);
|
|
253
|
+
data = process(data, oldData);
|
|
244
254
|
}
|
|
245
|
-
this._updateDataInHub(data);
|
|
255
|
+
this._updateDataInHub(data, oldData);
|
|
246
256
|
}
|
|
247
|
-
_defaultProcessData(data) {
|
|
257
|
+
_defaultProcessData(data, oldData) {
|
|
258
|
+
data = (0, _processors.writeRequestFromPreviousData)(data, oldData);
|
|
248
259
|
data = (0, _processors.writeDataStatus)(data);
|
|
249
260
|
data = (0, _processors.writeMisoIdToMeta)(data);
|
|
250
261
|
return data;
|
|
@@ -324,7 +335,7 @@ class Workflow extends _commons.Component {
|
|
|
324
335
|
|
|
325
336
|
// destroy //
|
|
326
337
|
destroy(options) {
|
|
327
|
-
this.
|
|
338
|
+
this._emit('destroy');
|
|
328
339
|
this._destroy(options);
|
|
329
340
|
}
|
|
330
341
|
_destroy({
|
|
@@ -129,8 +129,8 @@ class Explore extends _unit.default {
|
|
|
129
129
|
super.notifyViewUpdate(role, ...args);
|
|
130
130
|
return this;
|
|
131
131
|
}
|
|
132
|
-
_defaultProcessData(data) {
|
|
133
|
-
data = super._defaultProcessData(data);
|
|
132
|
+
_defaultProcessData(data, oldData) {
|
|
133
|
+
data = super._defaultProcessData(data, oldData);
|
|
134
134
|
data = this._addUrlToRelatedQuestions(data);
|
|
135
135
|
return data;
|
|
136
136
|
}
|
|
@@ -61,14 +61,14 @@ class HybridSearchAnswer extends _answerBased.default {
|
|
|
61
61
|
payload = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
62
62
|
return Object.assign({}, payload, {
|
|
63
63
|
_meta: Object.assign({}, payload._meta, {
|
|
64
|
-
question_source: qs || _constants.
|
|
64
|
+
question_source: qs || _constants.QUESTION_SOURCE.ORGANIC // might be null, not undefined
|
|
65
65
|
})
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// data //
|
|
70
|
-
_defaultProcessData(data) {
|
|
71
|
-
data = super._defaultProcessData(data);
|
|
70
|
+
_defaultProcessData(data, oldData) {
|
|
71
|
+
data = super._defaultProcessData(data, oldData);
|
|
72
72
|
data = (0, _processors.writeKeywordsToData)(data);
|
|
73
73
|
data = (0, _processors.writeMisoIdFromSession)(data);
|
|
74
74
|
data = (0, _processors.writeUnanswerableToMeta)(data);
|
|
@@ -69,8 +69,8 @@ class HybridSearchResults extends _searchBased.default {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// data //
|
|
72
|
-
_defaultProcessData(data) {
|
|
73
|
-
data = super._defaultProcessData(data);
|
|
72
|
+
_defaultProcessData(data, oldData) {
|
|
73
|
+
data = super._defaultProcessData(data, oldData);
|
|
74
74
|
(0, _processors.writeMisoIdToSession)(data);
|
|
75
75
|
return data;
|
|
76
76
|
}
|
|
@@ -7,6 +7,7 @@ exports.buildBaseInteraction = buildBaseInteraction;
|
|
|
7
7
|
exports.concatItemsFromMoreResponse = concatItemsFromMoreResponse;
|
|
8
8
|
exports.getRevision = getRevision;
|
|
9
9
|
exports.mappingAnswerData = mappingAnswerData;
|
|
10
|
+
exports.mappingFollowUpQuestionsData = mappingFollowUpQuestionsData;
|
|
10
11
|
exports.mappingReasoningData = mappingReasoningData;
|
|
11
12
|
exports.mappingSortData = mappingSortData;
|
|
12
13
|
exports.mappingSuggestionsData = mappingSuggestionsData;
|
|
@@ -18,9 +19,11 @@ exports.writeDataStatus = writeDataStatus;
|
|
|
18
19
|
exports.writeEventTargetToInteraction = writeEventTargetToInteraction;
|
|
19
20
|
exports.writeExhaustionToData = writeExhaustionToData;
|
|
20
21
|
exports.writeKeywordsToData = writeKeywordsToData;
|
|
22
|
+
exports.writeMisoIdAsRootMisoId = writeMisoIdAsRootMisoId;
|
|
21
23
|
exports.writeMisoIdFromSession = writeMisoIdFromSession;
|
|
22
24
|
exports.writeMisoIdToMeta = writeMisoIdToMeta;
|
|
23
25
|
exports.writeMisoIdToSession = writeMisoIdToSession;
|
|
26
|
+
exports.writeRequestFromPreviousData = writeRequestFromPreviousData;
|
|
24
27
|
exports.writeUnanswerableToMeta = writeUnanswerableToMeta;
|
|
25
28
|
var _commons = require("@miso.ai/commons");
|
|
26
29
|
var _constants = require("../constants.js");
|
|
@@ -99,11 +102,31 @@ function mappingSuggestionsData(_, {
|
|
|
99
102
|
text
|
|
100
103
|
}));
|
|
101
104
|
}
|
|
105
|
+
function mappingFollowUpQuestionsData(data) {
|
|
106
|
+
if (!data || !data.value) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
return (data.value.followup_questions || []).map(text => ({
|
|
110
|
+
text
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
102
113
|
|
|
103
114
|
// data //
|
|
104
115
|
function getRevision(data) {
|
|
105
116
|
return data && data.value && data.value.revision;
|
|
106
117
|
}
|
|
118
|
+
function writeRequestFromPreviousData(data, oldData) {
|
|
119
|
+
// patch request in case user call updateData() without request object in custom data scenario
|
|
120
|
+
if (!data || !data.value || data.request || !oldData || !oldData.request) {
|
|
121
|
+
return data;
|
|
122
|
+
}
|
|
123
|
+
const {
|
|
124
|
+
request
|
|
125
|
+
} = oldData;
|
|
126
|
+
return Object.assign({}, data, {
|
|
127
|
+
request
|
|
128
|
+
});
|
|
129
|
+
}
|
|
107
130
|
function writeDataStatus(data) {
|
|
108
131
|
const status = getStatus(data);
|
|
109
132
|
const ongoing = status === _constants.STATUS.READY ? data.ongoing : undefined;
|
|
@@ -250,6 +273,25 @@ function retainFacetCountsInData(data, currentFacetCounts) {
|
|
|
250
273
|
})
|
|
251
274
|
});
|
|
252
275
|
}
|
|
276
|
+
function writeMisoIdAsRootMisoId(data) {
|
|
277
|
+
const {
|
|
278
|
+
value
|
|
279
|
+
} = data;
|
|
280
|
+
if (!value) {
|
|
281
|
+
return data;
|
|
282
|
+
}
|
|
283
|
+
const {
|
|
284
|
+
miso_id
|
|
285
|
+
} = value;
|
|
286
|
+
if (!miso_id) {
|
|
287
|
+
return data;
|
|
288
|
+
}
|
|
289
|
+
return Object.assign({}, data, {
|
|
290
|
+
value: Object.assign({}, value, {
|
|
291
|
+
root_miso_id: miso_id
|
|
292
|
+
})
|
|
293
|
+
});
|
|
294
|
+
}
|
|
253
295
|
function concatItemsFromMoreResponse(oldData, newData, {
|
|
254
296
|
role = _constants.ROLE.PRODUCTS
|
|
255
297
|
} = {}) {
|
|
@@ -259,7 +301,8 @@ function concatItemsFromMoreResponse(oldData, newData, {
|
|
|
259
301
|
const {
|
|
260
302
|
[role]: oldProducts = [],
|
|
261
303
|
facet_counts,
|
|
262
|
-
total
|
|
304
|
+
total,
|
|
305
|
+
root_miso_id
|
|
263
306
|
} = oldData.value;
|
|
264
307
|
const {
|
|
265
308
|
[role]: newProducts = []
|
|
@@ -272,6 +315,7 @@ function concatItemsFromMoreResponse(oldData, newData, {
|
|
|
272
315
|
value: Object.assign({}, newData.value, {
|
|
273
316
|
facet_counts,
|
|
274
317
|
total,
|
|
318
|
+
root_miso_id,
|
|
275
319
|
[role]: [...oldProducts, ...newProducts]
|
|
276
320
|
})
|
|
277
321
|
});
|
|
@@ -215,8 +215,8 @@ class SearchBasedWorkflow extends _base.default {
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
// data //
|
|
218
|
-
_defaultProcessData(data) {
|
|
219
|
-
data = super._defaultProcessData(data);
|
|
218
|
+
_defaultProcessData(data, oldData) {
|
|
219
|
+
data = super._defaultProcessData(data, oldData);
|
|
220
220
|
data = (0, _processors.writeKeywordsToData)(data);
|
|
221
221
|
data = (0, _processors.retainFacetCountsInData)(data, this._currentFacetCounts);
|
|
222
222
|
data = (0, _processors.writeExhaustionToData)(data, {
|
|
@@ -239,7 +239,7 @@ class SearchBasedWorkflow extends _base.default {
|
|
|
239
239
|
_meta
|
|
240
240
|
} = request.payload;
|
|
241
241
|
if (!_meta || !_meta.page) {
|
|
242
|
-
return data; // not from "more" request
|
|
242
|
+
return (0, _processors.writeMisoIdAsRootMisoId)(data); // not from "more" request
|
|
243
243
|
}
|
|
244
244
|
// concat records if it's from "more" request
|
|
245
245
|
const currentData = this._hub.states[_index.fields.data()];
|
|
@@ -260,6 +260,29 @@ class SearchBasedWorkflow extends _base.default {
|
|
|
260
260
|
});
|
|
261
261
|
this._views.filters.apply();
|
|
262
262
|
}
|
|
263
|
+
|
|
264
|
+
// interactions //
|
|
265
|
+
_defaultProcessInteraction(payload, args) {
|
|
266
|
+
payload = super._defaultProcessInteraction(payload, args);
|
|
267
|
+
payload = this._writeRootMisoIdToInteraction(payload);
|
|
268
|
+
return payload;
|
|
269
|
+
}
|
|
270
|
+
_writeRootMisoIdToInteraction(payload) {
|
|
271
|
+
const data = this._hub.states[_index.fields.data()];
|
|
272
|
+
const {
|
|
273
|
+
root_miso_id
|
|
274
|
+
} = data && data.value || {};
|
|
275
|
+
if (!root_miso_id) {
|
|
276
|
+
return payload;
|
|
277
|
+
}
|
|
278
|
+
return (0, _processors.mergeInteraction)(payload, {
|
|
279
|
+
context: {
|
|
280
|
+
custom_context: {
|
|
281
|
+
root_miso_id
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
263
286
|
}
|
|
264
287
|
exports.default = SearchBasedWorkflow;
|
|
265
288
|
(0, _index3.makeConfigurable)(SearchBasedWorkflow.prototype, [_constants.WORKFLOW_CONFIGURABLE.PAGINATION, _constants.WORKFLOW_CONFIGURABLE.FILTERS]);
|
package/package.json
CHANGED
package/src/actor/data.js
CHANGED
|
@@ -38,10 +38,6 @@ export default class DataActor {
|
|
|
38
38
|
this._ac = new AbortController();
|
|
39
39
|
}
|
|
40
40
|
this._session = session;
|
|
41
|
-
|
|
42
|
-
// TODO: move this to workflow
|
|
43
|
-
// reflect session update
|
|
44
|
-
this._emitResponse({ session });
|
|
45
41
|
}
|
|
46
42
|
|
|
47
43
|
async _handleRequest(event) {
|
|
@@ -49,16 +45,12 @@ export default class DataActor {
|
|
|
49
45
|
if (!this.active) {
|
|
50
46
|
return;
|
|
51
47
|
}
|
|
52
|
-
const { session } =
|
|
53
|
-
const { session: _, ...request } = event;
|
|
54
|
-
|
|
55
|
-
// emit response to update request
|
|
56
|
-
this._emitResponse({ session, request });
|
|
48
|
+
const { session, ...request } = event;
|
|
57
49
|
|
|
58
50
|
try {
|
|
59
51
|
const { signal } = this._ac || {};
|
|
60
52
|
const options = { ...event.options, signal };
|
|
61
|
-
const response = await this._source({ session, ...
|
|
53
|
+
const response = await this._source({ session, ...request, options });
|
|
62
54
|
// takes an iterable, either sync or async
|
|
63
55
|
if (response && response[Symbol.asyncIterator]) {
|
|
64
56
|
// also emit reponse of the head request, if available
|
package/src/constants.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export const ATTR_DATA_MISO_UNIT_ID = `data-miso-unit-id`;
|
|
2
2
|
export const ATTR_DATA_MISO_PRODUCT_ID = `data-miso-product-id`;
|
|
3
3
|
export const DEFAULT_UNIT_ID = 'default';
|
|
4
|
-
export const ORGANIC_QUESTION_SOURCE = '_organic';
|
|
5
4
|
|
|
6
5
|
export const ROLE = Object.freeze({
|
|
7
6
|
CONTAINER: 'container',
|
|
@@ -19,6 +18,7 @@ export const ROLE = Object.freeze({
|
|
|
19
18
|
IMAGES: 'images',
|
|
20
19
|
SOURCES: 'sources',
|
|
21
20
|
RELATED_RESOURCES: 'related_resources',
|
|
21
|
+
FOLLOW_UP_QUESTIONS: 'follow_up_questions',
|
|
22
22
|
QUERY_SUGGESTIONS: 'query_suggestions',
|
|
23
23
|
RELATED_QUESTIONS: 'related_questions',
|
|
24
24
|
AFFILIATION: 'affiliation',
|
|
@@ -42,6 +42,7 @@ const DATA_ROLE_SET = new Set([
|
|
|
42
42
|
ROLE.IMAGES,
|
|
43
43
|
ROLE.SOURCES,
|
|
44
44
|
ROLE.RELATED_RESOURCES,
|
|
45
|
+
ROLE.FOLLOW_UP_QUESTIONS,
|
|
45
46
|
ROLE.QUERY_SUGGESTIONS,
|
|
46
47
|
ROLE.RELATED_QUESTIONS,
|
|
47
48
|
ROLE.AFFILIATION,
|
|
@@ -110,6 +111,12 @@ export const STATUS = Object.freeze({
|
|
|
110
111
|
UNANSWERABLE: 'unanswerable',
|
|
111
112
|
});
|
|
112
113
|
|
|
114
|
+
export const QUESTION_SOURCE = Object.freeze({
|
|
115
|
+
ORGANIC: '_organic',
|
|
116
|
+
SUGGESTED_QUESTIONS: '_suggested_questions',
|
|
117
|
+
INLINE_QUESTION_LINK: '_inline_question_link',
|
|
118
|
+
});
|
|
119
|
+
|
|
113
120
|
export function validateEventType(value) {
|
|
114
121
|
if (TRACKING_EVENT_TYPES.indexOf(value) < 0) {
|
|
115
122
|
throw new Error(`Unrecognized event type: ${value}`);
|
|
@@ -9,13 +9,16 @@ export const question = 'You asked...';
|
|
|
9
9
|
export const sources = 'This reply is based on the following articles';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* The phrase displayed right before <miso-
|
|
12
|
+
* The phrase displayed right before <miso-follow-up-questions>
|
|
13
13
|
*/
|
|
14
|
-
export const
|
|
14
|
+
export const followUpQuestions = 'Related questions you can explore';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The phrase displayed right before <miso-related-resources>
|
|
18
18
|
*/
|
|
19
19
|
export const relatedResources = 'Go beyond, and learn more about this topic';
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* The phrase displayed at the header of <miso-reasoning> box
|
|
23
|
+
*/
|
|
21
24
|
export const thoughts = 'Thoughts';
|
|
@@ -18,6 +18,7 @@ class Sections extends _Sections {
|
|
|
18
18
|
this.answer(options),
|
|
19
19
|
this.affiliation(options),
|
|
20
20
|
this.sources(options),
|
|
21
|
+
this.followUpQuestions(options),
|
|
21
22
|
container(options, { name: 'bottom-spacing', visibleWhen: 'ongoing' }),
|
|
22
23
|
];
|
|
23
24
|
}
|
|
@@ -76,6 +77,16 @@ class Sections extends _Sections {
|
|
|
76
77
|
]);
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
followUpQuestions(options) {
|
|
81
|
+
const { container, phrase } = this._helpers;
|
|
82
|
+
const name = 'follow-up-questions';
|
|
83
|
+
const extraNames = ['query-suggestions']; // backward compatibility (styling)
|
|
84
|
+
return container(options, { name, extraNames, visibleWhen: 'nonempty' }, [
|
|
85
|
+
phrase(options, { name, extraNames, tag: 'h3' }),
|
|
86
|
+
'<miso-follow-up-questions></miso-follow-up-questions>',
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
89
|
+
|
|
79
90
|
followUps(options) {
|
|
80
91
|
const { features = {} } = options;
|
|
81
92
|
return features.followUpQuestions === false ? '' : `<miso-follow-ups id="miso-ask-combo__follow-ups" class="miso-ask-combo__follow-ups"></miso-follow-ups>`;
|
|
@@ -91,16 +102,6 @@ class Sections extends _Sections {
|
|
|
91
102
|
return section(options, { name: 'related-resources' }, body);
|
|
92
103
|
}
|
|
93
104
|
|
|
94
|
-
querySuggestions(options) {
|
|
95
|
-
const { container, phrase } = this._helpers;
|
|
96
|
-
const { features = {} } = options;
|
|
97
|
-
return features.querySuggestions === false ? '' :
|
|
98
|
-
container(options, { name: 'query-suggestions', visibleWhen: 'initial+nonempty' }, [
|
|
99
|
-
phrase(options, { name: 'query-suggestions', tag: 'h3' }),
|
|
100
|
-
'<miso-query-suggestions></miso-query-suggestions>',
|
|
101
|
-
]);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
export const helpers = externalize(new Helpers({ ...CONSTANTS, DEFAULT_PHRASES }));
|
|
@@ -122,10 +123,9 @@ export function root(options = {}) {
|
|
|
122
123
|
|
|
123
124
|
export function followUp(options = {}) {
|
|
124
125
|
const { normalizeOptions, section, container } = helpers;
|
|
125
|
-
const {
|
|
126
|
+
const { answerGroup } = sections;
|
|
126
127
|
options = normalizeOptions(options);
|
|
127
128
|
return section(options, { name: 'follow-up' }, [
|
|
128
|
-
querySuggestions(options),
|
|
129
129
|
container(options, { name: 'query', visibleWhen: 'initial loading' }, '<miso-query></miso-query>'),
|
|
130
130
|
...answerGroup(options),
|
|
131
131
|
]);
|
|
@@ -94,17 +94,17 @@ export class Helpers {
|
|
|
94
94
|
|
|
95
95
|
normalizePhraseOptionKey(key) {
|
|
96
96
|
key = kebabOrSnakeToLowerCamel(key);
|
|
97
|
-
if (key === 'relatedQuestions') {
|
|
98
|
-
return '
|
|
97
|
+
if (key === 'relatedQuestions' || key === 'querySuggestions') {
|
|
98
|
+
return 'followUpQuestions'; // legacy key
|
|
99
99
|
}
|
|
100
100
|
return key;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
// html //
|
|
104
|
-
phrase(options, { name, tag = 'div', inline = false }) {
|
|
104
|
+
phrase(options, { name, extraNames = [], tag = 'div', inline = false }) {
|
|
105
105
|
const { classPrefix } = options;
|
|
106
106
|
const mainClass = inline ? `${classPrefix}__phrase-inline` : `${classPrefix}__phrase`;
|
|
107
|
-
return `<${tag} class="${mainClass} ${classPrefix}__${name}-phrase">${this.phraseText(options, kebabToLowerCamel(name))}</${tag}>`;
|
|
107
|
+
return `<${tag} class="${mainClass} ${[name, ...extraNames].map(name => `${classPrefix}__${name}-phrase`).join(' ')}">${this.phraseText(options, kebabToLowerCamel(name))}</${tag}>`;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
phraseText(options, key) {
|
|
@@ -126,8 +126,8 @@ export class Helpers {
|
|
|
126
126
|
}, body);
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
container({ classPrefix, circledCitationIndex, parentQuestionId }, { name, visibleWhen, trait, logo = false }, body) {
|
|
130
|
-
const classes = [`${classPrefix}__${name}-container`
|
|
129
|
+
container({ classPrefix, circledCitationIndex, parentQuestionId }, { name, extraNames = [], visibleWhen, trait, logo = false }, body) {
|
|
130
|
+
const classes = [name, ...extraNames].map(name => `${classPrefix}__${name}-container`);
|
|
131
131
|
circledCitationIndex && classes.push('miso-circled-citation-index');
|
|
132
132
|
return this.element(this._context.CONAINER_TAG, { classes, visibleWhen, trait, logo, parentQuestionId }, body);
|
|
133
133
|
}
|
|
@@ -14,6 +14,7 @@ export default class MisoFollowUpsElement extends MisoContextElement {
|
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
16
|
super();
|
|
17
|
+
this._elementToWorkflow = new WeakMap();
|
|
17
18
|
this._unsubscribes = [];
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -41,21 +42,45 @@ export default class MisoFollowUpsElement extends MisoContextElement {
|
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
// 1.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// 1. call auto-next if unset
|
|
46
|
+
if (!context._autoNextFn) {
|
|
47
|
+
context.autoNext();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 2. when a new workflow is created, insert a new section
|
|
51
|
+
this._unsubscribes.push(context.on('create', (workflow) => {
|
|
52
|
+
const { parentQuestionId } = workflow;
|
|
53
|
+
const template = workflow._options.resolved.templates.followUp;
|
|
54
|
+
if (!parentQuestionId || !template) {
|
|
48
55
|
return;
|
|
49
56
|
}
|
|
50
|
-
|
|
57
|
+
const oldChildCount = this.children.length;
|
|
58
|
+
this.insertAdjacentHTML('beforeend', template({ parentQuestionId }));
|
|
59
|
+
const newChildCount = this.children.length;
|
|
60
|
+
// keep track of the elements
|
|
61
|
+
for (const element of Array.prototype.slice.call(this.children, oldChildCount, newChildCount)) {
|
|
62
|
+
this._elementToWorkflow.set(element, workflow);
|
|
63
|
+
}
|
|
51
64
|
}));
|
|
52
65
|
|
|
53
|
-
//
|
|
54
|
-
this._unsubscribes.push(context.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
// 3. when a workflow is loading, scroll into view
|
|
67
|
+
this._unsubscribes.push(context.on('loading', ({ workflow }) => {
|
|
68
|
+
for (const element of this.children) {
|
|
69
|
+
if (this._elementToWorkflow.get(element) === workflow) {
|
|
70
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}));
|
|
75
|
+
|
|
76
|
+
// 4. when a workflow is destroyed, remove the section
|
|
77
|
+
this._unsubscribes.push(context.on('destroy', ({ workflow }) => {
|
|
78
|
+
for (const element of this.children) {
|
|
79
|
+
if (this._elementToWorkflow.get(element) === workflow) {
|
|
80
|
+
this._elementToWorkflow.delete(element);
|
|
81
|
+
element.remove();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
59
84
|
}));
|
|
60
85
|
}
|
|
61
86
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as MisoComponentElement } from './miso-component.js';
|
|
2
2
|
export { default as MisoQueryElement } from './miso-query.js';
|
|
3
|
+
export { default as MisoFollowUpQuestionsElement } from './miso-follow-up-questions.js';
|
|
3
4
|
export { default as MisoQuerySuggestionsElement } from './miso-query-suggestions.js';
|
|
4
5
|
export { default as MisoFeedbackElement } from './miso-feedback.js';
|
|
5
6
|
export { default as MisoResultsElement } from './miso-results.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoFollowUpQuestionsElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.FOLLOW_UP_QUESTIONS,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-follow-up-questions';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -116,15 +116,14 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
118
|
this._trackClick(event, binding);
|
|
119
|
-
this.
|
|
119
|
+
this._select(option.text);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
async
|
|
122
|
+
async _select(value) {
|
|
123
123
|
if (!value) {
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
this._view.hub.update(fields.query(), { q: value });
|
|
126
|
+
this._view._events.emit('select', { value });
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
destroy() {
|
|
@@ -151,8 +151,9 @@ export default class TypewriterLayout extends ProgressiveLayout {
|
|
|
151
151
|
// event //
|
|
152
152
|
_onClick(event) {
|
|
153
153
|
const { target } = event;
|
|
154
|
-
|
|
154
|
+
|
|
155
155
|
// citation link click
|
|
156
|
+
const citationLinkElement = target.closest(`[data-role="citation-link"]`);
|
|
156
157
|
if (citationLinkElement) {
|
|
157
158
|
const index = parseInt(citationLinkElement.dataset.index);
|
|
158
159
|
if (!Number.isNaN(index)) {
|
|
@@ -160,6 +161,18 @@ export default class TypewriterLayout extends ProgressiveLayout {
|
|
|
160
161
|
}
|
|
161
162
|
return;
|
|
162
163
|
}
|
|
164
|
+
|
|
165
|
+
// follow-up link click
|
|
166
|
+
const followUpLinkElement = target.closest(`[data-role="follow-up-link"]`);
|
|
167
|
+
if (followUpLinkElement) {
|
|
168
|
+
let { q } = followUpLinkElement.dataset;
|
|
169
|
+
q = q ? q.trim() : undefined;
|
|
170
|
+
if (q) {
|
|
171
|
+
this._view._events.emit('follow-up-click', { event, q });
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
163
176
|
// generic link click
|
|
164
177
|
const anchorElement = target.closest('a');
|
|
165
178
|
if (anchorElement) {
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.12.
|
|
1
|
+
export default '1.12.3-beta.1';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { API } from '@miso.ai/commons';
|
|
2
2
|
import Workflow from './base.js';
|
|
3
3
|
import { fields, FeedbackActor } from '../actor/index.js';
|
|
4
|
-
import { ROLE, STATUS,
|
|
4
|
+
import { ROLE, STATUS, QUESTION_SOURCE } from '../constants.js';
|
|
5
5
|
import { SearchBoxLayout, TextLayout, ListLayout, GalleryLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
|
|
6
6
|
import { processData as processAffiliationData } from '../affiliation/index.js';
|
|
7
7
|
import { mergeRolesOptions, autoQuery as autoQueryFn, DEFAULT_AUTO_QUERY_PARAM, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
|
|
@@ -174,7 +174,7 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
_writeQuestionSourceToSession(args) {
|
|
177
|
-
this.session.meta.question_source = args.qs ||
|
|
177
|
+
this.session.meta.question_source = args.qs || QUESTION_SOURCE.ORGANIC; // might be null, not undefined
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
_buildPayload() {
|
|
@@ -209,8 +209,8 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
209
209
|
|
|
210
210
|
_handleHeadResponse(data) {}
|
|
211
211
|
|
|
212
|
-
_defaultProcessData(data) {
|
|
213
|
-
data = super._defaultProcessData(data);
|
|
212
|
+
_defaultProcessData(data, oldData) {
|
|
213
|
+
data = super._defaultProcessData(data, oldData);
|
|
214
214
|
data = processAffiliationData(data);
|
|
215
215
|
data = writeAnswerStageToMeta(data);
|
|
216
216
|
return data;
|
|
@@ -234,12 +234,12 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
234
234
|
|
|
235
235
|
const url = new URL(window.location);
|
|
236
236
|
const currentQuestion = url.searchParams.get(param);
|
|
237
|
-
const currentQuestionSource = url.searchParams.get(sourceParam) ||
|
|
237
|
+
const currentQuestionSource = url.searchParams.get(sourceParam) || QUESTION_SOURCE.ORGANIC;
|
|
238
238
|
if (question === currentQuestion && questionSource === currentQuestionSource) {
|
|
239
239
|
return;
|
|
240
240
|
}
|
|
241
241
|
url.searchParams.set(param, question);
|
|
242
|
-
if (questionSource ===
|
|
242
|
+
if (questionSource === QUESTION_SOURCE.ORGANIC) {
|
|
243
243
|
url.searchParams.delete(sourceParam);
|
|
244
244
|
} else {
|
|
245
245
|
url.searchParams.set(sourceParam, questionSource);
|
|
@@ -294,10 +294,13 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
294
294
|
|
|
295
295
|
// handlers //
|
|
296
296
|
_onCitationClick({ index, event }) {
|
|
297
|
+
if (event.button !== 0) {
|
|
298
|
+
return; // only left click
|
|
299
|
+
}
|
|
297
300
|
if (isTracked(event)) {
|
|
298
301
|
return;
|
|
299
302
|
}
|
|
300
|
-
const { value } = this.states[fields.data()] || {};
|
|
303
|
+
const { value } = this._hub.states[fields.data()] || {};
|
|
301
304
|
const { sources } = value || {};
|
|
302
305
|
// index is 1-based
|
|
303
306
|
const source = sources && sources[index - 1];
|
|
@@ -307,11 +310,13 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
307
310
|
// TODO: should we track impression as well?
|
|
308
311
|
markAsTracked(event);
|
|
309
312
|
// distinguish from regular sources element click
|
|
310
|
-
// TODO
|
|
311
313
|
this._views.trackers.sources.click([source.product_id], { event_target: 'citation-link' });
|
|
312
314
|
}
|
|
313
315
|
|
|
314
316
|
_onAnswerLinkClick({ event, ...item }) {
|
|
317
|
+
if (event.button !== 0) {
|
|
318
|
+
return; // only left click
|
|
319
|
+
}
|
|
315
320
|
if (isTracked(event)) {
|
|
316
321
|
return;
|
|
317
322
|
}
|