@miso.ai/client-sdk-ui 1.11.5-beta.0 → 1.11.5-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 +4 -2
- package/dist/cjs/actor/view.js +3 -2
- package/dist/cjs/asset/svgs.js +5 -2
- package/dist/cjs/constants.js +2 -1
- package/dist/cjs/defaults/hybrid-search/answer-box.js +13 -2
- package/dist/cjs/defaults/hybrid-search/controls.js +2 -1
- package/dist/cjs/defaults/hybrid-search/templates.js +9 -0
- package/dist/cjs/layout/affiliation/affiliation.js +6 -7
- package/dist/cjs/layout/container/container.js +5 -1
- package/dist/cjs/layout/index.js +7 -0
- package/dist/cjs/layout/input/option-list.js +2 -1
- package/dist/cjs/layout/input/search-box.js +2 -1
- package/dist/cjs/layout/list/carousel.js +2 -2
- package/dist/cjs/layout/list/collection.js +7 -4
- package/dist/cjs/layout/list/gallery.js +270 -0
- package/dist/cjs/layout/mixin/swipeable.js +14 -15
- package/dist/cjs/layout/raf.js +2 -0
- package/dist/cjs/layout/templates.js +19 -8
- package/dist/cjs/util/dom.js +101 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/answer-based.js +49 -77
- package/dist/cjs/workflow/ask.js +5 -3
- package/dist/cjs/workflow/base.js +4 -2
- package/dist/cjs/workflow/explore.js +17 -7
- package/dist/cjs/workflow/hybrid-search-answer.js +13 -0
- package/dist/cjs/workflow/hybrid-search-results.js +16 -0
- package/dist/cjs/workflow/hybrid-search.js +3 -8
- package/dist/cjs/workflow/options/auto-query.js +62 -0
- package/dist/cjs/workflow/options/index.js +11 -0
- package/dist/cjs/workflow/processors.js +73 -0
- package/dist/cjs/workflow/search-based.js +4 -0
- package/dist/cjs/workflow/search.js +0 -25
- package/dist/cjs/workflow/use-link.js +9 -2
- package/package.json +2 -2
- package/src/actor/data.js +4 -2
- package/src/actor/view.js +3 -2
- package/src/asset/svgs.js +5 -1
- package/src/constants.js +1 -0
- package/src/defaults/hybrid-search/answer-box.js +9 -2
- package/src/defaults/hybrid-search/controls.js +2 -2
- package/src/defaults/hybrid-search/templates.js +9 -0
- package/src/layout/affiliation/affiliation.js +5 -7
- package/src/layout/container/container.js +4 -1
- package/src/layout/index.js +1 -0
- package/src/layout/input/option-list.js +2 -1
- package/src/layout/input/search-box.js +2 -1
- package/src/layout/list/carousel.js +3 -3
- package/src/layout/list/collection.js +6 -4
- package/src/layout/list/gallery.js +229 -0
- package/src/layout/mixin/swipeable.js +12 -16
- package/src/layout/raf.js +1 -0
- package/src/layout/templates.js +15 -3
- package/src/util/dom.js +103 -0
- package/src/version.js +1 -1
- package/src/workflow/answer-based.js +42 -42
- package/src/workflow/ask.js +6 -4
- package/src/workflow/base.js +4 -2
- package/src/workflow/explore.js +15 -4
- package/src/workflow/hybrid-search-answer.js +15 -1
- package/src/workflow/hybrid-search-results.js +17 -0
- package/src/workflow/hybrid-search.js +3 -6
- package/src/workflow/options/auto-query.js +29 -0
- package/src/workflow/options/index.js +1 -0
- package/src/workflow/processors.js +60 -0
- package/src/workflow/search-based.js +5 -1
- package/src/workflow/search.js +0 -17
- package/src/workflow/use-link.js +2 -2
|
@@ -12,9 +12,13 @@ exports.retainFacetCountsInData = retainFacetCountsInData;
|
|
|
12
12
|
exports.writeAffiliationInfoToInteraction = writeAffiliationInfoToInteraction;
|
|
13
13
|
exports.writeAnswerStageToMeta = writeAnswerStageToMeta;
|
|
14
14
|
exports.writeDataStatus = writeDataStatus;
|
|
15
|
+
exports.writeEventTargetToInteraction = writeEventTargetToInteraction;
|
|
15
16
|
exports.writeExhaustionToData = writeExhaustionToData;
|
|
16
17
|
exports.writeKeywordsToData = writeKeywordsToData;
|
|
18
|
+
exports.writeMisoIdFromSession = writeMisoIdFromSession;
|
|
17
19
|
exports.writeMisoIdToMeta = writeMisoIdToMeta;
|
|
20
|
+
exports.writeMisoIdToSession = writeMisoIdToSession;
|
|
21
|
+
exports.writeUnanswerableToMeta = writeUnanswerableToMeta;
|
|
18
22
|
var _commons = require("@miso.ai/commons");
|
|
19
23
|
var _constants = require("../constants.js");
|
|
20
24
|
var _index = require("../actor/index.js");
|
|
@@ -97,6 +101,44 @@ function writeMisoIdToMeta(data) {
|
|
|
97
101
|
})
|
|
98
102
|
});
|
|
99
103
|
}
|
|
104
|
+
function writeMisoIdToSession(data) {
|
|
105
|
+
const {
|
|
106
|
+
session,
|
|
107
|
+
value
|
|
108
|
+
} = data;
|
|
109
|
+
if (!session || !value) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const {
|
|
113
|
+
miso_id
|
|
114
|
+
} = value;
|
|
115
|
+
if (!miso_id) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
session.meta.miso_id = miso_id;
|
|
119
|
+
}
|
|
120
|
+
function writeMisoIdFromSession(data) {
|
|
121
|
+
const {
|
|
122
|
+
session,
|
|
123
|
+
value
|
|
124
|
+
} = data;
|
|
125
|
+
if (!session || !value) {
|
|
126
|
+
return data;
|
|
127
|
+
}
|
|
128
|
+
const {
|
|
129
|
+
meta: {
|
|
130
|
+
miso_id
|
|
131
|
+
} = {}
|
|
132
|
+
} = session;
|
|
133
|
+
if (!miso_id) {
|
|
134
|
+
return data;
|
|
135
|
+
}
|
|
136
|
+
return Object.assign({}, data, {
|
|
137
|
+
meta: Object.assign({}, data.meta, {
|
|
138
|
+
miso_id
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
}
|
|
100
142
|
function writeKeywordsToData(data) {
|
|
101
143
|
const {
|
|
102
144
|
request,
|
|
@@ -282,6 +324,21 @@ function writeAffiliationInfoToInteraction(payload, args) {
|
|
|
282
324
|
}
|
|
283
325
|
});
|
|
284
326
|
}
|
|
327
|
+
function writeEventTargetToInteraction(payload) {
|
|
328
|
+
let {
|
|
329
|
+
event_target
|
|
330
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
331
|
+
if (!event_target) {
|
|
332
|
+
return payload;
|
|
333
|
+
}
|
|
334
|
+
return mergeInteraction(payload, {
|
|
335
|
+
context: {
|
|
336
|
+
custom_context: {
|
|
337
|
+
event_target
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
285
342
|
function mergeInteraction() {
|
|
286
343
|
let base = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
287
344
|
let patch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -290,4 +347,20 @@ function mergeInteraction() {
|
|
|
290
347
|
custom_context: (0, _commons.trimObj)(Object.assign({}, base.context && base.context.custom_context, patch.context && patch.context.custom_context))
|
|
291
348
|
}))
|
|
292
349
|
}));
|
|
350
|
+
}
|
|
351
|
+
function writeUnanswerableToMeta(data) {
|
|
352
|
+
const {
|
|
353
|
+
value
|
|
354
|
+
} = data;
|
|
355
|
+
if (!value) {
|
|
356
|
+
return data;
|
|
357
|
+
}
|
|
358
|
+
if (!value.finished || value.finish_reason !== 'success' || value.sources && value.sources.length > 0) {
|
|
359
|
+
return data;
|
|
360
|
+
}
|
|
361
|
+
return Object.assign({}, data, {
|
|
362
|
+
meta: Object.assign({}, data.meta, {
|
|
363
|
+
unanswerable: true
|
|
364
|
+
})
|
|
365
|
+
});
|
|
293
366
|
}
|
|
@@ -80,6 +80,10 @@ class SearchBasedWorkflow extends _base.default {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
// query //
|
|
83
|
+
autoQuery() {
|
|
84
|
+
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
85
|
+
_index3.autoQuery.call(this, options);
|
|
86
|
+
}
|
|
83
87
|
query(args) {
|
|
84
88
|
if (!args.q) {
|
|
85
89
|
throw new Error(`q is required in query() call`);
|
|
@@ -49,31 +49,6 @@ class Search extends _searchBased.default {
|
|
|
49
49
|
super._initProperties(args);
|
|
50
50
|
this._initAutocomplete(args);
|
|
51
51
|
}
|
|
52
|
-
autoQuery() {
|
|
53
|
-
let {
|
|
54
|
-
setValue = true,
|
|
55
|
-
focus = true,
|
|
56
|
-
param = 'q'
|
|
57
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
58
|
-
// TODO: align implementation with AnswerBasedWorkflow
|
|
59
|
-
const q = new URLSearchParams(window.location.search).get(param);
|
|
60
|
-
const {
|
|
61
|
-
layout
|
|
62
|
-
} = this._views.get(_constants.ROLE.QUERY);
|
|
63
|
-
if (layout) {
|
|
64
|
-
if (q && setValue) {
|
|
65
|
-
layout.value = q;
|
|
66
|
-
}
|
|
67
|
-
if (!q && focus) {
|
|
68
|
-
layout.focus();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (q) {
|
|
72
|
-
this.query({
|
|
73
|
-
q
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
52
|
notifyViewUpdate() {
|
|
78
53
|
let role = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _constants.ROLE.PRODUCTS;
|
|
79
54
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.UseLinkMixin = void 0;
|
|
7
7
|
exports.enableUseLink = enableUseLink;
|
|
8
8
|
var _commons = require("@miso.ai/commons");
|
|
9
|
+
const _excluded = ["q"];
|
|
10
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
9
11
|
function enableUseLink(prototype) {
|
|
10
12
|
(0, _commons.mixin)(prototype, UseLinkMixin.prototype);
|
|
11
13
|
}
|
|
@@ -34,11 +36,16 @@ class UseLinkMixin {
|
|
|
34
36
|
window.open(url, target, windowFeatures);
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
_getSubmitUrl(
|
|
39
|
+
_getSubmitUrl() {
|
|
40
|
+
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
41
|
+
let {
|
|
42
|
+
q
|
|
43
|
+
} = _ref,
|
|
44
|
+
args = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
38
45
|
if (!this._linkFn) {
|
|
39
46
|
throw new Error('useLink(fn) must be called before _getSubmitUrl()');
|
|
40
47
|
}
|
|
41
|
-
return this._linkFn[0](args
|
|
48
|
+
return this._linkFn[0](q, args);
|
|
42
49
|
}
|
|
43
50
|
}
|
|
44
51
|
exports.UseLinkMixin = UseLinkMixin;
|
package/package.json
CHANGED
package/src/actor/data.js
CHANGED
|
@@ -22,11 +22,12 @@ export default class DataActor {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
_handleSession(session) {
|
|
25
|
-
//
|
|
25
|
+
// this is mandatory in any case
|
|
26
|
+
/*
|
|
26
27
|
if (!this.active) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
*/
|
|
30
31
|
// abort ongoing data fetch if any
|
|
31
32
|
if (!this._session || (session.index !== this._session.index)) {
|
|
32
33
|
// new session, abort preview data fetch if necessary
|
|
@@ -38,6 +39,7 @@ export default class DataActor {
|
|
|
38
39
|
}
|
|
39
40
|
this._session = session;
|
|
40
41
|
|
|
42
|
+
// TODO: move this to workflow
|
|
41
43
|
// reflect session update
|
|
42
44
|
this._emitResponse({ session });
|
|
43
45
|
}
|
package/src/actor/view.js
CHANGED
|
@@ -185,13 +185,14 @@ export default class ViewActor {
|
|
|
185
185
|
}
|
|
186
186
|
// iterate over all member components' roles
|
|
187
187
|
for (const { role } of element.components) {
|
|
188
|
-
// not a data role ->
|
|
188
|
+
// not a data role -> irrelevant
|
|
189
189
|
if (!isDataRole(role)) {
|
|
190
|
-
|
|
190
|
+
continue;
|
|
191
191
|
}
|
|
192
192
|
let sliced = value && value[role];
|
|
193
193
|
if (role === ROLE.QUERY_SUGGESTIONS) {
|
|
194
194
|
// special case: query suggestions -> look up value from hub
|
|
195
|
+
// TODO: adhoc
|
|
195
196
|
const data = this.hub.states[fields.suggestions()];
|
|
196
197
|
sliced = data && data.value;
|
|
197
198
|
}
|
package/src/asset/svgs.js
CHANGED
|
@@ -15,6 +15,7 @@ const ICON_NAME = {
|
|
|
15
15
|
SEARCH: 'search',
|
|
16
16
|
TRIANGLE: 'triangle',
|
|
17
17
|
TRIANGLE_EQ: 'triangle-eq',
|
|
18
|
+
CHEVRON: 'chevron',
|
|
18
19
|
CHEVRON_NEGATIVE: 'chevron-negative',
|
|
19
20
|
};
|
|
20
21
|
|
|
@@ -27,9 +28,11 @@ const ICON_TRIANGLE = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE}" viewBox="-5
|
|
|
27
28
|
|
|
28
29
|
const ICON_TRIANGLE_EQ = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE_EQ}" viewBox="-100 -100 200 200"><path d="M12.99 -77.5A15 15,0,0,0,-12.99 -77.5L-73.61 27.5A15 15,0,0,0,-60.62 50L60.62 50A15 15,0,0,0,73.61 27.5L12.99 -77.5Z"/></symbol>`;
|
|
29
30
|
|
|
31
|
+
const ICON_CHEVRON = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON}" viewBox="-100 -100 200 200"><path d="M10.61 -43.94A15 15,0,0,0,-10.61 -43.94L-60.61 6.06A15 15,0,0,0,-39.39 27.27L0 -12.12L39.39 27.27A15 15,0,0,0,60.61 6.06L10.61 -43.94Z"/></symbol>`;
|
|
32
|
+
|
|
30
33
|
const ICON_CHEVRON_NEGATIVE = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON_NEGATIVE}" viewBox="-100 -100 200 200"><path d="M100 100V-200H-200V200H200ZM-10.61 -43.94A15 15,0,0,1,10.61 -43.94L60.61 6.06A15 15,0,0,1,39.39 27.27L0 -12.12L-39.39 27.27A15 15,0,0,1,-60.61 6.06L-10.61 -43.94Z"/></symbol>`;
|
|
31
34
|
|
|
32
|
-
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON_NEGATIVE];
|
|
35
|
+
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE];
|
|
33
36
|
|
|
34
37
|
const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
|
|
35
38
|
|
|
@@ -59,4 +62,5 @@ export const SEND = _icon(ICON_NAME.SEND);
|
|
|
59
62
|
export const SEARCH = _icon(ICON_NAME.SEARCH);
|
|
60
63
|
export const TRIANGLE = _icon(ICON_NAME.TRIANGLE);
|
|
61
64
|
export const TRIANGLE_EQ = _icon(ICON_NAME.TRIANGLE_EQ);
|
|
65
|
+
export const CHEVRON = _icon(ICON_NAME.CHEVRON);
|
|
62
66
|
export const CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
|
package/src/constants.js
CHANGED
|
@@ -9,12 +9,13 @@ const TOGGLE_BUTTON_SELECTOR = '[data-role="answer-box-toggle"]';
|
|
|
9
9
|
|
|
10
10
|
export default class AnswerBox {
|
|
11
11
|
|
|
12
|
-
constructor(client, element, { classPrefix = CLASS_PREFIX, phrases = {} } = {}) {
|
|
12
|
+
constructor(client, element, { classPrefix = CLASS_PREFIX, phrases = {}, hideWhenUnanswerable = true } = {}) {
|
|
13
13
|
this._client = client;
|
|
14
14
|
this._workflow = client.ui.hybridSearch;
|
|
15
15
|
this._element = element;
|
|
16
16
|
this._classPrefix = classPrefix;
|
|
17
17
|
this._phrases = phrases;
|
|
18
|
+
this._hideWhenUnanswerable = hideWhenUnanswerable;
|
|
18
19
|
this._init();
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -58,10 +59,16 @@ export default class AnswerBox {
|
|
|
58
59
|
|
|
59
60
|
_syncWofkflowStatus() {
|
|
60
61
|
const { status } = this._workflow._answer;
|
|
62
|
+
const { meta: { unanswerable = false } = {} } = this._workflow._answer._hub.states[fields.data()];
|
|
63
|
+
|
|
61
64
|
switch (status) {
|
|
62
65
|
case STATUS.ERRONEOUS:
|
|
63
66
|
case STATUS.READY:
|
|
64
|
-
this.
|
|
67
|
+
if (unanswerable && this._hideWhenUnanswerable) {
|
|
68
|
+
this.hide();
|
|
69
|
+
} else {
|
|
70
|
+
this.show();
|
|
71
|
+
}
|
|
65
72
|
break;
|
|
66
73
|
default:
|
|
67
74
|
this.hide();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import AnswerBox from './answer-box.js';
|
|
2
2
|
|
|
3
|
-
export function wireAnswerBox(client, element) {
|
|
3
|
+
export function wireAnswerBox(client, element, options = {}) {
|
|
4
4
|
if (!client) {
|
|
5
5
|
throw new Error('client is required');
|
|
6
6
|
}
|
|
7
7
|
if (!element) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
|
-
new AnswerBox(client, element);
|
|
10
|
+
new AnswerBox(client, element, options);
|
|
11
11
|
}
|
|
@@ -9,6 +9,15 @@ class Sections extends _Sections {
|
|
|
9
9
|
super({ helpers });
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
answer(options) {
|
|
13
|
+
const { container } = this._helpers;
|
|
14
|
+
return container(options, { name: 'answer', visibleWhen: 'ready !unanswerable' }, [
|
|
15
|
+
...this.question(options),
|
|
16
|
+
'<miso-answer></miso-answer>',
|
|
17
|
+
'<miso-feedback></miso-feedback>',
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
|
|
12
21
|
answerBox(options) {
|
|
13
22
|
const { element } = this._helpers;
|
|
14
23
|
const { classPrefix } = options;
|
|
@@ -3,12 +3,13 @@ import { STATUS } from '../../constants.js';
|
|
|
3
3
|
import CollectionLayout from '../list/collection.js';
|
|
4
4
|
import { affiliation, helpers } from '../templates.js';
|
|
5
5
|
import { TRIANGLE } from '../../asset/svgs.js';
|
|
6
|
+
import { setOrRemoveAttribute } from '../../util/dom.js';
|
|
6
7
|
|
|
7
8
|
const TYPE = 'affiliation';
|
|
8
9
|
const DEFAULT_CLASSNAME = 'miso-affiliation';
|
|
9
10
|
|
|
10
11
|
function root(layout, state) {
|
|
11
|
-
const { className, role, templates } = layout;
|
|
12
|
+
const { className, role, templates, options } = layout;
|
|
12
13
|
const { status } = state;
|
|
13
14
|
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
14
15
|
const data = state.value || {};
|
|
@@ -16,7 +17,8 @@ function root(layout, state) {
|
|
|
16
17
|
const items = layout._getItems(state);
|
|
17
18
|
const itemCount = items ? items.length : undefined;
|
|
18
19
|
const itemCountAttr = itemCount !== undefined ? ` data-item-count="${itemCount}"` : '';
|
|
19
|
-
|
|
20
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : '';
|
|
21
|
+
return `<div class="${className} ${status}"${roleAttr}${channelAttr}${itemTypeAttr}${itemCountAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}</div>`;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
function ready(layout, state) {
|
|
@@ -256,12 +258,8 @@ export default class AffiliationLayout extends CollectionLayout {
|
|
|
256
258
|
if (!element) {
|
|
257
259
|
return;
|
|
258
260
|
}
|
|
261
|
+
setOrRemoveAttribute(element, 'data-item-count', itemCount);
|
|
259
262
|
this._displayedCount = itemCount;
|
|
260
|
-
if (itemCount === undefined) {
|
|
261
|
-
element.removeAttribute('data-item-count');
|
|
262
|
-
} else {
|
|
263
|
-
element.setAttribute('data-item-count', itemCount);
|
|
264
|
-
}
|
|
265
263
|
}
|
|
266
264
|
|
|
267
265
|
_syncItemIndex() {
|
|
@@ -60,11 +60,14 @@ export default class ContainerLayout extends RafLayout {
|
|
|
60
60
|
if (!element) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
|
-
const { status, ongoing, meta: { miso_id, empty = false } = {} } = state;
|
|
63
|
+
const { status, ongoing, meta: { miso_id, empty = false, unanswerable = false } = {} } = state;
|
|
64
64
|
const statuses = [status, empty ? STATUS.EMPTY : STATUS.NONEMPTY];
|
|
65
65
|
if (status === STATUS.READY) {
|
|
66
66
|
statuses.push(ongoing ? STATUS.ONGOING : STATUS.DONE);
|
|
67
67
|
}
|
|
68
|
+
if (unanswerable) {
|
|
69
|
+
statuses.push(STATUS.UNANSWERABLE);
|
|
70
|
+
}
|
|
68
71
|
element.setAttribute('status', statuses.join(' '));
|
|
69
72
|
if (miso_id) {
|
|
70
73
|
element.setAttribute('miso-id', miso_id);
|
package/src/layout/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { default as CollectionLayout } from './list/collection.js';
|
|
|
6
6
|
export { default as ListLayout } from './list/list.js';
|
|
7
7
|
export { default as CardsLayout } from './list/cards.js';
|
|
8
8
|
export { default as CarouselLayout } from './list/carousel.js';
|
|
9
|
+
export { default as GalleryLayout } from './list/gallery.js';
|
|
9
10
|
export { default as SearchBoxLayout } from './input/search-box.js';
|
|
10
11
|
export { default as OptionListLayout } from './input/option-list.js';
|
|
11
12
|
export { default as FeedbackLayout } from './radio/feedback.js';
|
|
@@ -2,6 +2,7 @@ import { escapeHtml } from '@miso.ai/commons';
|
|
|
2
2
|
import { fields } from '../../actor/index.js';
|
|
3
3
|
import TemplateBasedLayout from '../template.js';
|
|
4
4
|
import { makeTrackable } from '../mixin/trackable.js';
|
|
5
|
+
import { addOrRemoveClass } from '../../util/dom.js';
|
|
5
6
|
|
|
6
7
|
const TYPE = 'option-list';
|
|
7
8
|
const DEFAULT_CLASSNAME = 'miso-option-list';
|
|
@@ -96,7 +97,7 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
99
|
const optionValues = this._getItems(state) || [];
|
|
99
|
-
optionsElement
|
|
100
|
+
addOrRemoveClass(optionsElement, 'empty', optionValues.length === 0);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
_getItems(state) {
|
|
@@ -4,6 +4,7 @@ import { fields } from '../../actor/index.js';
|
|
|
4
4
|
import TemplateBasedLayout from '../template.js';
|
|
5
5
|
import { imageBlock, productInfoBlock } from '../templates.js';
|
|
6
6
|
import { getIcon } from '../../asset/svgs.js';
|
|
7
|
+
import { addOrRemoveClass } from '../../util/dom.js';
|
|
7
8
|
|
|
8
9
|
const TYPE = 'search-box';
|
|
9
10
|
const DEFAULT_CLASSNAME = 'miso-search-box';
|
|
@@ -215,7 +216,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
215
216
|
|
|
216
217
|
const items = context.trackItems(completions);
|
|
217
218
|
|
|
218
|
-
element
|
|
219
|
+
addOrRemoveClass(element, 'nonempty', items.length > 0);
|
|
219
220
|
autocompleteElement.setAttribute('data-status', status);
|
|
220
221
|
autocompleteElement.innerHTML = this.templates.completions(this, items);
|
|
221
222
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import CollectionLayout from './collection.js';
|
|
2
2
|
import { makeSwipeable } from '../mixin/swipeable.js';
|
|
3
|
-
import { CHEVRON_NEGATIVE } from '../../asset/svgs.js';
|
|
3
|
+
import { CHEVRON, CHEVRON_NEGATIVE } from '../../asset/svgs.js';
|
|
4
4
|
|
|
5
5
|
const TYPE = 'carousel';
|
|
6
6
|
const DEFAULT_CLASSNAME = 'miso-carousel';
|
|
@@ -41,8 +41,8 @@ function control(layout, state, direction) {
|
|
|
41
41
|
return `<div class="${className}__control-${direction}" data-role="${direction}">${templates.controlIcon(layout, state, direction)}</div>`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function controlIcon(layout
|
|
45
|
-
return CHEVRON_NEGATIVE;
|
|
44
|
+
function controlIcon(layout) {
|
|
45
|
+
return layout.options.itemType === 'image' ? CHEVRON_NEGATIVE : CHEVRON;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function indexIndicator(layout, state, values) {
|
|
@@ -5,10 +5,11 @@ import { makeTriggerable } from '../mixin/triggerable.js';
|
|
|
5
5
|
import { product, article, image, question, productInfoBlock, articleInfoBlock, imageInfoBlock, titleBlock, brandBlock, descriptionBlock, dateBlock, priceBlock, discountRateText, ctaBlock, cta, imageBlock, indexBlock } from '../templates.js';
|
|
6
6
|
|
|
7
7
|
function root(layout, state) {
|
|
8
|
-
const { className, role, templates } = layout;
|
|
8
|
+
const { className, role, templates, options } = layout;
|
|
9
9
|
const { status } = state;
|
|
10
|
-
const roleAttr = role ? `data-role="${role}"` : '';
|
|
11
|
-
|
|
10
|
+
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
11
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : '';
|
|
12
|
+
return `<div class="${className} ${status}"${roleAttr}${itemTypeAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}${templates.trigger(layout, state)}${templates.loading(layout, state)}</div>`;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
function ready(layout, state) {
|
|
@@ -30,8 +31,9 @@ function body(layout, state, values) {
|
|
|
30
31
|
function list(layout, state, values) {
|
|
31
32
|
const { className, templates, options } = layout;
|
|
32
33
|
const listTag = templates.ordered ? 'ol' : 'ul';
|
|
34
|
+
const itemTypeAttr = options.itemType ? ` data-item-type="${options.itemType}"` : ''; // backward compatible
|
|
33
35
|
// TODO: support separator?
|
|
34
|
-
return `<${listTag} class="${className}__list" data-role="list"
|
|
36
|
+
return `<${listTag} class="${className}__list" data-role="list"${itemTypeAttr}>${templates.items(layout, state, values)}</${listTag}>`;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
function items(layout, state, values, { offset = 0 } = {}) {
|