@miso.ai/client-sdk-ui 1.13.2-beta.1 → 1.14.0-beta.2

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.
Files changed (214) hide show
  1. package/dist/cjs/asset/svgs.js +15 -4
  2. package/dist/cjs/combo/ask/index.js +2 -2
  3. package/dist/cjs/constants.js +118 -98
  4. package/dist/cjs/defaults/ask/controls.js +1 -1
  5. package/dist/cjs/defaults/hybrid-search/answer-box.js +4 -4
  6. package/dist/cjs/defaults.js +169 -0
  7. package/dist/cjs/element/container/index.js +14 -0
  8. package/dist/cjs/element/container/miso-ask.js +3 -3
  9. package/dist/cjs/element/container/miso-conversation.js +21 -0
  10. package/dist/cjs/element/container/miso-explore.js +1 -1
  11. package/dist/cjs/element/container/miso-history.js +21 -0
  12. package/dist/cjs/element/container/miso-hybrid-search.js +1 -1
  13. package/dist/cjs/element/container/miso-recommendation.js +1 -1
  14. package/dist/cjs/element/container/miso-search.js +1 -1
  15. package/dist/cjs/element/context/miso-follow-ups.js +1 -1
  16. package/dist/cjs/element/role/index.js +42 -0
  17. package/dist/cjs/element/role/miso-messages.js +20 -0
  18. package/dist/cjs/element/role/miso-new-thread.js +20 -0
  19. package/dist/cjs/element/role/miso-rename.js +20 -0
  20. package/dist/cjs/element/role/miso-subscription.js +20 -0
  21. package/dist/cjs/element/role/miso-threads.js +20 -0
  22. package/dist/cjs/element/role/miso-title.js +20 -0
  23. package/dist/cjs/layout/affiliation/affiliation.js +1 -1
  24. package/dist/cjs/layout/banner/banner.js +2 -1
  25. package/dist/cjs/layout/button/button.js +130 -0
  26. package/dist/cjs/layout/button/checkbox.js +115 -0
  27. package/dist/cjs/layout/button/more-button.js +3 -3
  28. package/dist/cjs/layout/container/container.js +1 -1
  29. package/dist/cjs/layout/error/error.js +2 -1
  30. package/dist/cjs/layout/index.js +28 -0
  31. package/dist/cjs/layout/input/facets.js +4 -3
  32. package/dist/cjs/layout/input/option-list.js +3 -2
  33. package/dist/cjs/layout/input/search-box.js +42 -9
  34. package/dist/cjs/layout/input/select.js +2 -1
  35. package/dist/cjs/layout/list/cards.js +2 -1
  36. package/dist/cjs/layout/list/carousel.js +2 -1
  37. package/dist/cjs/layout/list/collection.js +5 -0
  38. package/dist/cjs/layout/list/gallery.js +2 -1
  39. package/dist/cjs/layout/list/horizontal.js +2 -1
  40. package/dist/cjs/layout/list/list.js +2 -1
  41. package/dist/cjs/layout/list/messages.js +346 -0
  42. package/dist/cjs/layout/list/threads.js +257 -0
  43. package/dist/cjs/layout/mixin/trackable.js +4 -5
  44. package/dist/cjs/layout/mixin/triggerable.js +2 -2
  45. package/dist/cjs/layout/radio/feedback.js +4 -3
  46. package/dist/cjs/layout/templates.js +70 -0
  47. package/dist/cjs/layout/text/text.js +2 -1
  48. package/dist/cjs/layout/text/typewriter/index.js +4 -2
  49. package/dist/cjs/plugin.js +43 -104
  50. package/dist/cjs/util/confirm.js +33 -0
  51. package/dist/cjs/util/modal.js +48 -0
  52. package/dist/cjs/util/prompt.js +47 -0
  53. package/dist/cjs/version.js +1 -1
  54. package/package.json +5 -4
  55. package/src/CLAUDE.md +48 -105
  56. package/src/asset/svgs.js +14 -3
  57. package/src/combo/ask/index.js +2 -2
  58. package/src/constants.js +37 -147
  59. package/src/defaults/ask/controls.js +1 -1
  60. package/src/defaults/hybrid-search/answer-box.js +2 -2
  61. package/src/defaults.js +107 -0
  62. package/src/element/container/index.js +2 -0
  63. package/src/element/container/miso-ask.js +3 -3
  64. package/src/element/container/miso-conversation.js +19 -0
  65. package/src/element/container/miso-explore.js +1 -1
  66. package/src/element/container/miso-history.js +19 -0
  67. package/src/element/container/miso-hybrid-search.js +1 -1
  68. package/src/element/container/miso-recommendation.js +1 -1
  69. package/src/element/container/miso-search.js +1 -1
  70. package/src/element/context/miso-follow-ups.js +1 -1
  71. package/src/element/role/index.js +6 -0
  72. package/src/element/role/miso-messages.js +16 -0
  73. package/src/element/role/miso-new-thread.js +16 -0
  74. package/src/element/role/miso-rename.js +16 -0
  75. package/src/element/role/miso-subscription.js +16 -0
  76. package/src/element/role/miso-threads.js +16 -0
  77. package/src/element/role/miso-title.js +16 -0
  78. package/src/layout/affiliation/affiliation.js +2 -2
  79. package/src/layout/banner/banner.js +2 -1
  80. package/src/layout/button/button.js +116 -0
  81. package/src/layout/button/checkbox.js +91 -0
  82. package/src/layout/button/more-button.js +3 -3
  83. package/src/layout/container/container.js +2 -2
  84. package/src/layout/error/error.js +2 -1
  85. package/src/layout/index.js +4 -0
  86. package/src/layout/input/facets.js +3 -2
  87. package/src/layout/input/option-list.js +3 -2
  88. package/src/layout/input/search-box.js +41 -6
  89. package/src/layout/input/select.js +2 -1
  90. package/src/layout/list/cards.js +2 -1
  91. package/src/layout/list/carousel.js +2 -1
  92. package/src/layout/list/collection.js +6 -1
  93. package/src/layout/list/gallery.js +2 -1
  94. package/src/layout/list/horizontal.js +2 -1
  95. package/src/layout/list/list.js +2 -1
  96. package/src/layout/list/messages.js +318 -0
  97. package/src/layout/list/threads.js +206 -0
  98. package/src/layout/mixin/trackable.js +2 -3
  99. package/src/layout/mixin/triggerable.js +1 -1
  100. package/src/layout/radio/feedback.js +3 -2
  101. package/src/layout/templates.js +62 -0
  102. package/src/layout/text/text.js +2 -1
  103. package/src/layout/text/typewriter/index.js +5 -3
  104. package/src/plugin.js +31 -117
  105. package/src/util/confirm.js +28 -0
  106. package/src/util/modal.js +49 -0
  107. package/src/util/prompt.js +42 -0
  108. package/src/version.js +1 -1
  109. package/dist/cjs/actor/data.js +0 -132
  110. package/dist/cjs/actor/feedback.js +0 -29
  111. package/dist/cjs/actor/fields.js +0 -57
  112. package/dist/cjs/actor/filters.js +0 -161
  113. package/dist/cjs/actor/hub.js +0 -57
  114. package/dist/cjs/actor/index.js +0 -73
  115. package/dist/cjs/actor/interactions.js +0 -36
  116. package/dist/cjs/actor/sessions.js +0 -25
  117. package/dist/cjs/actor/tracker-states.js +0 -61
  118. package/dist/cjs/actor/tracker.js +0 -109
  119. package/dist/cjs/actor/trackers.js +0 -52
  120. package/dist/cjs/actor/utils.js +0 -15
  121. package/dist/cjs/actor/view.js +0 -294
  122. package/dist/cjs/actor/views.js +0 -209
  123. package/dist/cjs/source.js +0 -27
  124. package/dist/cjs/util/proxy.js +0 -88
  125. package/dist/cjs/util/trackers.js +0 -88
  126. package/dist/cjs/workflow/affiliations.js +0 -140
  127. package/dist/cjs/workflow/answer-based.js +0 -337
  128. package/dist/cjs/workflow/ask.js +0 -319
  129. package/dist/cjs/workflow/asks.js +0 -150
  130. package/dist/cjs/workflow/autocompletable.js +0 -63
  131. package/dist/cjs/workflow/autocomplete.js +0 -120
  132. package/dist/cjs/workflow/base.js +0 -418
  133. package/dist/cjs/workflow/context.js +0 -19
  134. package/dist/cjs/workflow/explore.js +0 -210
  135. package/dist/cjs/workflow/explores.js +0 -21
  136. package/dist/cjs/workflow/hybrid-search-answer.js +0 -88
  137. package/dist/cjs/workflow/hybrid-search-views.js +0 -109
  138. package/dist/cjs/workflow/hybrid-search.js +0 -213
  139. package/dist/cjs/workflow/index.js +0 -41
  140. package/dist/cjs/workflow/options/api.js +0 -41
  141. package/dist/cjs/workflow/options/auto-query.js +0 -97
  142. package/dist/cjs/workflow/options/configurable.js +0 -45
  143. package/dist/cjs/workflow/options/data-processor.js +0 -20
  144. package/dist/cjs/workflow/options/filters.js +0 -15
  145. package/dist/cjs/workflow/options/index.js +0 -126
  146. package/dist/cjs/workflow/options/interactions.js +0 -41
  147. package/dist/cjs/workflow/options/layouts.js +0 -79
  148. package/dist/cjs/workflow/options/options.js +0 -156
  149. package/dist/cjs/workflow/options/pagination.js +0 -25
  150. package/dist/cjs/workflow/options/roles.js +0 -15
  151. package/dist/cjs/workflow/options/templates.js +0 -30
  152. package/dist/cjs/workflow/options/trackers.js +0 -83
  153. package/dist/cjs/workflow/options/utils.js +0 -33
  154. package/dist/cjs/workflow/processors.js +0 -607
  155. package/dist/cjs/workflow/recommendation.js +0 -57
  156. package/dist/cjs/workflow/recommendations.js +0 -18
  157. package/dist/cjs/workflow/search-based.js +0 -337
  158. package/dist/cjs/workflow/search.js +0 -64
  159. package/dist/cjs/workflow/unit.js +0 -57
  160. package/dist/cjs/workflow/units.js +0 -42
  161. package/dist/cjs/workflow/use-link.js +0 -49
  162. package/src/actor/data.js +0 -106
  163. package/src/actor/feedback.js +0 -28
  164. package/src/actor/fields.js +0 -51
  165. package/src/actor/filters.js +0 -149
  166. package/src/actor/hub.js +0 -47
  167. package/src/actor/index.js +0 -10
  168. package/src/actor/interactions.js +0 -32
  169. package/src/actor/sessions.js +0 -21
  170. package/src/actor/tracker-states.js +0 -57
  171. package/src/actor/tracker.js +0 -104
  172. package/src/actor/trackers.js +0 -45
  173. package/src/actor/utils.js +0 -7
  174. package/src/actor/view.js +0 -272
  175. package/src/actor/views.js +0 -224
  176. package/src/source.js +0 -17
  177. package/src/util/proxy.js +0 -81
  178. package/src/util/trackers.js +0 -84
  179. package/src/workflow/affiliations.js +0 -121
  180. package/src/workflow/answer-based.js +0 -312
  181. package/src/workflow/ask.js +0 -284
  182. package/src/workflow/asks.js +0 -143
  183. package/src/workflow/autocompletable.js +0 -67
  184. package/src/workflow/autocomplete.js +0 -114
  185. package/src/workflow/base.js +0 -396
  186. package/src/workflow/context.js +0 -16
  187. package/src/workflow/explore.js +0 -194
  188. package/src/workflow/explores.js +0 -18
  189. package/src/workflow/hybrid-search-answer.js +0 -73
  190. package/src/workflow/hybrid-search-views.js +0 -116
  191. package/src/workflow/hybrid-search.js +0 -230
  192. package/src/workflow/index.js +0 -5
  193. package/src/workflow/options/api.js +0 -31
  194. package/src/workflow/options/auto-query.js +0 -70
  195. package/src/workflow/options/configurable.js +0 -48
  196. package/src/workflow/options/data-processor.js +0 -15
  197. package/src/workflow/options/filters.js +0 -10
  198. package/src/workflow/options/index.js +0 -11
  199. package/src/workflow/options/interactions.js +0 -36
  200. package/src/workflow/options/layouts.js +0 -73
  201. package/src/workflow/options/options.js +0 -175
  202. package/src/workflow/options/pagination.js +0 -18
  203. package/src/workflow/options/roles.js +0 -12
  204. package/src/workflow/options/templates.js +0 -27
  205. package/src/workflow/options/trackers.js +0 -80
  206. package/src/workflow/options/utils.js +0 -26
  207. package/src/workflow/processors.js +0 -490
  208. package/src/workflow/recommendation.js +0 -63
  209. package/src/workflow/recommendations.js +0 -14
  210. package/src/workflow/search-based.js +0 -329
  211. package/src/workflow/search.js +0 -73
  212. package/src/workflow/unit.js +0 -51
  213. package/src/workflow/units.js +0 -43
  214. package/src/workflow/use-link.js +0 -41
