@miso.ai/client-sdk-ui 1.11.4 → 1.11.5-beta.0
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/views.js +1 -0
- package/dist/cjs/asset/svgs.js +10 -4
- package/dist/cjs/constants.js +3 -2
- package/dist/cjs/element/role/index.js +7 -0
- package/dist/cjs/element/role/miso-images.js +20 -0
- package/dist/cjs/layout/input/option-list.js +1 -1
- package/dist/cjs/layout/input/select.js +1 -1
- package/dist/cjs/layout/list/carousel.js +43 -84
- package/dist/cjs/layout/list/collection.js +11 -5
- package/dist/cjs/layout/mixin/swipeable.js +165 -0
- package/dist/cjs/layout/{trackable.js → mixin/trackable.js} +4 -3
- package/dist/cjs/layout/{triggerable.js → mixin/triggerable.js} +2 -2
- package/dist/cjs/layout/radio/radio.js +11 -7
- package/dist/cjs/layout/templates.js +24 -5
- package/dist/cjs/layout/text/typewriter/index.js +2 -0
- package/dist/cjs/util/trackers.js +18 -5
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/answer-based.js +23 -4
- package/dist/cjs/workflow/search.js +0 -1
- package/package.json +2 -2
- package/src/actor/views.js +1 -0
- package/src/asset/svgs.js +9 -1
- package/src/constants.js +3 -0
- package/src/element/role/index.js +1 -0
- package/src/element/role/miso-images.js +16 -0
- package/src/layout/input/option-list.js +1 -1
- package/src/layout/input/select.js +1 -1
- package/src/layout/list/carousel.js +39 -86
- package/src/layout/list/collection.js +13 -6
- package/src/layout/mixin/swipeable.js +162 -0
- package/src/layout/{trackable.js → mixin/trackable.js} +4 -3
- package/src/layout/{triggerable.js → mixin/triggerable.js} +2 -2
- package/src/layout/radio/radio.js +7 -7
- package/src/layout/templates.js +26 -5
- package/src/layout/text/typewriter/index.js +2 -1
- package/src/util/trackers.js +17 -4
- package/src/version.js +1 -1
- package/src/workflow/answer-based.js +14 -4
- package/src/workflow/search.js +0 -1
|
@@ -50,7 +50,7 @@ export default class RadioLayout extends TemplateBasedLayout {
|
|
|
50
50
|
view.hub.on(this._field, () => this._refresh()),
|
|
51
51
|
proxyElement.on('click', (e) => this._handleClick(e)),
|
|
52
52
|
];
|
|
53
|
-
this._defaultValue ? this._select(this._defaultValue) : this._clear();
|
|
53
|
+
this._defaultValue ? this._select(this._defaultValue, { silent: true }) : this._clear({ silent: true });
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
_preprocess(states, controls) {
|
|
@@ -98,16 +98,16 @@ export default class RadioLayout extends TemplateBasedLayout {
|
|
|
98
98
|
this._state = undefined;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
_select(value) {
|
|
102
|
-
this._submit({ value });
|
|
101
|
+
_select(value, options) {
|
|
102
|
+
this._submit({ value }, options);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
_clear() {
|
|
106
|
-
this._submit({ unselected: true });
|
|
105
|
+
_clear(options) {
|
|
106
|
+
this._submit({ unselected: true }, options);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
async _submit(state) {
|
|
110
|
-
this._view.hub.update(this._field, state);
|
|
109
|
+
async _submit(state, options) {
|
|
110
|
+
this._view.hub.update(this._field, state, options);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
}
|
package/src/layout/templates.js
CHANGED
|
@@ -42,6 +42,17 @@ export function article(layout, state, data, meta) {
|
|
|
42
42
|
].join('');
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export function image(layout, state, data, meta) {
|
|
46
|
+
const { templates } = layout;
|
|
47
|
+
const [openTag, closeTag] = tagPair(layout, data);
|
|
48
|
+
return [
|
|
49
|
+
openTag,
|
|
50
|
+
(templates.imageBlock || imageBlock)(layout, data, meta),
|
|
51
|
+
(templates.infoBlock || templates.imageInfoBlock || imageInfoBlock)(layout, data, meta),
|
|
52
|
+
closeTag,
|
|
53
|
+
].join('');
|
|
54
|
+
}
|
|
55
|
+
|
|
45
56
|
export function affiliation(layout, state, data, meta) {
|
|
46
57
|
const { templates } = layout;
|
|
47
58
|
const [openTag, closeTag] = tagPair(layout, data, { link: false});
|
|
@@ -82,6 +93,13 @@ export function articleInfoBlock(layout, data, meta) {
|
|
|
82
93
|
].join('')}</div>`;
|
|
83
94
|
}
|
|
84
95
|
|
|
96
|
+
export function imageInfoBlock(layout, data, meta) {
|
|
97
|
+
const { className, templates } = layout;
|
|
98
|
+
return `<div class="${className}__item-info-container">${[
|
|
99
|
+
(templates.titleBlock || titleBlock)(layout, data, meta),
|
|
100
|
+
].join('')}</div>`;
|
|
101
|
+
}
|
|
102
|
+
|
|
85
103
|
export function titleBlock({ className }, { title }) {
|
|
86
104
|
return title ? `<div class="${className}__item-title">${escapeHtml(title)}</div>` : '';
|
|
87
105
|
}
|
|
@@ -134,13 +152,16 @@ export function discountRateText(layout, { discount_rate_percent }) {
|
|
|
134
152
|
|
|
135
153
|
export function imageBlock(layout, data, meta = {}) {
|
|
136
154
|
const { className, templates } = layout;
|
|
137
|
-
const { cover_image } = data;
|
|
138
|
-
if (!cover_image) {
|
|
155
|
+
const { cover_image, image_src, image_alt } = data;
|
|
156
|
+
if (!cover_image && !image_src) {
|
|
139
157
|
return '';
|
|
140
158
|
}
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
159
|
+
const subtype = image_src ? 'image' : 'cover-image';
|
|
160
|
+
const img = subtype === 'image' ?
|
|
161
|
+
`<img class="${className}__item-${subtype}" src="${image_src}"${image_alt ? ` alt="${image_alt}"` : ''}>` :
|
|
162
|
+
`<img class="${className}__item-${subtype}" src="${cover_image}">`;
|
|
163
|
+
const brand = subtype === 'cover-image' && meta.brand ? (templates.brandBlock || brandBlock)(layout, data, meta) : '';
|
|
164
|
+
return `<div class="${className}__item-${subtype}-container">${img}${brand}</div>`;
|
|
144
165
|
}
|
|
145
166
|
|
|
146
167
|
export function indexBlock({ className }, data, { index }) {
|
|
@@ -157,7 +157,7 @@ export default class TypewriterLayout extends ProgressiveLayout {
|
|
|
157
157
|
if (citationLinkElement) {
|
|
158
158
|
const index = parseInt(citationLinkElement.dataset.index);
|
|
159
159
|
if (!Number.isNaN(index)) {
|
|
160
|
-
this._view._events.emit('citation-click', { index });
|
|
160
|
+
this._view._events.emit('citation-click', { event, index });
|
|
161
161
|
}
|
|
162
162
|
return;
|
|
163
163
|
}
|
|
@@ -169,6 +169,7 @@ export default class TypewriterLayout extends ProgressiveLayout {
|
|
|
169
169
|
const { href, innerText, className } = anchorElement;
|
|
170
170
|
if (href) {
|
|
171
171
|
this._view._events.emit('link-click', trimObj({
|
|
172
|
+
event,
|
|
172
173
|
url: href,
|
|
173
174
|
text: innerText ? innerText.trim() : '',
|
|
174
175
|
className: className || '',
|
package/src/util/trackers.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { findInAncestors, trimObj } from '@miso.ai/commons';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const TRACKED = Symbol.for('miso:tracked');
|
|
4
|
+
|
|
5
|
+
export function isTracked(event) {
|
|
6
|
+
return !!event[TRACKED];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function markAsTracked(event) {
|
|
10
|
+
event[TRACKED] = true;
|
|
11
|
+
}
|
|
4
12
|
|
|
5
13
|
const DEFAULT_TRACKER_OPTIONS = Object.freeze({
|
|
6
14
|
impression: Object.freeze({
|
|
@@ -19,6 +27,7 @@ function mergeOptions(def, opt) {
|
|
|
19
27
|
return !!opt && { ...def, ...opt };
|
|
20
28
|
}
|
|
21
29
|
|
|
30
|
+
// TODO: don't need this anymore
|
|
22
31
|
export function normalizeTrackerOptions(options) {
|
|
23
32
|
// TODO: make this { active: false } to keep it an object
|
|
24
33
|
if (options === false) {
|
|
@@ -54,15 +63,19 @@ export function validateClick(options = {}, event) {
|
|
|
54
63
|
}
|
|
55
64
|
|
|
56
65
|
// standard criteria
|
|
57
|
-
// 1.
|
|
66
|
+
// 1. each event can only be tracked once
|
|
67
|
+
if (isTracked(event)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
// 2. it must be a left click
|
|
58
71
|
if (event.button !== 0) {
|
|
59
72
|
return false;
|
|
60
73
|
}
|
|
61
|
-
//
|
|
74
|
+
// 3. event default must not be prevented
|
|
62
75
|
if (event.defaultPrevented) {
|
|
63
76
|
return false;
|
|
64
77
|
}
|
|
65
|
-
//
|
|
78
|
+
// 4. must go through a real link
|
|
66
79
|
if (!findInAncestors(event.target, element => (element.tagName === 'A' && element.href) || undefined)) {
|
|
67
80
|
return false;
|
|
68
81
|
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.11.
|
|
1
|
+
export default '1.11.5-beta.0';
|
|
@@ -2,11 +2,12 @@ import { API } from '@miso.ai/commons';
|
|
|
2
2
|
import Workflow from './base.js';
|
|
3
3
|
import { fields, FeedbackActor } from '../actor/index.js';
|
|
4
4
|
import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
|
|
5
|
-
import { SearchBoxLayout, TextLayout, ListLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
|
|
5
|
+
import { SearchBoxLayout, TextLayout, ListLayout, CarouselLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
|
|
6
6
|
import { processData as processAffiliationData } from '../affiliation/index.js';
|
|
7
7
|
import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
|
|
8
8
|
import { writeAnswerStageToMeta, mergeInteraction } from './processors.js';
|
|
9
9
|
import { enableUseLink } from './use-link.js';
|
|
10
|
+
import { isTracked, markAsTracked } from '../util/trackers.js';
|
|
10
11
|
|
|
11
12
|
const DEFAULT_API_OPTIONS = Object.freeze({
|
|
12
13
|
...Workflow.DEFAULT_API_OPTIONS,
|
|
@@ -34,6 +35,7 @@ const DEFAULT_LAYOUTS = Object.freeze({
|
|
|
34
35
|
[ROLE.QUESTION]: [TextLayout.type, { tag: 'h2' }],
|
|
35
36
|
[ROLE.ANSWER]: TypewriterLayout.type,
|
|
36
37
|
[ROLE.FEEDBACK]: FeedbackLayout.type,
|
|
38
|
+
[ROLE.IMAGES]: [CarouselLayout.type, { incremental: true, itemType: 'image' }],
|
|
37
39
|
[ROLE.SOURCES]: [ListLayout.type, { incremental: true, itemType: 'article', templates: { ordered: true } }],
|
|
38
40
|
[ROLE.AFFILIATION]: [AffiliationLayout.type, { incremental: true, itemType: 'affiliation', link: { rel: 'noopener nofollow' } }],
|
|
39
41
|
});
|
|
@@ -46,6 +48,7 @@ const DEFAULT_TRACKERS = Object.freeze({
|
|
|
46
48
|
deduplicated: false,
|
|
47
49
|
click: DEFAULT_TRACKER_OPTIONS.click, // click only
|
|
48
50
|
},
|
|
51
|
+
[ROLE.IMAGES]: DEFAULT_TRACKER_OPTIONS,
|
|
49
52
|
[ROLE.SOURCES]: DEFAULT_TRACKER_OPTIONS,
|
|
50
53
|
[ROLE.AFFILIATION]: DEFAULT_TRACKER_OPTIONS,
|
|
51
54
|
[ROLE.PRODUCTS]: DEFAULT_TRACKER_OPTIONS,
|
|
@@ -268,7 +271,6 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
268
271
|
if (args.role !== ROLE.ANSWER) {
|
|
269
272
|
return payload;
|
|
270
273
|
}
|
|
271
|
-
console.log('writeAnswerClickInteraction', payload, args);
|
|
272
274
|
const { items = [] } = args;
|
|
273
275
|
return mergeInteraction(payload, {
|
|
274
276
|
context: {
|
|
@@ -289,7 +291,10 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
// handlers //
|
|
292
|
-
_onCitationClick({ index }) {
|
|
294
|
+
_onCitationClick({ index, event }) {
|
|
295
|
+
if (isTracked(event)) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
293
298
|
const { value } = this.states[fields.data()] || {};
|
|
294
299
|
const { sources } = value || {};
|
|
295
300
|
// index is 1-based
|
|
@@ -298,10 +303,15 @@ export default class AnswerBasedWorkflow extends Workflow {
|
|
|
298
303
|
return;
|
|
299
304
|
}
|
|
300
305
|
// TODO: should we track impression as well?
|
|
306
|
+
markAsTracked(event);
|
|
301
307
|
this._views.trackers.sources.click([source.product_id]);
|
|
302
308
|
}
|
|
303
309
|
|
|
304
|
-
_onAnswerLinkClick(item) {
|
|
310
|
+
_onAnswerLinkClick({ event, ...item }) {
|
|
311
|
+
if (isTracked(event)) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
markAsTracked(event);
|
|
305
315
|
// put everything into args and let _defaultProcessInteraction() handles it
|
|
306
316
|
// for it's hard to make it a standard item
|
|
307
317
|
this._views.trackers.answer.click([], { items: [item] });
|