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

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 (226) hide show
  1. package/dist/cjs/asset/svgs.js +17 -4
  2. package/dist/cjs/combo/ask/index.js +2 -2
  3. package/dist/cjs/constants.js +120 -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 +259 -0
  7. package/dist/cjs/element/container/index.js +28 -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-message-item.js +91 -0
  14. package/dist/cjs/element/container/miso-recommendation.js +1 -1
  15. package/dist/cjs/element/container/miso-search.js +1 -1
  16. package/dist/cjs/element/container/miso-thread-item.js +91 -0
  17. package/dist/cjs/element/context/miso-follow-ups.js +1 -1
  18. package/dist/cjs/element/role/index.js +49 -0
  19. package/dist/cjs/element/role/miso-delete.js +20 -0
  20. package/dist/cjs/element/role/miso-messages.js +20 -0
  21. package/dist/cjs/element/role/miso-new-thread.js +20 -0
  22. package/dist/cjs/element/role/miso-rename.js +20 -0
  23. package/dist/cjs/element/role/miso-subscription.js +20 -0
  24. package/dist/cjs/element/role/miso-threads.js +20 -0
  25. package/dist/cjs/element/role/miso-title.js +20 -0
  26. package/dist/cjs/layout/affiliation/affiliation.js +1 -1
  27. package/dist/cjs/layout/banner/banner.js +2 -1
  28. package/dist/cjs/layout/button/button.js +170 -0
  29. package/dist/cjs/layout/button/checkbox.js +116 -0
  30. package/dist/cjs/layout/button/more-button.js +3 -3
  31. package/dist/cjs/layout/container/container.js +1 -1
  32. package/dist/cjs/layout/container/item-container.js +99 -0
  33. package/dist/cjs/layout/error/error.js +2 -1
  34. package/dist/cjs/layout/index.js +42 -0
  35. package/dist/cjs/layout/input/facets.js +4 -3
  36. package/dist/cjs/layout/input/option-list.js +3 -2
  37. package/dist/cjs/layout/input/search-box.js +50 -12
  38. package/dist/cjs/layout/input/select.js +2 -1
  39. package/dist/cjs/layout/list/cards.js +2 -1
  40. package/dist/cjs/layout/list/carousel.js +2 -1
  41. package/dist/cjs/layout/list/collection.js +13 -1
  42. package/dist/cjs/layout/list/gallery.js +2 -1
  43. package/dist/cjs/layout/list/horizontal.js +2 -1
  44. package/dist/cjs/layout/list/list.js +2 -1
  45. package/dist/cjs/layout/list/messages.js +359 -0
  46. package/dist/cjs/layout/list/threads.js +199 -0
  47. package/dist/cjs/layout/mixin/trackable.js +4 -5
  48. package/dist/cjs/layout/mixin/triggerable.js +2 -2
  49. package/dist/cjs/layout/radio/feedback.js +4 -3
  50. package/dist/cjs/layout/templates.js +97 -0
  51. package/dist/cjs/layout/text/question.js +71 -0
  52. package/dist/cjs/layout/text/text.js +2 -1
  53. package/dist/cjs/layout/text/typewriter/index.js +18 -23
  54. package/dist/cjs/plugin.js +43 -104
  55. package/dist/cjs/util/confirm.js +33 -0
  56. package/dist/cjs/util/dom.js +21 -0
  57. package/dist/cjs/util/modal.js +48 -0
  58. package/dist/cjs/util/prompt.js +47 -0
  59. package/dist/cjs/version.js +1 -1
  60. package/package.json +5 -4
  61. package/src/CLAUDE.md +51 -104
  62. package/src/asset/svgs.js +16 -3
  63. package/src/combo/ask/index.js +2 -2
  64. package/src/constants.js +39 -147
  65. package/src/defaults/ask/controls.js +1 -1
  66. package/src/defaults/hybrid-search/answer-box.js +2 -2
  67. package/src/defaults.js +174 -0
  68. package/src/element/container/index.js +4 -0
  69. package/src/element/container/miso-ask.js +3 -3
  70. package/src/element/container/miso-conversation.js +19 -0
  71. package/src/element/container/miso-explore.js +1 -1
  72. package/src/element/container/miso-history.js +19 -0
  73. package/src/element/container/miso-hybrid-search.js +1 -1
  74. package/src/element/container/miso-message-item.js +94 -0
  75. package/src/element/container/miso-recommendation.js +1 -1
  76. package/src/element/container/miso-search.js +1 -1
  77. package/src/element/container/miso-thread-item.js +94 -0
  78. package/src/element/context/miso-follow-ups.js +1 -1
  79. package/src/element/role/index.js +7 -0
  80. package/src/element/role/miso-delete.js +16 -0
  81. package/src/element/role/miso-messages.js +16 -0
  82. package/src/element/role/miso-new-thread.js +16 -0
  83. package/src/element/role/miso-rename.js +16 -0
  84. package/src/element/role/miso-subscription.js +16 -0
  85. package/src/element/role/miso-threads.js +16 -0
  86. package/src/element/role/miso-title.js +16 -0
  87. package/src/layout/affiliation/affiliation.js +2 -2
  88. package/src/layout/banner/banner.js +2 -1
  89. package/src/layout/button/button.js +152 -0
  90. package/src/layout/button/checkbox.js +92 -0
  91. package/src/layout/button/more-button.js +3 -3
  92. package/src/layout/container/container.js +2 -2
  93. package/src/layout/container/item-container.js +99 -0
  94. package/src/layout/error/error.js +2 -1
  95. package/src/layout/index.js +6 -0
  96. package/src/layout/input/facets.js +3 -2
  97. package/src/layout/input/option-list.js +3 -2
  98. package/src/layout/input/search-box.js +45 -8
  99. package/src/layout/input/select.js +2 -1
  100. package/src/layout/list/cards.js +2 -1
  101. package/src/layout/list/carousel.js +2 -1
  102. package/src/layout/list/collection.js +15 -2
  103. package/src/layout/list/gallery.js +2 -1
  104. package/src/layout/list/horizontal.js +2 -1
  105. package/src/layout/list/list.js +2 -1
  106. package/src/layout/list/messages.js +316 -0
  107. package/src/layout/list/threads.js +166 -0
  108. package/src/layout/mixin/trackable.js +2 -3
  109. package/src/layout/mixin/triggerable.js +1 -1
  110. package/src/layout/radio/feedback.js +3 -2
  111. package/src/layout/templates.js +97 -0
  112. package/src/layout/text/question.js +58 -0
  113. package/src/layout/text/text.js +2 -1
  114. package/src/layout/text/typewriter/index.js +15 -18
  115. package/src/plugin.js +31 -117
  116. package/src/util/confirm.js +28 -0
  117. package/src/util/dom.js +16 -0
  118. package/src/util/modal.js +49 -0
  119. package/src/util/prompt.js +42 -0
  120. package/src/version.js +1 -1
  121. package/dist/cjs/actor/data.js +0 -132
  122. package/dist/cjs/actor/feedback.js +0 -29
  123. package/dist/cjs/actor/fields.js +0 -57
  124. package/dist/cjs/actor/filters.js +0 -161
  125. package/dist/cjs/actor/hub.js +0 -57
  126. package/dist/cjs/actor/index.js +0 -73
  127. package/dist/cjs/actor/interactions.js +0 -36
  128. package/dist/cjs/actor/sessions.js +0 -25
  129. package/dist/cjs/actor/tracker-states.js +0 -61
  130. package/dist/cjs/actor/tracker.js +0 -109
  131. package/dist/cjs/actor/trackers.js +0 -52
  132. package/dist/cjs/actor/utils.js +0 -15
  133. package/dist/cjs/actor/view.js +0 -294
  134. package/dist/cjs/actor/views.js +0 -209
  135. package/dist/cjs/source.js +0 -27
  136. package/dist/cjs/util/proxy.js +0 -88
  137. package/dist/cjs/util/trackers.js +0 -88
  138. package/dist/cjs/workflow/affiliations.js +0 -140
  139. package/dist/cjs/workflow/answer-based.js +0 -337
  140. package/dist/cjs/workflow/ask.js +0 -319
  141. package/dist/cjs/workflow/asks.js +0 -150
  142. package/dist/cjs/workflow/autocompletable.js +0 -63
  143. package/dist/cjs/workflow/autocomplete.js +0 -120
  144. package/dist/cjs/workflow/base.js +0 -418
  145. package/dist/cjs/workflow/context.js +0 -19
  146. package/dist/cjs/workflow/explore.js +0 -210
  147. package/dist/cjs/workflow/explores.js +0 -21
  148. package/dist/cjs/workflow/hybrid-search-answer.js +0 -88
  149. package/dist/cjs/workflow/hybrid-search-views.js +0 -109
  150. package/dist/cjs/workflow/hybrid-search.js +0 -213
  151. package/dist/cjs/workflow/index.js +0 -41
  152. package/dist/cjs/workflow/options/api.js +0 -41
  153. package/dist/cjs/workflow/options/auto-query.js +0 -97
  154. package/dist/cjs/workflow/options/configurable.js +0 -45
  155. package/dist/cjs/workflow/options/data-processor.js +0 -20
  156. package/dist/cjs/workflow/options/filters.js +0 -15
  157. package/dist/cjs/workflow/options/index.js +0 -126
  158. package/dist/cjs/workflow/options/interactions.js +0 -41
  159. package/dist/cjs/workflow/options/layouts.js +0 -79
  160. package/dist/cjs/workflow/options/options.js +0 -156
  161. package/dist/cjs/workflow/options/pagination.js +0 -25
  162. package/dist/cjs/workflow/options/roles.js +0 -15
  163. package/dist/cjs/workflow/options/templates.js +0 -30
  164. package/dist/cjs/workflow/options/trackers.js +0 -83
  165. package/dist/cjs/workflow/options/utils.js +0 -33
  166. package/dist/cjs/workflow/processors.js +0 -607
  167. package/dist/cjs/workflow/recommendation.js +0 -57
  168. package/dist/cjs/workflow/recommendations.js +0 -18
  169. package/dist/cjs/workflow/search-based.js +0 -337
  170. package/dist/cjs/workflow/search.js +0 -64
  171. package/dist/cjs/workflow/unit.js +0 -57
  172. package/dist/cjs/workflow/units.js +0 -42
  173. package/dist/cjs/workflow/use-link.js +0 -49
  174. package/src/actor/data.js +0 -106
  175. package/src/actor/feedback.js +0 -28
  176. package/src/actor/fields.js +0 -51
  177. package/src/actor/filters.js +0 -149
  178. package/src/actor/hub.js +0 -47
  179. package/src/actor/index.js +0 -10
  180. package/src/actor/interactions.js +0 -32
  181. package/src/actor/sessions.js +0 -21
  182. package/src/actor/tracker-states.js +0 -57
  183. package/src/actor/tracker.js +0 -104
  184. package/src/actor/trackers.js +0 -45
  185. package/src/actor/utils.js +0 -7
  186. package/src/actor/view.js +0 -272
  187. package/src/actor/views.js +0 -224
  188. package/src/source.js +0 -17
  189. package/src/util/proxy.js +0 -81
  190. package/src/util/trackers.js +0 -84
  191. package/src/workflow/affiliations.js +0 -121
  192. package/src/workflow/answer-based.js +0 -312
  193. package/src/workflow/ask.js +0 -284
  194. package/src/workflow/asks.js +0 -143
  195. package/src/workflow/autocompletable.js +0 -67
  196. package/src/workflow/autocomplete.js +0 -114
  197. package/src/workflow/base.js +0 -396
  198. package/src/workflow/context.js +0 -16
  199. package/src/workflow/explore.js +0 -194
  200. package/src/workflow/explores.js +0 -18
  201. package/src/workflow/hybrid-search-answer.js +0 -73
  202. package/src/workflow/hybrid-search-views.js +0 -116
  203. package/src/workflow/hybrid-search.js +0 -230
  204. package/src/workflow/index.js +0 -5
  205. package/src/workflow/options/api.js +0 -31
  206. package/src/workflow/options/auto-query.js +0 -70
  207. package/src/workflow/options/configurable.js +0 -48
  208. package/src/workflow/options/data-processor.js +0 -15
  209. package/src/workflow/options/filters.js +0 -10
  210. package/src/workflow/options/index.js +0 -11
  211. package/src/workflow/options/interactions.js +0 -36
  212. package/src/workflow/options/layouts.js +0 -73
  213. package/src/workflow/options/options.js +0 -175
  214. package/src/workflow/options/pagination.js +0 -18
  215. package/src/workflow/options/roles.js +0 -12
  216. package/src/workflow/options/templates.js +0 -27
  217. package/src/workflow/options/trackers.js +0 -80
  218. package/src/workflow/options/utils.js +0 -26
  219. package/src/workflow/processors.js +0 -490
  220. package/src/workflow/recommendation.js +0 -63
  221. package/src/workflow/recommendations.js +0 -14
  222. package/src/workflow/search-based.js +0 -329
  223. package/src/workflow/search.js +0 -73
  224. package/src/workflow/unit.js +0 -51
  225. package/src/workflow/units.js +0 -43
  226. package/src/workflow/use-link.js +0 -41