@@ -1,16 +0,0 @@
1
- import { Component } from '@miso.ai/commons';
2
- import { WorkflowContextOptions, makeConfigurable } from './options/index.js';
3
-
4
- export default class WorkflowContext extends Component {
5
-
6
- constructor(name, plugin, client) {
7
- super(name, plugin);
8
- this._name = name;
9
- this._plugin = plugin;
10
- this._client = client;
11
- this._options = new WorkflowContextOptions();
12
- }
13
-
14
- }
15
-
16
- makeConfigurable(WorkflowContext.prototype);
@@ -1,194 +0,0 @@
1
- import { API } from '@miso.ai/commons';
2
- import UnitWorkflow from './unit.js';
3
- import { fields } from '../actor/index.js';
4
- import { ROLE, EVENT_TYPE } from '../constants.js';
5
- import { ListLayout, SearchBoxLayout } from '../layout/index.js';
6
- import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
7
- import { enableUseLink, UseLinkMixin } from './use-link.js';
8
- import { makeAutocompletable } from './autocompletable.js';
9
-
10
- const DEFAULT_API_OPTIONS = Object.freeze({
11
- ...UnitWorkflow.DEFAULT_API_OPTIONS,
12
- group: API.GROUP.ASK,
13
- name: API.NAME.RELATED_QUESTIONS,
14
- });
15
-
16
- const DEFAULT_LAYOUTS = Object.freeze({
17
- ...UnitWorkflow.DEFAULT_LAYOUTS,
18
- [ROLE.RELATED_QUESTIONS]: [ListLayout.type, { itemType: 'question', link: { rel: 'noopener nofollow' } }], // TODO: should define by useLink()
19
- [ROLE.QUERY]: [SearchBoxLayout.type, { placeholder: 'Ask a question' }],
20
- });
21
-
22
- const DEFAULT_TRACKERS = Object.freeze({
23
- ...UnitWorkflow.DEFAULT_TRACKERS,
24
- [ROLE.RELATED_QUESTIONS]: DEFAULT_TRACKER_OPTIONS,
25
- [ROLE.CONTAINER]: {
26
- ...DEFAULT_TRACKER_OPTIONS,
27
- itemless: true,
28
- },
29
- [ROLE.QUERY]: {
30
- [EVENT_TYPE.SUBMIT]: {
31
- active: true,
32
- },
33
- },
34
- });
35
-
36
- const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
37
- api: {
38
- group: API.GROUP.ASK,
39
- name: API.NAME.QUERY_SUGGESTION,
40
- },
41
- });
42
-
43
- const DEFAULT_OPTIONS = Object.freeze({
44
- ...UnitWorkflow.DEFAULT_OPTIONS,
45
- api: DEFAULT_API_OPTIONS,
46
- layouts: DEFAULT_LAYOUTS,
47
- trackers: DEFAULT_TRACKERS,
48
- autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
49
- });
50
-
51
- const ROLES_OPTIONS = mergeRolesOptions(UnitWorkflow.ROLES_OPTIONS, {
52
- main: ROLE.RELATED_QUESTIONS,
53
- members: Object.keys(DEFAULT_LAYOUTS),
54
- });
55
-
56
- export default class Explore extends UnitWorkflow {
57
-
58
- constructor(context, id) {
59
- super({
60
- name: 'explore',
61
- context,
62
- roles: ROLES_OPTIONS,
63
- defaults: DEFAULT_OPTIONS,
64
- id,
65
- });
66
- }
67
-
68
- _initProperties(args) {
69
- super._initProperties(args);
70
- this._initAutocomplete(args);
71
- this._productId = undefined;
72
- this._linkFn = undefined;
73
- }
74
-
75
- _initSubscriptions(args) {
76
- super._initSubscriptions(args);
77
- this._unsubscribes = [
78
- ...this._unsubscribes,
79
- this._views.on(ROLE.RELATED_QUESTIONS, 'click', event => this._handleRelatedQuestionClick(event)),
80
- this._hub.on(fields.query(), args => this._query(args)),
81
- ];
82
- }
83
-
84
- // configuration //
85
- set productId(value) {
86
- console.warning('DEPRECATED: use useApi() instead');
87
- this.useApi({
88
- product_id: value,
89
- });
90
- }
91
-
92
- useApi(...args) {
93
- const options = (typeof args[0] === 'object' ? args[0] : args[1]) || {};
94
- const { product_id } = options;
95
- if (product_id) {
96
- this._productId = product_id;
97
- }
98
- return super.useApi(...args);
99
- }
100
-
101
- useLink(fn, options) {
102
- UseLinkMixin.prototype.useLink.call(this, fn, options);
103
- // also put options to layouts
104
- if (options) {
105
- this.useLayouts({
106
- [ROLE.RELATED_QUESTIONS]: { link: options },
107
- });
108
- }
109
- return this;
110
- }
111
-
112
- // lifecycle //
113
- start({ relatedQuestions = true } = {}) {
114
- if (this._linkFn === undefined) {
115
- throw new Error('Must define link mapping function with useLink(fn) before calling start()');
116
- }
117
- // in explore workflow, start() triggers query
118
- // TODO: we should still make the query lifecycle
119
- if (relatedQuestions) {
120
- this._request();
121
- } else {
122
- // TODO: ad-hoc
123
- const { session } = this;
124
- this.updateData({ session, request: {}, value: { related_questions: [] } });
125
- }
126
- return this;
127
- }
128
-
129
- notifyViewUpdate(role = ROLE.RELATED_QUESTIONS, ...args) {
130
- super.notifyViewUpdate(role, ...args);
131
- return this;
132
- }
133
-
134
- _defaultProcessData(data, oldData) {
135
- data = super._defaultProcessData(data, oldData);
136
- data = this._addUrlToRelatedQuestions(data);
137
- return data;
138
- }
139
-
140
- _addUrlToRelatedQuestions(data) {
141
- const { value } = data;
142
- if (!value || !value.related_questions) {
143
- return data;
144
- }
145
- const [linkFn, linkOptions = {}] = this._linkFn || [];
146
- const getDisplayedUrl = text => linkFn && linkOptions.showUrl ? this._getSubmitUrl({ q: text, generated: true }) : '#';
147
- const related_questions = value.related_questions.map(text => ({
148
- text,
149
- url: getDisplayedUrl(text),
150
- }));
151
- return {
152
- ...data,
153
- value: {
154
- ...value,
155
- related_questions,
156
- },
157
- };
158
- }
159
-
160
- _handleRelatedQuestionClick({ value: question, ...event }) {
161
- this._events.emit('select', Object.freeze({ ...event, question }));
162
- const [linkFn, linkOptions = {}] = this._linkFn || [];
163
- if (!linkFn || !linkOptions.showUrl) {
164
- event.domEvent && event.domEvent.preventDefault();
165
- }
166
- if (linkFn && !linkOptions.showUrl) {
167
- this._submitToPage({ q: question.text, generated: true });
168
- }
169
- }
170
-
171
- query(args) {
172
- if (!args.q) {
173
- throw new Error(`q is required in query() call`);
174
- }
175
- this._hub.update(fields.query(), args);
176
- }
177
-
178
- _query(args) {
179
- this._submitToPage({ ...args, generated: false });
180
- }
181
-
182
- _getSubmitUrl(args) {
183
- // TODO: if trending_questions -> qs = '_trending'
184
- let url = UseLinkMixin.prototype._getSubmitUrl.call(this, args);
185
- if (!args.generated || !this._productId) {
186
- return url;
187
- }
188
- return `${url}&qs=${encodeURIComponent(this._productId)}`;
189
- }
190
-
191
- }
192
-
193
- enableUseLink(Explore.prototype);
194
- makeAutocompletable(Explore.prototype);
@@ -1,18 +0,0 @@
1
- import UnitWorkflowContext from './units.js';
2
- import Explore from './explore.js';
3
- import { makeAutocompletableContext } from './autocompletable.js';
4
-
5
- export default class Explores extends UnitWorkflowContext {
6
-
7
- constructor(plugin, client) {
8
- super('explores', plugin, client);
9
- this._initAutocompleteContext();
10
- }
11
-
12
- _create(unitId) {
13
- return new Explore(this, unitId);
14
- }
15
-
16
- }
17
-
18
- makeAutocompletableContext(Explores.prototype);
@@ -1,73 +0,0 @@
1
- import AnswerBasedWorkflow from './answer-based.js';
2
- import { fields } from '../actor/index.js';
3
- import { writeKeywordsToData, writeMisoIdToSession, writeMisoIdFromSession, writeUnanswerableToMeta } from './processors.js';
4
-
5
- const ROLES_OPTIONS = AnswerBasedWorkflow.ROLES_OPTIONS;
6
-
7
- export default class HybridSearchAnswer extends AnswerBasedWorkflow {
8
-
9
- constructor(superworkflow) {
10
- super({
11
- name: 'hybrid-search/answer',
12
- plugin: superworkflow._plugin,
13
- client: superworkflow._client,
14
- options: superworkflow._options,
15
- defaults: superworkflow._defaults,
16
- roles: ROLES_OPTIONS,
17
- superworkflow,
18
- });
19
- }
20
-
21
- _initProperties(args) {
22
- super._initProperties(args);
23
- this._superworkflow = args.superworkflow;
24
- }
25
-
26
- _initSession() {} // no reset here, will manually reset later
27
-
28
- _doLoading(data) {
29
- const { session } = this;
30
- this.updateData({ ...data, session });
31
- }
32
-
33
- _queryWithQuestionId(data) {
34
- const { session } = this;
35
- const { request, value } = data;
36
- this.updateData({ ...data, session });
37
- // start query with question_id
38
- const { question_id } = value;
39
- if (!question_id) {
40
- return;
41
- }
42
- // forge the request
43
- const payload = {
44
- ...request.payload,
45
- question_id,
46
- };
47
- if (payload.metadata.page !== undefined) {
48
- delete payload.metadata.page;
49
- }
50
- this._hub.update(fields.request(), { ...request, payload, session });
51
- }
52
-
53
- // data //
54
- _defaultProcessData(data, oldData) {
55
- data = super._defaultProcessData(data, oldData);
56
- data = writeKeywordsToData(data);
57
- data = writeMisoIdFromSession(data);
58
- data = writeUnanswerableToMeta(data);
59
- return data;
60
- }
61
-
62
- _handleHeadResponse(data) {
63
- super._handleHeadResponse(data);
64
- // keep track of miso_id in session
65
- writeMisoIdToSession(data);
66
- }
67
-
68
- // interactions //
69
- _onTracker(args) {
70
- this._superworkflow._onTracker(args);
71
- }
72
-
73
- }
@@ -1,116 +0,0 @@
1
- import SearchBasedWorkflow from './search-based.js';
2
-
3
- const RESULTS_ROLE_MEMBERS = SearchBasedWorkflow.ROLES_OPTIONS.members;
4
-
5
- function getSubworkflowByRole(role) {
6
- // TODO: ROLE.ERROR
7
- return RESULTS_ROLE_MEMBERS.includes(role) ? 'results' : 'answer';
8
- }
9
-
10
- export default class HybridSearchViewsActor {
11
-
12
- constructor(subviews) {
13
- this._subviews = subviews;
14
- this._containers = new Set();
15
- }
16
-
17
- get filters() {
18
- return this._subviews.results.filters;
19
- }
20
-
21
- on(role, event, callback) {
22
- return this._getSubviews(role).on(role, event, callback);
23
- }
24
-
25
- get(role) {
26
- return this._getSubviews(role).get(role);
27
- }
28
-
29
- getAll(role) {
30
- return this._getSubviews(role).getAll(role);
31
- }
32
-
33
- addContainer(element) {
34
- if (this._containers.has(element)) {
35
- return;
36
- }
37
- this._containers.add(element);
38
-
39
- const { components } = element;
40
- for (const component of components) {
41
- this.addComponent(component);
42
- }
43
- }
44
-
45
- removeContainer(element) {
46
- for (const subviews of this._getAllSubviews()) {
47
- subviews.removeContainer(element);
48
- }
49
- this._containers.delete(element);
50
- }
51
-
52
- addComponent(element) {
53
- this._getSubviews(element.role).addComponent(element);
54
- this._addContainerToSubviews(element._container, element);
55
- }
56
-
57
- removeComponent(element) {
58
- this._getSubviews(element.role).removeComponent(element);
59
- this._removeContainerFromSubviewsIfNecessary(element._container);
60
- }
61
-
62
- updateComponentRole(element, oldRole, newRole) {
63
- // TODO
64
- }
65
-
66
- refreshElement(element) {
67
- this._getSubviews(element.role).refreshElement(element);
68
- }
69
-
70
- // helpers //
71
- _getAllSubviews() {
72
- return Object.values(this._subviews);
73
- }
74
-
75
- _getSubviews(role) {
76
- return this._subviews[getSubworkflowByRole(role)];
77
- }
78
-
79
- _addContainerToSubviews(container, child) {
80
- if (!container) {
81
- return;
82
- }
83
- const { role } = child;
84
- const subviews = this._getSubviews(role);
85
- if (subviews._containers.has(container)) {
86
- return;
87
- }
88
- // check if the container is in other subviews
89
- for (const otherSubviews of this._getAllSubviews()) {
90
- if (otherSubviews === subviews) {
91
- continue;
92
- }
93
- if (otherSubviews._containers.has(container)) {
94
- // find the conflicting element
95
- for (const component of container.components) {
96
- if (otherSubviews.containsElement(component)) {
97
- throw new Error(`<${container.tagName.toLowerCase()}> cannot contain both <${component.tagName.toLowerCase()}> and <${child.tagName.toLowerCase()}>, for they don't share the same data lifecycle.`);
98
- }
99
- }
100
- throw new Error(`Failed to add container <${container.tagName.toLowerCase()}> with child component <${child.tagName.toLowerCase()}>.`);
101
- }
102
- }
103
- // add the container to the subviews
104
- subviews.addContainer(container);
105
- }
106
-
107
- _removeContainerFromSubviewsIfNecessary(container) {
108
- if (!container || container.components.length > 0) {
109
- return;
110
- }
111
- for (const subviews of this._getAllSubviews()) {
112
- subviews.removeContainer(container);
113
- }
114
- }
115
-
116
- }
@@ -1,230 +0,0 @@
1
- import { API } from '@miso.ai/commons';
2
- import SearchBasedWorkflow from './search-based.js';
3
- import AnswerBasedWorkflow from './answer-based.js';
4
- import { ROLE, WORKFLOW_CONFIGURABLE } from '../constants.js';
5
- import { SearchBoxLayout, TextLayout, HorizontalLayout } from '../layout/index.js';
6
- import { compactArticle, compactArticleInfoBlock } from '../layout/templates.js';
7
- import HybridSearchAnswer from './hybrid-search-answer.js';
8
- import HybridSearchViewsActor from './hybrid-search-views.js';
9
- import { makeConfigurable } from './options/index.js';
10
-
11
- import { mergeApiPayloads } from '@miso.ai/commons';
12
- import { STATUS, REQUEST_TYPE } from '../constants.js';
13
- import { writeMisoIdToSession, writeQuestionSourceToPayload, disableAnswerForNonQueryRequest, carryOverQuestionIdToData, writeAnswerInfoToInteraction } from './processors.js';
14
- import { makeAutocompletable } from './autocompletable.js';
15
-
16
- const DEFAULT_API_OPTIONS = Object.freeze({
17
- group: API.GROUP.ASK,
18
- name: API.NAME.SEARCH,
19
- payload: {
20
- ...AnswerBasedWorkflow.DEFAULT_API_OPTIONS.payload,
21
- ...SearchBasedWorkflow.DEFAULT_API_OPTIONS.payload,
22
- source_fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at', 'title', 'authors'],
23
- },
24
- });
25
-
26
- const DEFAULT_LAYOUTS = Object.freeze({
27
- ...AnswerBasedWorkflow.DEFAULT_LAYOUTS,
28
- ...SearchBasedWorkflow.DEFAULT_LAYOUTS,
29
- [ROLE.QUERY]: [SearchBoxLayout.type, { placeholder: '' }],
30
- [ROLE.QUESTION]: [TextLayout.type, { raw: true }],
31
- [ROLE.SOURCES]: [
32
- HorizontalLayout.type,
33
- {
34
- incremental: true,
35
- itemType: 'article',
36
- templates: {
37
- ordered: true,
38
- article: compactArticle,
39
- articleInfoBlock: compactArticleInfoBlock
40
- }
41
- }
42
- ],
43
- });
44
-
45
- const DEFAULT_TRACKERS = Object.freeze({
46
- ...AnswerBasedWorkflow.DEFAULT_TRACKERS,
47
- ...SearchBasedWorkflow.DEFAULT_TRACKERS,
48
- });
49
-
50
- const DEFAULT_PAGINATION = Object.freeze({
51
- ...SearchBasedWorkflow.DEFAULT_PAGINATION,
52
- active: true,
53
- });
54
-
55
- const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
56
- api: {
57
- group: API.GROUP.ASK,
58
- name: API.NAME.SEARCH_AUTOCOMPLETE,
59
- payload: {
60
- completion_fields: ['suggested_queries'],
61
- },
62
- },
63
- });
64
-
65
- const DEFAULT_FILTERS_OPTIONS = Object.freeze({
66
- sort: {
67
- options: [
68
- { field: 'relevance', text: 'Relevance', default: true },
69
- { field: 'published_at', text: 'Date' },
70
- ],
71
- },
72
- });
73
-
74
- const DEFAULT_OPTIONS = Object.freeze({
75
- ...AnswerBasedWorkflow.DEFAULT_OPTIONS,
76
- ...SearchBasedWorkflow.DEFAULT_OPTIONS,
77
- api: DEFAULT_API_OPTIONS,
78
- layouts: DEFAULT_LAYOUTS,
79
- trackers: DEFAULT_TRACKERS,
80
- autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
81
- pagination: DEFAULT_PAGINATION,
82
- filters: DEFAULT_FILTERS_OPTIONS,
83
- });
84
-
85
- const ROLES_OPTIONS = Object.freeze({
86
- main: ROLE.PRODUCTS,
87
- members: Object.keys(DEFAULT_LAYOUTS),
88
- mappings: Object.freeze({
89
- ...AnswerBasedWorkflow.ROLES_OPTIONS.mappings,
90
- ...SearchBasedWorkflow.ROLES_OPTIONS.mappings,
91
- }),
92
- });
93
-
94
- const EXTRA_OPTIONS = Object.freeze({
95
- api: Object.freeze({
96
- polling: false,
97
- }),
98
- });
99
-
100
- export default class HybridSearch extends SearchBasedWorkflow {
101
-
102
- constructor(plugin, client) {
103
- super({
104
- name: 'hybrid-search',
105
- plugin,
106
- client,
107
- roles: ROLES_OPTIONS,
108
- defaults: DEFAULT_OPTIONS,
109
- extraOptions: EXTRA_OPTIONS,
110
- });
111
- }
112
-
113
- _initProperties(args) {
114
- super._initProperties(args);
115
- this._initAutocomplete(args);
116
- this._answer = new HybridSearchAnswer(this);
117
- }
118
-
119
- _initActors(args) {
120
- super._initActors(args);
121
- this._views = new HybridSearchViewsActor({
122
- results: this._views,
123
- answer: this._answer._views,
124
- });
125
- }
126
-
127
- restart({ type } = {}) {
128
- super.restart();
129
- if (!type || type === REQUEST_TYPE.QUERY) {
130
- this._answer.restart();
131
- }
132
- }
133
-
134
- // properties //
135
- get answer() {
136
- return this._answer;
137
- }
138
-
139
- get questionId() {
140
- return this._answer.questionId;
141
- }
142
-
143
- // query //
144
- _buildPayload(payload, type) {
145
- payload = super._buildPayload(payload, type);
146
- // borrow the work from the sibling
147
- payload = disableAnswerForNonQueryRequest(payload, type);
148
- payload = writeQuestionSourceToPayload(payload);
149
- payload = this._writeQuestionIdToPayload(payload, type);
150
- if (payload.answer !== false) {
151
- // uses autoQuery params, so we want to apply to this workflow
152
- payload = AnswerBasedWorkflow.prototype._writeWikiLinkTemplateToPayload.call(this, payload);
153
- }
154
- return payload;
155
- }
156
-
157
- _buildOrderBy(sort) {
158
- if (!sort) {
159
- return undefined;
160
- }
161
- // works differently than search
162
- return sort.field;
163
- }
164
-
165
- _writeQuestionIdToPayload(payload, type) {
166
- if (type === REQUEST_TYPE.QUERY) {
167
- return payload;
168
- }
169
- const question_id = this._answer.questionId;
170
- if (!question_id) {
171
- return payload;
172
- }
173
- return mergeApiPayloads(payload, {
174
- metadata: {
175
- question_id,
176
- },
177
- });
178
- }
179
-
180
- // data //
181
- _defaultProcessData(data, oldData) {
182
- data = super._defaultProcessData(data, oldData);
183
- writeMisoIdToSession(data);
184
- return data;
185
- }
186
-
187
- _updateDataInHub(data, oldData) {
188
- this._dispatchDataToAnswerWorkflow(data);
189
- data = carryOverQuestionIdToData(data, oldData); // TODO: may as well move to process data
190
- super._updateDataInHub(data, oldData);
191
- }
192
-
193
- _dispatchDataToAnswerWorkflow(data) {
194
- const { request } = data;
195
- if (!request) {
196
- return;
197
- }
198
- const { type, payload } = request;
199
- if (type !== REQUEST_TYPE.QUERY || !payload || payload.answer === false) {
200
- return;
201
- }
202
- switch (data.status) {
203
- case STATUS.LOADING:
204
- // share the loading status with its sibling
205
- this._answer._doLoading(data);
206
- break;
207
- case STATUS.READY:
208
- // start a query with retrieved question ID, if any
209
- this._answer._queryWithQuestionId(data);
210
- break;
211
- }
212
- }
213
-
214
- // interactions //
215
- _defaultProcessInteraction(payload, args) {
216
- payload = super._defaultProcessInteraction(payload, args);
217
- payload = writeAnswerInfoToInteraction(payload, args);
218
- return payload;
219
- }
220
-
221
- // destroy //
222
- _destroy() {
223
- this._answer.destroy();
224
- super._destroy();
225
- }
226
-
227
- }
228
-
229
- makeConfigurable(HybridSearch.prototype, [WORKFLOW_CONFIGURABLE.PAGINATION, WORKFLOW_CONFIGURABLE.FILTERS]);
230
- makeAutocompletable(HybridSearch.prototype);
@@ -1,5 +0,0 @@
1
- export { default as Asks } from './asks.js';
2
- export { default as HybridSearch } from './hybrid-search.js';
3
- export { default as Search } from './search.js';
4
- export { default as Recommendations } from './recommendations.js';
5
- export { default as Explores } from './explores.js';
@@ -1,31 +0,0 @@
1
- import { trimObj, mergeApiPayloads } from '@miso.ai/commons';
2
- import { mergeOptions } from './utils.js';
3
-
4
- export function normalizeApiOptions([name, payload] = []) {
5
- // TODO: take object form as well
6
- if (name === false) {
7
- return { actor: false };
8
- }
9
- if (typeof name === 'object' && payload === undefined) {
10
- payload = name;
11
- name = undefined;
12
- }
13
- let group = undefined;
14
- if (name && name.indexOf('/') !== -1) {
15
- [group, name] = name.split('/');
16
- }
17
- if ((name && typeof name !== 'string') || (payload !== undefined && typeof payload !== 'object')) {
18
- throw new Error(`Invalid arguments for useApi(): ${name}, ${payload}`);
19
- }
20
- return trimObj({ group, name, payload });
21
- }
22
-
23
- export function mergeApiOptions(...optionsList) {
24
- if (optionsList[optionsList.length - 1] === false) {
25
- return false;
26
- }
27
- return mergeOptions(optionsList, (merged, options) => Object.assign(merged, {
28
- ...options,
29
- payload: mergeApiPayloads(merged.payload, options.payload),
30
- }));
31
- }