package/src/asset/svgs.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { isInBrowser } from '@miso.ai/commons';
1
2
  import version from '../version.js';
2
3
 
3
4
  function trianglePath(r) {
@@ -18,6 +19,12 @@ const ICON_NAME = {
18
19
  CHEVRON: 'chevron',
19
20
  CHEVRON_NEGATIVE: 'chevron-negative',
20
21
  BULB: 'bulb',
22
+ DOTS_VERTICAL: 'dots-vertical',
23
+ PLUS: 'plus',
24
+ PENCIL: 'pencil',
25
+ BELL: 'bell',
26
+ BELL_FILL: 'bell-fill',
27
+ TRASH: 'trash',
21
28
  };
22
29
 
23
30
  // CC0 SVGs
@@ -31,9 +38,15 @@ const ICON_CHEVRON = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON}" viewBox="-100
31
38
  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>`;
32
39
 
33
40
  // from Bootstrap Icons (MIT)
34
- const ICON_BULB = `<symbol id="${PREFIX}-${ICON_NAME.BULB}" viewBox="0 0 16 16"><path d="M2 6a6 6 0 1 1 10.174 4.31c-.203.196-.359.4-.453.619l-.762 1.769A.5.5 0 0 1 10.5 13a.5.5 0 0 1 0 1 .5.5 0 0 1 0 1l-.224.447a1 1 0 0 1-.894.553H6.618a1 1 0 0 1-.894-.553L5.5 15a.5.5 0 0 1 0-1 .5.5 0 0 1 0-1 .5.5 0 0 1-.46-.302l-.761-1.77a2 2 0 0 0-.453-.618A5.98 5.98 0 0 1 2 6m6-5a5 5 0 0 0-3.479 8.592c.263.254.514.564.676.941L5.83 12h4.342l.632-1.467c.162-.377.413-.687.676-.941A5 5 0 0 0 8 1"/></symbol>`;
41
+ const ICON_BULB = `<symbol id="${PREFIX}-${ICON_NAME.BULB}" viewBox="0 0 16 16"><path fill="currentColor" d="M2 6a6 6 0 1 1 10.174 4.31c-.203.196-.359.4-.453.619l-.762 1.769A.5.5 0 0 1 10.5 13a.5.5 0 0 1 0 1 .5.5 0 0 1 0 1l-.224.447a1 1 0 0 1-.894.553H6.618a1 1 0 0 1-.894-.553L5.5 15a.5.5 0 0 1 0-1 .5.5 0 0 1 0-1 .5.5 0 0 1-.46-.302l-.761-1.77a2 2 0 0 0-.453-.618A5.98 5.98 0 0 1 2 6m6-5a5 5 0 0 0-3.479 8.592c.263.254.514.564.676.941L5.83 12h4.342l.632-1.467c.162-.377.413-.687.676-.941A5 5 0 0 0 8 1"/></symbol>`;
42
+ const ICON_DOTS_VERTICAL = `<symbol id="${PREFIX}-${ICON_NAME.DOTS_VERTICAL}" viewBox="0 0 16 16"><path fill="currentColor" d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/></symbol>`;
43
+ const ICON_PLUS = `<symbol id="${PREFIX}-${ICON_NAME.PLUS}" viewBox="0 0 16 16"><path fill="currentColor" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2"/></symbol>`;
44
+ const ICON_PENCIL = `<symbol id="${PREFIX}-${ICON_NAME.PENCIL}" viewBox="0 0 16 16"><path fill="currentColor" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.325-.175"/></symbol>`;
45
+ const ICON_BELL = `<symbol id="${PREFIX}-${ICON_NAME.BELL}" viewBox="0 0 16 16"><path fill="currentColor" d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2M8 1.918l-.797.161A4 4 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4 4 0 0 0-3.203-3.92zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5 5 0 0 1 13 6c0 .88.32 4.2 1.22 6"/></symbol>`;
46
+ const ICON_BELL_FILL = `<symbol id="${PREFIX}-${ICON_NAME.BELL_FILL}" viewBox="0 0 16 16"><path fill="currentColor" d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2m.995-14.901a1 1 0 1 0-1.99 0A5 5 0 0 0 3 6c0 1.098-.5 6-2 7h14c-1.5-1-2-5.902-2-7 0-2.42-1.72-4.44-4.005-4.901"/></symbol>`;
47
+ const ICON_TRASH = `<symbol id="${PREFIX}-${ICON_NAME.TRASH}" viewBox="0 0 16 16"><path fill="currentColor" d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/><path fill="currentColor" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"/></symbol>`;
35
48
 
36
- const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE, ICON_BULB];
49
+ const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE, ICON_BULB, ICON_DOTS_VERTICAL, ICON_PLUS, ICON_PENCIL, ICON_BELL, ICON_BELL_FILL, ICON_TRASH];
37
50
 
38
51
  const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
39
52
 
@@ -47,7 +60,7 @@ function loadSvgSprites() {
47
60
  document.head.insertAdjacentHTML('beforeend', SPRITES_SVG);
48
61
  }
49
62
 
50
- loadSvgSprites();
63
+ isInBrowser && loadSvgSprites();
51
64
 
52
65
  function _icon(name) {
53
66
  return `<svg class="miso-ui-icon miso-ui-icon-${name}"><use href="#${PREFIX}-${name}"></use></svg>`;
@@ -102,8 +102,8 @@ export default class AskCombo extends Combo {
102
102
  const { wireFollowUps, wireRelatedResources } = MisoClient.ui.defaults.ask;
103
103
  const { templates = {}, features = {}, api } = options;
104
104
 
105
- const context = client.ui.asks;
106
- const rootWorkflow = client.ui.ask;
105
+ const context = client.workflows.asks;
106
+ const rootWorkflow = client.workflows.ask;
107
107
 
108
108
  if (api) {
109
109
  context.useApi(api);
package/src/constants.js CHANGED
@@ -1,156 +1,48 @@
1
+ // workflow-level constants live in the workflow package; re-exported here for convenience
2
+ export {
3
+ DEFAULT_UNIT_ID,
4
+ ROLE,
5
+ isDataRole,
6
+ isProductRole,
7
+ EVENT_TYPE,
8
+ TRACKING_EVENT_TYPES,
9
+ PERFORMANCE_EVENT_TYPES,
10
+ DIRECT_TRACKING_EVENT_TYPES,
11
+ isPerformanceEventType,
12
+ TRACKING_STATUS,
13
+ STATUS,
14
+ QUESTION_SOURCE,
15
+ validateEventType,
16
+ validateTrackingStatus,
17
+ WORKFLOW_CONFIGURABLE,
18
+ REQUEST_TYPE,
19
+ } from '@miso.ai/client-sdk-workflow';
20
+
1
21
  export const ATTR_DATA_MISO_UNIT_ID = `data-miso-unit-id`;
2
22
  export const ATTR_DATA_MISO_PRODUCT_ID = `data-miso-product-id`;
3
- export const DEFAULT_UNIT_ID = 'default';
4
23
 
5
- export const ROLE = Object.freeze({
24
+ export const LAYOUT_TYPE = Object.freeze({
6
25
  CONTAINER: 'container',
26
+ ITEM_CONTAINER: 'item-container',
27
+ ERROR: 'error',
7
28
  BANNER: 'banner',
8
- QUERY: 'query',
9
- FEEDBACK: 'feedback',
10
- PRODUCTS: 'products',
11
- CATEGORIES: 'categories',
12
- ATTRIBUTES: 'attributes',
13
- RESULTS: 'results',
14
- ITEMS: 'items',
15
- QUESTION: 'question',
16
- ANSWER: 'answer',
17
- REASONING: 'reasoning',
18
- IMAGES: 'images',
19
- SOURCES: 'sources',
20
- RELATED_RESOURCES: 'related_resources',
21
- FOLLOW_UP_QUESTIONS: 'follow_up_questions',
22
- QUERY_SUGGESTIONS: 'query_suggestions',
23
- RELATED_QUESTIONS: 'related_questions',
24
29
  AFFILIATION: 'affiliation',
25
- KEYWORDS: 'keywords',
30
+ LIST: 'list',
31
+ THREADS: 'threads',
32
+ MESSAGES: 'messages',
33
+ HORIZONTAL: 'horizontal',
34
+ CARDS: 'cards',
35
+ CAROUSEL: 'carousel',
36
+ GALLERY: 'gallery',
37
+ SEARCH_BOX: 'search-box',
38
+ OPTION_LIST: 'option-list',
26
39
  FACETS: 'facets',
27
- TOTAL: 'total',
28
- MORE: 'more',
29
- SORT: 'sort',
30
- ERROR: 'error',
31
- });
32
-
33
- const DATA_ROLE_SET = new Set([
34
- ROLE.PRODUCTS,
35
- ROLE.CATEGORIES,
36
- ROLE.ATTRIBUTES,
37
- ROLE.RESULTS,
38
- ROLE.ITEMS,
39
- ROLE.QUESTION,
40
- ROLE.ANSWER,
41
- ROLE.REASONING,
42
- ROLE.IMAGES,
43
- ROLE.SOURCES,
44
- ROLE.RELATED_RESOURCES,
45
- ROLE.FOLLOW_UP_QUESTIONS,
46
- ROLE.QUERY_SUGGESTIONS,
47
- ROLE.RELATED_QUESTIONS,
48
- ROLE.AFFILIATION,
49
- ROLE.FACETS,
50
- ROLE.TOTAL,
51
- ]);
52
-
53
- export function isDataRole(role) {
54
- return DATA_ROLE_SET.has(role);
55
- }
56
-
57
- const PRODUCT_ROLE_SET = new Set([
58
- ROLE.PRODUCTS,
59
- ROLE.IMAGES,
60
- ROLE.SOURCES,
61
- ROLE.RELATED_RESOURCES,
62
- ]);
63
-
64
- export function isProductRole(role) {
65
- return PRODUCT_ROLE_SET.has(role);
66
- }
67
-
68
- export const EVENT_TYPE = Object.freeze({
69
- IMPRESSION: 'impression',
70
- VIEWABLE: 'viewable',
71
- CLICK: 'click',
72
- SUBMIT: 'submit',
40
+ SELECT: 'select',
41
+ MORE_BUTTON: 'more-button',
42
+ BUTTON: 'button',
43
+ CHECKBOX: 'checkbox',
73
44
  FEEDBACK: 'feedback',
74
- HEARTBEAT: 'heartbeat',
75
- GENERIC_CLICK: 'generic_click',
76
- });
77
-
78
- export const TRACKING_EVENT_TYPES = [
79
- EVENT_TYPE.IMPRESSION,
80
- EVENT_TYPE.VIEWABLE,
81
- EVENT_TYPE.CLICK,
82
- EVENT_TYPE.SUBMIT,
83
- EVENT_TYPE.FEEDBACK,
84
- EVENT_TYPE.HEARTBEAT,
85
- ];
86
-
87
- export const PERFORMANCE_EVENT_TYPES = [
88
- EVENT_TYPE.IMPRESSION,
89
- EVENT_TYPE.VIEWABLE,
90
- EVENT_TYPE.CLICK,
91
- ];
92
-
93
- export const DIRECT_TRACKING_EVENT_TYPES = [
94
- EVENT_TYPE.SUBMIT,
95
- EVENT_TYPE.HEARTBEAT,
96
- EVENT_TYPE.GENERIC_CLICK,
97
- ];
98
-
99
- const PERFORMANCE_EVENT_TYPE_SET = new Set(PERFORMANCE_EVENT_TYPES);
100
-
101
- export function isPerformanceEventType(type) {
102
- return PERFORMANCE_EVENT_TYPE_SET.has(type);
103
- }
104
-
105
- export const TRACKING_STATUS = Object.freeze({
106
- UNTRACKED: 'untracked',
107
- TRACKING: 'tracking',
108
- TRIGGERED: 'triggered',
109
- });
110
-
111
- export const STATUS = Object.freeze({
112
- INITIAL: 'initial',
113
- LOADING: 'loading',
114
- ERRONEOUS: 'erroneous',
115
- READY: 'ready',
116
- ONGOING: 'ongoing',
117
- DONE: 'done',
118
- EMPTY: 'empty',
119
- NONEMPTY: 'nonempty',
120
- UNANSWERABLE: 'unanswerable',
121
- });
122
-
123
- export const QUESTION_SOURCE = Object.freeze({
124
- ORGANIC: '_organic',
125
- SUGGESTED_QUESTIONS: '_suggested_questions',
126
- INLINE_QUESTION_LINK: '_inline_question_link',
127
- });
128
-
129
- export function validateEventType(value) {
130
- if (TRACKING_EVENT_TYPES.indexOf(value) < 0) {
131
- throw new Error(`Unrecognized event type: ${value}`);
132
- }
133
- }
134
-
135
- export function validateTrackingStatus(value) {
136
- if (value !== TRACKING_STATUS.UNTRACKED && value !== TRACKING_STATUS.TRACKING && value !== TRACKING_STATUS.TRIGGERED) {
137
- throw new Error(`Unrecognized tracking status: ${value}`);
138
- }
139
- }
140
-
141
- export const WORKFLOW_CONFIGURABLE = Object.freeze({
142
- API: 'api',
143
- LAYOUTS: 'layouts',
144
- DATA_PROCESSOR: 'dataProcessor',
145
- TRACKERS: 'trackers',
146
- INTERACTIONS: 'interactions',
147
- FILTERS: 'filters',
148
- PAGINATION: 'pagination',
149
- TEMPLATES: 'templates',
150
- });
151
-
152
- export const REQUEST_TYPE = Object.freeze({
153
- QUERY: 'query',
154
- REFINE: 'refine',
155
- MORE: 'more',
45
+ TEXT: 'text',
46
+ QUESTION: 'question',
47
+ TYPEWRITER: 'typewriter',
156
48
  });
@@ -17,7 +17,7 @@ function setFollowUpTemplate(client, { template = followUpTemplate, ...options }
17
17
  if (template === followUpTemplate && !hasExtraOptions) {
18
18
  return; // same as default
19
19
  }
20
- client.ui.asks.useTemplates({
20
+ client.workflows.asks.useTemplates({
21
21
  followUp: hasExtraOptions ? (args) => template({ ...options, ...args }) : template,
22
22
  });
23
23
  }
@@ -1,6 +1,6 @@
1
1
  import { CLASS_PREFIX } from './constants.js';
2
2
  import { STATUS } from '../../constants.js';
3
- import { fields } from '../../actor/index.js';
3
+ import { fields } from '@miso.ai/client-sdk-workflow';
4
4
  import { showMore as DEFAULT_PHRASE_SHOW_MORE, showLess as DEFAULT_PHRASE_SHOW_LESS } from './phrases.js';
5
5
 
6
6
  const CLASS_OPEN = 'answer-box-open';
@@ -11,7 +11,7 @@ export default class AnswerBox {
11
11
 
12
12
  constructor(client, element, { classPrefix = CLASS_PREFIX, phrases = {}, hideWhenUnanswerable = true } = {}) {
13
13
  this._client = client;
14
- this._workflow = client.ui.hybridSearch;
14
+ this._workflow = client.workflows.hybridSearch;
15
15
  this._element = element;
16
16
  this._classPrefix = classPrefix;
17
17
  this._phrases = phrases;
@@ -0,0 +1,174 @@
1
+ import { escapeHtml } from '@miso.ai/commons';
2
+ import { ROLE, LAYOUT_TYPE } from './constants.js';
3
+ import { compactArticle, compactArticleInfoBlock } from './layout/templates.js';
4
+
5
+ /**
6
+ * Default layout options of each workflow, keyed by workflow name. The UI
7
+ * plugin seeds the workflow plugin's defaults store with these values at
8
+ * install. The tables mirror the workflow class hierarchy.
9
+ */
10
+
11
+ const BASE_LAYOUTS = {
12
+ [ROLE.CONTAINER]: LAYOUT_TYPE.CONTAINER,
13
+ [ROLE.ERROR]: LAYOUT_TYPE.ERROR,
14
+ };
15
+
16
+ const ANSWER_BASED_LAYOUTS = {
17
+ ...BASE_LAYOUTS,
18
+ [ROLE.QUERY]: [LAYOUT_TYPE.SEARCH_BOX, { placeholder: 'Ask a question' }],
19
+ [ROLE.QUESTION]: [LAYOUT_TYPE.TEXT, { tag: 'h2' }],
20
+ [ROLE.ANSWER]: LAYOUT_TYPE.TYPEWRITER,
21
+ [ROLE.FEEDBACK]: LAYOUT_TYPE.FEEDBACK,
22
+ [ROLE.IMAGES]: [LAYOUT_TYPE.GALLERY, { incremental: true, itemType: 'image' }],
23
+ [ROLE.SOURCES]: [LAYOUT_TYPE.LIST, { incremental: true, itemType: 'article', templates: { ordered: true } }],
24
+ [ROLE.AFFILIATION]: [LAYOUT_TYPE.AFFILIATION, { incremental: true, itemType: 'affiliation', link: { rel: 'noopener nofollow' } }],
25
+ };
26
+
27
+ function totalContent(layout, { value }) {
28
+ if (value === undefined) {
29
+ return '';
30
+ }
31
+ const { formatNumber } = layout.templates.helpers;
32
+ const formatted = formatNumber(value);
33
+ const label = value === 1 ? 'result' : 'results';
34
+ return `${formatted} ${label}`;
35
+ }
36
+
37
+ const { [ROLE.QUERY]: _answerBasedQueryLayout, ...MESSAGE_LAYOUTS } = ANSWER_BASED_LAYOUTS;
38
+
39
+ // the rename/delete button controls of a thread (the conversation header's,
40
+ // and a thread list item's context menu's): mapped to the thread record —
41
+ // the dialogs work with its title, and the buttons disable while the record
42
+ // has no thread id yet (a thread being created is not addressable until
43
+ // resolved; the workflows guard all the same)
44
+ const THREAD_CONTROL_OPTIONS = Object.freeze({
45
+ value: thread => thread && thread.title,
46
+ disabled: thread => !(thread && thread.thread_id),
47
+ });
48
+ const THREAD_RENAME_PROMPT = Object.freeze({
49
+ title: 'Rename thread',
50
+ placeholder: 'Thread name',
51
+ confirmText: 'Rename',
52
+ });
53
+ const THREAD_DELETE_CONFIRM = Object.freeze({
54
+ title: 'Delete thread',
55
+ message: title => `Are you sure you want to delete "${title || 'this thread'}"? This cannot be undone.`,
56
+ confirmText: 'Delete',
57
+ danger: true,
58
+ });
59
+
60
+ const SEARCH_BASED_LAYOUTS = {
61
+ ...BASE_LAYOUTS,
62
+ [ROLE.QUERY]: [LAYOUT_TYPE.SEARCH_BOX],
63
+ [ROLE.PRODUCTS]: [LAYOUT_TYPE.LIST, { incremental: true, infiniteScroll: true }],
64
+ [ROLE.KEYWORDS]: [LAYOUT_TYPE.TEXT, { raw: true }],
65
+ [ROLE.TOTAL]: [LAYOUT_TYPE.TEXT, { raw: true, templates: { content: totalContent } }],
66
+ [ROLE.FACETS]: [LAYOUT_TYPE.FACETS],
67
+ [ROLE.SORT]: [LAYOUT_TYPE.SELECT],
68
+ [ROLE.MORE]: [LAYOUT_TYPE.MORE_BUTTON],
69
+ };
70
+
71
+ export const defaultLayouts = Object.freeze({
72
+
73
+ 'ask': Object.freeze({
74
+ ...ANSWER_BASED_LAYOUTS,
75
+ [ROLE.QUERY]: [LAYOUT_TYPE.SEARCH_BOX, { templates: { buttonIcon: 'send' } }],
76
+ [ROLE.REASONING]: LAYOUT_TYPE.TYPEWRITER,
77
+ [ROLE.RELATED_RESOURCES]: [LAYOUT_TYPE.LIST, { incremental: true, itemType: 'article' }],
78
+ [ROLE.QUERY_SUGGESTIONS]: LAYOUT_TYPE.OPTION_LIST,
79
+ [ROLE.FOLLOW_UP_QUESTIONS]: LAYOUT_TYPE.OPTION_LIST,
80
+ }),
81
+
82
+ 'search': Object.freeze({
83
+ ...SEARCH_BASED_LAYOUTS,
84
+ }),
85
+
86
+ 'hybrid-search': Object.freeze({
87
+ ...ANSWER_BASED_LAYOUTS,
88
+ ...SEARCH_BASED_LAYOUTS,
89
+ [ROLE.QUERY]: [LAYOUT_TYPE.SEARCH_BOX, { placeholder: '' }],
90
+ [ROLE.QUESTION]: [LAYOUT_TYPE.TEXT, { raw: true }],
91
+ [ROLE.SOURCES]: [
92
+ LAYOUT_TYPE.HORIZONTAL,
93
+ {
94
+ incremental: true,
95
+ itemType: 'article',
96
+ templates: {
97
+ ordered: true,
98
+ article: compactArticle,
99
+ articleInfoBlock: compactArticleInfoBlock
100
+ }
101
+ }
102
+ ],
103
+ }),
104
+
105
+ 'recommendation': Object.freeze({
106
+ ...BASE_LAYOUTS,
107
+ [ROLE.PRODUCTS]: LAYOUT_TYPE.LIST,
108
+ }),
109
+
110
+ 'explore': Object.freeze({
111
+ ...BASE_LAYOUTS,
112
+ [ROLE.RELATED_QUESTIONS]: [LAYOUT_TYPE.LIST, { itemType: 'question', link: { rel: 'noopener nofollow' } }], // TODO: should define by useLink()
113
+ [ROLE.QUERY]: [LAYOUT_TYPE.SEARCH_BOX, { placeholder: 'Ask a question' }],
114
+ }),
115
+
116
+ // the thread list's own roles plus its thread item subworkflows' — the
117
+ // items share the history workflow's options, so one bag serves both.
118
+ // The item roles: the item-container layout (the standard container
119
+ // duties plus the items' context menus, driven by the item-menu
120
+ // data-role contract — it only ever drives its own item's menu, so
121
+ // hosting it on the panel is inert, and the panel never triggers the
122
+ // auto logo either, having no main-role component), the title text
123
+ // (with a presentation fallback for untitled threads), the context
124
+ // menu's rename (ask-then-submit through the prompt dialog) and delete
125
+ // (confirm-then-submit) buttons, and its subscription toggle — a menu
126
+ // item like the other two, so text only, labeled by the action a click
127
+ // takes rather than by the state
128
+ 'history': Object.freeze({
129
+ ...BASE_LAYOUTS,
130
+ [ROLE.CONTAINER]: [LAYOUT_TYPE.ITEM_CONTAINER, { logo: false }],
131
+ [ROLE.THREADS]: [LAYOUT_TYPE.THREADS, { itemType: 'thread', incremental: true, infiniteScroll: true }],
132
+ [ROLE.NEW_THREAD]: [LAYOUT_TYPE.BUTTON, { icon: 'plus', text: 'New chat' }],
133
+ [ROLE.TITLE]: [LAYOUT_TYPE.TEXT, { tag: 'div', templates: { content: (layout, { value }) => escapeHtml(value || 'Untitled') } }],
134
+ [ROLE.RENAME]: [LAYOUT_TYPE.BUTTON, { ...THREAD_CONTROL_OPTIONS, text: 'Rename', prompt: THREAD_RENAME_PROMPT }],
135
+ [ROLE.DELETE]: [LAYOUT_TYPE.BUTTON, { ...THREAD_CONTROL_OPTIONS, text: 'Delete', confirm: THREAD_DELETE_CONFIRM }],
136
+ [ROLE.SUBSCRIPTION]: [LAYOUT_TYPE.CHECKBOX, { text: 'Subscribe', checkedText: 'Unsubscribe' }],
137
+ }),
138
+
139
+ // the conversation panel's own roles plus its message item subworkflows'
140
+ // — the items share the conversation workflow's options, so one bag
141
+ // serves both. The message roles: the answer-based layouts minus the
142
+ // query role (a message has no query flow of its own; the query entry
143
+ // below is the panel's composer), with the question layout (text plus
144
+ // authorship attributes, off the whole record), the answer typewriter
145
+ // with `instant: true` (an already-finished answer renders in one shot),
146
+ // and the sources as the compact horizontal cards of the hybrid-search
147
+ // UI. logo: false turns the per-message banner off; the panel never
148
+ // triggers the auto logo anyway, having no main-role component
149
+ 'conversation': Object.freeze({
150
+ ...MESSAGE_LAYOUTS,
151
+ [ROLE.CONTAINER]: [LAYOUT_TYPE.CONTAINER, { logo: false }],
152
+ [ROLE.QUESTION]: LAYOUT_TYPE.QUESTION,
153
+ [ROLE.ANSWER]: [LAYOUT_TYPE.TYPEWRITER, { instant: true }],
154
+ [ROLE.SOURCES]: [
155
+ LAYOUT_TYPE.HORIZONTAL,
156
+ {
157
+ incremental: true,
158
+ itemType: 'article',
159
+ templates: {
160
+ ordered: true,
161
+ article: compactArticle,
162
+ articleInfoBlock: compactArticleInfoBlock
163
+ }
164
+ }
165
+ ],
166
+ [ROLE.MESSAGES]: [LAYOUT_TYPE.MESSAGES, { itemType: 'message', incremental: true, infiniteScroll: true }],
167
+ [ROLE.QUERY]: [LAYOUT_TYPE.SEARCH_BOX, { placeholder: 'Ask a follow-up question', clearOnSubmit: true, blurOnSubmit: false, disableWhenOngoing: true, templates: { buttonIcon: 'send' } }],
168
+ [ROLE.TITLE]: [LAYOUT_TYPE.TEXT, { tag: 'div' }],
169
+ [ROLE.RENAME]: [LAYOUT_TYPE.BUTTON, { ...THREAD_CONTROL_OPTIONS, icon: 'pencil', prompt: THREAD_RENAME_PROMPT }],
170
+ [ROLE.DELETE]: [LAYOUT_TYPE.BUTTON, { ...THREAD_CONTROL_OPTIONS, icon: 'trash', confirm: THREAD_DELETE_CONFIRM }],
171
+ [ROLE.SUBSCRIPTION]: [LAYOUT_TYPE.CHECKBOX, { icon: 'bell', text: 'Subscribe', checkedIcon: 'bell-fill', checkedText: 'Subscribed' }],
172
+ }),
173
+
174
+ });
@@ -1,5 +1,9 @@
1
1
  export { default as MisoAskElement } from './miso-ask.js';
2
2
  export { default as MisoExploreElement } from './miso-explore.js';
3
+ export { default as MisoHistoryElement } from './miso-history.js';
4
+ export { default as MisoConversationElement } from './miso-conversation.js';
5
+ export { default as MisoMessageItemElement } from './miso-message-item.js';
6
+ export { default as MisoThreadItemElement } from './miso-thread-item.js';
3
7
  export { default as MisoHybridSearchElement } from './miso-hybrid-search.js';
4
8
  export { default as MisoSearchElement } from './miso-search.js';
5
9
  export { default as MisoRecommendationElement } from './miso-recommendation.js';
@@ -22,13 +22,13 @@ export default class MisoAskElement extends MisoContainerElement {
22
22
 
23
23
  _getWorkflow(client) {
24
24
  if (this.boundToActiveWorkflow) {
25
- return client.ui.asks.active;
25
+ return client.workflows.asks.active;
26
26
  }
27
27
  return this._getWorkflowByParentQuestionId(client, this.parentQuestionId);
28
28
  }
29
29
 
30
30
  _getWorkflowByParentQuestionId(client, id) {
31
- return client.ui.asks.getByParentQuestionId(id, { autoCreate: true });
31
+ return client.workflows.asks.getByParentQuestionId(id, { autoCreate: true });
32
32
  }
33
33
 
34
34
  // properties //
@@ -66,7 +66,7 @@ export default class MisoAskElement extends MisoContainerElement {
66
66
  async connectedCallback() {
67
67
  await super.connectedCallback();
68
68
  if (document.body.contains(this)) { // in case already disconnected
69
- const context = this._client.ui.asks;
69
+ const context = this._client.workflows.asks;
70
70
  this._unsubscribes = [
71
71
  ...(this._unsubscribes || []),
72
72
  context.on('active', (event) => {
@@ -0,0 +1,19 @@
1
+ import MisoContainerElement from './miso-container.js';
2
+
3
+ const TAG_NAME = 'miso-conversation';
4
+
5
+ export default class MisoConversationElement extends MisoContainerElement {
6
+
7
+ static get tagName() {
8
+ return TAG_NAME;
9
+ }
10
+
11
+ static get observedAttributes() {
12
+ return MisoContainerElement.observedAttributes;
13
+ }
14
+
15
+ _getWorkflow(client) {
16
+ return client.workflows.conversation;
17
+ }
18
+
19
+ }
@@ -13,7 +13,7 @@ export default class MisoExploreElement extends MisoUnitElement {
13
13
  }
14
14
 
15
15
  _getWorkflowByUnitId(client, unitId) {
16
- return client.ui.explores.get(unitId);
16
+ return client.workflows.explores.get(unitId);
17
17
  }
18
18
 
19
19
  }
@@ -0,0 +1,19 @@
1
+ import MisoContainerElement from './miso-container.js';
2
+
3
+ const TAG_NAME = 'miso-history';
4
+
5
+ export default class MisoHistoryElement extends MisoContainerElement {
6
+
7
+ static get tagName() {
8
+ return TAG_NAME;
9
+ }
10
+
11
+ static get observedAttributes() {
12
+ return MisoContainerElement.observedAttributes;
13
+ }
14
+
15
+ _getWorkflow(client) {
16
+ return client.workflows.history;
17
+ }
18
+
19
+ }
@@ -13,7 +13,7 @@ export default class MisoHybridSearchElement extends MisoContainerElement {
13
13
  }
14
14
 
15
15
  _getWorkflow(client) {
16
- return client.ui.hybridSearch;
16
+ return client.workflows.hybridSearch;
17
17
  }
18
18
 
19
19
  }
@@ -0,0 +1,94 @@
1
+ import MisoContainerElement from './miso-container.js';
2
+ import { getContainer } from '../utils.js';
3
+
4
+ const TAG_NAME = 'miso-message-item';
5
+
6
+ const ATTR_QUESTION_ID = 'question-id';
7
+ const OBSERVED_ATTRIBUTES = Object.freeze([
8
+ ...MisoContainerElement.observedAttributes,
9
+ ATTR_QUESTION_ID,
10
+ ]);
11
+
12
+ /**
13
+ * A container element for one message (question-answer pair) of the
14
+ * conversation panel, placed inside <miso-conversation> — a container
15
+ * element inside another container element hosting an item subworkflow (the
16
+ * `message` workflow). Normally bound implicitly: the messages layout
17
+ * renders one <miso-message-item> per item and assigns the workflow off the item
18
+ * binding (element.workflow = parent workflow's _getMessageWorkflow(record)),
19
+ * which also covers a just-posted message that has no question id yet. A
20
+ * `question-id` attribute binds explicitly instead, through the parent
21
+ * container's workflow. Role elements inside (question, answer, sources,
22
+ * ...) bind to the message workflow as usual — getContainer() resolves to
23
+ * the closest container ancestor.
24
+ */
25
+ export default class MisoMessageItemElement extends MisoContainerElement {
26
+
27
+ static get tagName() {
28
+ return TAG_NAME;
29
+ }
30
+
31
+ static get observedAttributes() {
32
+ return OBSERVED_ATTRIBUTES;
33
+ }
34
+
35
+ // properties //
36
+ get questionId() {
37
+ return this.getAttribute(ATTR_QUESTION_ID) || undefined;
38
+ }
39
+
40
+ set questionId(value) {
41
+ value = value !== undefined ? `${value}` : undefined;
42
+ if (value === this.questionId) {
43
+ return;
44
+ }
45
+ if (value) {
46
+ this.setAttribute(ATTR_QUESTION_ID, value);
47
+ } else {
48
+ this.removeAttribute(ATTR_QUESTION_ID);
49
+ }
50
+ }
51
+
52
+ _getWorkflow(client) {
53
+ const { questionId } = this;
54
+ if (!questionId) {
55
+ // implicitly bound: the messages layout assigns element.workflow off
56
+ // the item binding — keep whatever is (or will be) assigned
57
+ return this._workflow;
58
+ }
59
+ const container = this._getParentContainer();
60
+ const workflow = container && container.workflow;
61
+ // the parent workflow hands out the item subworkflow; the parent binds
62
+ // its own workflow first (its connectedCallback resolves earlier), so
63
+ // it is normally present by now
64
+ return workflow && typeof workflow._getMessageWorkflow === 'function' ? workflow._getMessageWorkflow(questionId) : undefined;
65
+ }
66
+
67
+ _getParentContainer() {
68
+ try {
69
+ return this.parentNode ? getContainer(this.parentNode) : undefined;
70
+ } catch (_) {
71
+ return undefined; // not inside a container element
72
+ }
73
+ }
74
+
75
+ attributeChangedCallback(attr, oldValue, newValue) {
76
+ switch (attr) {
77
+ case ATTR_QUESTION_ID:
78
+ this._handleQuestionIdUpdate(oldValue, newValue);
79
+ break;
80
+ default:
81
+ super.attributeChangedCallback(attr, oldValue, newValue);
82
+ }
83
+ }
84
+
85
+ _handleQuestionIdUpdate(oldValue, newValue) {
86
+ oldValue = oldValue || undefined; // null -> undefined
87
+ newValue = newValue || undefined;
88
+ if (oldValue === newValue || !this._client) {
89
+ return;
90
+ }
91
+ this._setWorkflow(this._getWorkflow(this._client));
92
+ }
93
+
94
+ }
@@ -13,7 +13,7 @@ export default class MisoRecommendationElement extends MisoUnitElement {
13
13
  }
14
14
 
15
15
  _getWorkflowByUnitId(client, unitId) {
16
- return client.ui.recommendations.get(unitId);
16
+ return client.workflows.recommendations.get(unitId);
17
17
  }
18
18
 
19
19
  }
@@ -13,7 +13,7 @@ export default class MisoSearchElement extends MisoContainerElement {
13
13
  }
14
14
 
15
15
  _getWorkflow(client) {
16
- return client.ui.search;
16
+ return client.workflows.search;
17
17
  }
18
18
 
19
19
  }