@miso.ai/client-sdk-ui 1.13.2-beta.0 → 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
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _clientSdkWorkflow = require("@miso.ai/client-sdk-workflow");
8
+ var _constants = require("../../constants.js");
9
+ var _collection = _interopRequireDefault(require("./collection.js"));
10
+ var _dom = require("../../util/dom.js");
11
+ var _confirm = _interopRequireDefault(require("../../util/confirm.js"));
12
+ var _prompt = _interopRequireDefault(require("../../util/prompt.js"));
13
+ const _excluded = ["className", "templates"];
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ 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; }
16
+ const TYPE = _constants.LAYOUT_TYPE.THREADS;
17
+ const DEFAULT_CLASSNAME = 'miso-threads';
18
+
19
+ // the thread template renders the <li> itself (it is the item, carrying the
20
+ // item role and state), so the stock <li> wrapping is skipped
21
+ function item(layout, state, value, index) {
22
+ const {
23
+ templates,
24
+ options
25
+ } = layout;
26
+ return templates[options.itemType](layout, state, value, {
27
+ index
28
+ });
29
+ }
30
+
31
+ /**
32
+ * The thread list of the chat history interface: a list of `thread` items.
33
+ *
34
+ * Selection comes with the data: the history workflow stamps
35
+ * `selectedThreadId` into its value and the role mapping decorates each
36
+ * thread record with a `selected` flag, so any selection change flows down
37
+ * the regular data path and refreshes the view. The list renders
38
+ * incrementally (append-only); in-place state changes on existing items
39
+ * (selected, unread) are applied by `_syncSelection` after each render,
40
+ * reading the fresh values off the item bindings — no item re-render needed.
41
+ *
42
+ * Each item carries a context menu (vertical dots) with thread actions,
43
+ * each asking through a shared modal dialog util, then emitting a view event
44
+ * for the history workflow to act on: `rename` (a prompt dialog pre-filled
45
+ * with the current title) and `delete` (a confirm dialog).
46
+ */
47
+ class ThreadsLayout extends _collection.default {
48
+ static get type() {
49
+ return TYPE;
50
+ }
51
+ static get defaultClassName() {
52
+ return DEFAULT_CLASSNAME;
53
+ }
54
+ constructor(_ref = {}) {
55
+ let {
56
+ className = DEFAULT_CLASSNAME,
57
+ templates
58
+ } = _ref,
59
+ options = _objectWithoutPropertiesLoose(_ref, _excluded);
60
+ super(Object.assign({
61
+ className,
62
+ templates: Object.assign({
63
+ item
64
+ }, templates)
65
+ }, options));
66
+ }
67
+ initialize(view) {
68
+ super.initialize(view);
69
+ // clicking outside the list closes any open context menu
70
+ if (typeof document !== 'undefined') {
71
+ const onDocumentClick = event => {
72
+ const element = this._element;
73
+ if (element && !element.contains(event.target)) {
74
+ this._closeMenus();
75
+ }
76
+ };
77
+ document.addEventListener('click', onDocumentClick);
78
+ this._unsubscribes.push(() => document.removeEventListener('click', onDocumentClick));
79
+ }
80
+ }
81
+
82
+ // the list is newest-first, so incremental renders PREPEND the fresh items
83
+ // (the collection layout's stock incremental mode is append-only)
84
+ _html(state, rendered, incremental) {
85
+ if (incremental) {
86
+ const values = this._getItems(state) || [];
87
+ const fresh = values.slice(0, values.length - rendered.value.length);
88
+ return fresh.length > 0 ? this.templates.items(this, state, fresh, {
89
+ offset: 0
90
+ }) : '';
91
+ }
92
+ return this.templates.root(this, state);
93
+ }
94
+ _render(element, {
95
+ state
96
+ }, {
97
+ notifyUpdate
98
+ }) {
99
+ const {
100
+ incremental,
101
+ html
102
+ } = state;
103
+ if (incremental) {
104
+ if (html) {
105
+ this._getListElement(element).insertAdjacentHTML('afterbegin', html);
106
+ } else {
107
+ notifyUpdate(false);
108
+ }
109
+ } else {
110
+ element.innerHTML = html;
111
+ }
112
+ }
113
+ _afterRender(element, state) {
114
+ super._afterRender(element, state); // syncs bindings to the latest values
115
+ this._syncItems(element);
116
+ }
117
+
118
+ // sync in-place item changes from the bound values onto the existing item
119
+ // elements: selection/unread state, and record changes that arrive without
120
+ // a re-render (rename, a placeholder thread resolving to its real record)
121
+ _syncItems(element) {
122
+ for (const item of this._getItemElements(element)) {
123
+ const binding = this._bindings.get(item);
124
+ if (!binding) {
125
+ continue;
126
+ }
127
+ const {
128
+ value
129
+ } = binding;
130
+ (0, _dom.setOrRemoveAttribute)(item, 'data-selected', value.selected ? '' : undefined);
131
+ (0, _dom.setOrRemoveAttribute)(item, 'data-unread', (0, _clientSdkWorkflow.isThreadUnread)(value) ? '' : undefined);
132
+ (0, _dom.setOrRemoveAttribute)(item, 'data-thread-id', (0, _clientSdkWorkflow.getThreadId)(value) || undefined);
133
+ const titleElement = item.querySelector(`.${this.className}__title`);
134
+ const title = value.title || 'Untitled';
135
+ if (titleElement && titleElement.textContent !== title) {
136
+ titleElement.textContent = title;
137
+ }
138
+ }
139
+ }
140
+
141
+ // a click on a thread item means selection — a navigation action, not a
142
+ // content-engagement click: emit a select view event and skip click tracking
143
+ _onClick(event) {
144
+ if (event.target.closest(`[data-role="thread-menu-button"]`)) {
145
+ this._toggleMenu(event.target.closest(`[data-role="item"]`));
146
+ return;
147
+ }
148
+ if (event.target.closest(`[data-role="thread-rename"]`)) {
149
+ this._closeMenus();
150
+ const binding = this._bindings.get(event.target.closest(`[data-role="item"]`));
151
+ binding && this._requestRename(binding);
152
+ return;
153
+ }
154
+ if (event.target.closest(`[data-role="thread-delete"]`)) {
155
+ this._closeMenus();
156
+ const binding = this._bindings.get(event.target.closest(`[data-role="item"]`));
157
+ binding && this._requestDelete(binding);
158
+ return;
159
+ }
160
+ if (event.target.closest(`[data-role="thread-menu"]`)) {
161
+ return; // other clicks inside the menu don't select
162
+ }
163
+ this._closeMenus();
164
+ const element = event.target.closest(`[data-role="item"]`);
165
+ if (!element) {
166
+ return;
167
+ }
168
+ const binding = this._bindings.get(element);
169
+ if (!binding) {
170
+ return;
171
+ }
172
+ const {
173
+ session
174
+ } = this._view._state;
175
+ const {
176
+ value
177
+ } = binding;
178
+ this._view._emit('select', {
179
+ session,
180
+ value,
181
+ element: binding.element,
182
+ domEvent: event
183
+ });
184
+ }
185
+
186
+ // context menu //
187
+ _toggleMenu(item) {
188
+ const menu = item && item.querySelector(`[data-role="thread-menu"]`);
189
+ if (!menu) {
190
+ return;
191
+ }
192
+ const open = menu.hidden;
193
+ this._closeMenus();
194
+ menu.hidden = !open;
195
+ }
196
+ _closeMenus() {
197
+ const element = this._element;
198
+ if (!element) {
199
+ return;
200
+ }
201
+ for (const menu of element.querySelectorAll(`[data-role="thread-menu"]:not([hidden])`)) {
202
+ menu.hidden = true;
203
+ }
204
+ }
205
+
206
+ // rename //
207
+ async _requestRename(binding) {
208
+ const {
209
+ value,
210
+ element
211
+ } = binding;
212
+ const title = await (0, _prompt.default)({
213
+ title: 'Rename thread',
214
+ value: value.title || '',
215
+ placeholder: 'Thread name',
216
+ confirmText: 'Rename'
217
+ });
218
+ if (!title || title === value.title) {
219
+ return; // cancelled, cleared, or unchanged
220
+ }
221
+ const {
222
+ session
223
+ } = this._view._state;
224
+ this._view._emit('rename', {
225
+ session,
226
+ value,
227
+ element,
228
+ title
229
+ });
230
+ }
231
+
232
+ // delete //
233
+ async _requestDelete(binding) {
234
+ const {
235
+ value,
236
+ element
237
+ } = binding;
238
+ const confirmed = await (0, _confirm.default)({
239
+ title: 'Delete thread',
240
+ message: `Are you sure you want to delete "${value.title || 'this thread'}"? This cannot be undone.`,
241
+ confirmText: 'Delete',
242
+ danger: true
243
+ });
244
+ if (!confirmed) {
245
+ return;
246
+ }
247
+ const {
248
+ session
249
+ } = this._view._state;
250
+ this._view._emit('delete', {
251
+ session,
252
+ value,
253
+ element
254
+ });
255
+ }
256
+ }
257
+ exports.default = ThreadsLayout;
@@ -8,7 +8,7 @@ exports.makeTrackable = makeTrackable;
8
8
  var _commons = require("@miso.ai/commons");
9
9
  var _bindings = _interopRequireDefault(require("../../util/bindings.js"));
10
10
  var _viewables = _interopRequireDefault(require("../../util/viewables.js"));
11
- var _trackers = require("../../util/trackers.js");
11
+ var _clientSdkWorkflow = require("@miso.ai/client-sdk-workflow");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  function makeTrackable(prototype) {
14
14
  (0, _commons.mixin)(prototype, TrackableMixin.prototype);
@@ -36,8 +36,7 @@ class TrackableMixin {
36
36
  this._onBindingsUpdate(bounds, unbounds);
37
37
  }
38
38
  _getItemKey(value) {
39
- // TODO: ad-hoc!
40
- return value.product_id || value.text || value.id || value;
39
+ return this._view.tracker.getItemKey(value);
41
40
  }
42
41
  _getItems(state) {
43
42
  throw new Error(`Not implemented.`);
@@ -92,8 +91,8 @@ class TrackableMixin {
92
91
  const {
93
92
  click: options
94
93
  } = this._view.tracker.options || {};
95
- if ((0, _trackers.validateClick)(options, event, binding)) {
96
- (0, _trackers.markAsTracked)(event);
94
+ if ((0, _clientSdkWorkflow.validateClick)(options, event, binding)) {
95
+ (0, _clientSdkWorkflow.markAsTracked)(event);
97
96
  this._view.tracker.click([binding.value]);
98
97
  }
99
98
  }
@@ -7,7 +7,7 @@ exports.TriggerableMixin = void 0;
7
7
  exports.makeTriggerable = makeTriggerable;
8
8
  var _commons = require("@miso.ai/commons");
9
9
  var _constants = require("../../constants.js");
10
- var _index = require("../../actor/index.js");
10
+ var _clientSdkWorkflow = require("@miso.ai/client-sdk-workflow");
11
11
  function makeTriggerable(prototype) {
12
12
  (0, _commons.mixin)(prototype, TriggerableMixin.prototype);
13
13
  }
@@ -63,7 +63,7 @@ class TriggerableMixin {
63
63
  }
64
64
  }
65
65
  _onTrigger() {
66
- this._view.hub.trigger(_index.fields.more());
66
+ this._view.hub.trigger(_clientSdkWorkflow.fields.more());
67
67
  }
68
68
  _untrackTrigger() {
69
69
  if (!this._trigger) {
@@ -4,13 +4,14 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _index = require("../../actor/index.js");
7
+ var _constants = require("../../constants.js");
8
+ var _clientSdkWorkflow = require("@miso.ai/client-sdk-workflow");
8
9
  var _radio = _interopRequireDefault(require("./radio.js"));
9
10
  var _svgs = require("../svgs.js");
10
11
  const _excluded = ["className", "templates"];
11
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
13
  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; }
13
- const TYPE = 'feedback';
14
+ const TYPE = _constants.LAYOUT_TYPE.FEEDBACK;
14
15
  const DEFAULT_CLASSNAME = 'miso-feedback';
15
16
  const OPTIONS = ['helpful', 'unhelpful'];
16
17
  function options(layout) {
@@ -78,7 +79,7 @@ class FeedbackLayout extends _radio.default {
78
79
  super(Object.assign({
79
80
  className,
80
81
  templates: Object.assign({}, DEFAULT_TEMPLATES, templates),
81
- field: _index.fields.feedback()
82
+ field: _clientSdkWorkflow.fields.feedback()
82
83
  }, options));
83
84
  if (options.text === false && options.icon === false) {
84
85
  throw new Error('At least one of options.text or options.icon must be enabled');
@@ -22,14 +22,22 @@ exports.image = image;
22
22
  exports.imageBlock = imageBlock;
23
23
  exports.imageInfoBlock = imageInfoBlock;
24
24
  exports.indexBlock = indexBlock;
25
+ exports.message = message;
26
+ exports.messageAnswerBlock = messageAnswerBlock;
27
+ exports.messageAuthor = messageAuthor;
28
+ exports.messageQuestionBlock = messageQuestionBlock;
25
29
  exports.priceBlock = priceBlock;
26
30
  exports.product = product;
27
31
  exports.productInfoBlock = productInfoBlock;
28
32
  exports.question = question;
29
33
  exports.requiresImplementation = requiresImplementation;
34
+ exports.thread = thread;
35
+ exports.threadMenuBlock = threadMenuBlock;
30
36
  exports.titleBlock = titleBlock;
31
37
  exports.unimplemented = unimplemented;
32
38
  var _commons = require("@miso.ai/commons");
39
+ var _clientSdkWorkflow = require("@miso.ai/client-sdk-workflow");
40
+ var _svgs = require("../asset/svgs.js");
33
41
  var _constants = require("../constants.js");
34
42
  const _excluded = ["classSuffix", "role"];
35
43
  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; }
@@ -55,6 +63,68 @@ function question(layout, state, data) {
55
63
  const [openTag, closeTag] = tagPair(layout, data);
56
64
  return `${openTag}${data.value || data.text || data}${closeTag}`;
57
65
  }
66
+
67
+ // the <li> itself is the item: it carries the item role, the thread identity
68
+ // and the item state — a thread item is not a link, so no anchor body (and
69
+ // the wrapper div around it) is needed
70
+ function thread(layout, state, data) {
71
+ const {
72
+ className,
73
+ templates
74
+ } = layout;
75
+ const threadId = (0, _clientSdkWorkflow.getThreadId)(data);
76
+ const threadIdAttr = threadId ? ` data-thread-id="${threadId}"` : '';
77
+ const unreadAttr = (0, _clientSdkWorkflow.isThreadUnread)(data) ? ' data-unread' : '';
78
+ const selectedAttr = data.selected ? ' data-selected' : '';
79
+ const title = (0, _commons.escapeHtml)(data.title || 'Untitled');
80
+ return `<li class="${className}__item" data-role="item"${threadIdAttr}${unreadAttr}${selectedAttr}><div class="${className}__title">${title}</div>${(templates.threadMenuBlock || threadMenuBlock)(layout, data)}</li>`;
81
+ }
82
+ function threadMenuBlock({
83
+ className
84
+ }) {
85
+ return `<button type="button" class="${className}__menu-button" data-role="thread-menu-button" aria-label="Thread actions" aria-haspopup="menu">${(0, _svgs.getIcon)('dots-vertical')}</button>` + `<div class="${className}__menu" data-role="thread-menu" role="menu" hidden>` + `<button type="button" class="${className}__menu-item" data-role="thread-rename" role="menuitem">Rename</button>` + `<button type="button" class="${className}__menu-item ${className}__menu-item--danger" data-role="thread-delete" role="menuitem">Delete</button>` + `</div>`;
86
+ }
87
+ function message(layout, state, data) {
88
+ const {
89
+ className,
90
+ templates
91
+ } = layout;
92
+ return [`<div class="${className}__item-body" data-role="item">`, (templates.messageQuestionBlock || messageQuestionBlock)(layout, data), (templates.messageAnswerBlock || messageAnswerBlock)(layout, data), `</div>`].join('');
93
+ }
94
+ function messageQuestionBlock({
95
+ className
96
+ }, message) {
97
+ const {
98
+ question
99
+ } = message;
100
+ const generatedBy = (0, _clientSdkWorkflow.getGeneratedBy)(message);
101
+ const author = messageAuthor(message);
102
+ // always rendered so it can be filled in place when the question text
103
+ // arrives later (the list renders incrementally); the authorship attrs
104
+ // drive the author label and the bubble color
105
+ const attrs = `${author ? ` data-author="${(0, _commons.escapeHtml)(author)}"` : ''}${generatedBy ? ` data-generated-by="${(0, _commons.escapeHtml)(generatedBy)}"` : ''}`;
106
+ return `<div class="${className}__question" data-role="question"${attrs}${question ? '' : ' hidden'}>${question ? (0, _commons.escapeHtml)(question) : ''}</div>`;
107
+ }
108
+
109
+ /**
110
+ * The author label of a message's question bubble: labeled only when the
111
+ * question was written by the answer-updates monitor — the user's own
112
+ * questions carry no label.
113
+ */
114
+ function messageAuthor(message) {
115
+ return (0, _clientSdkWorkflow.getGeneratedBy)(message) === 'answer_update_monitor' ? 'Written by Miso' : undefined;
116
+ }
117
+ function messageAnswerBlock({
118
+ className
119
+ }, {
120
+ answer
121
+ }) {
122
+ // the content is left blank here: the layout fills it in a second pass
123
+ // (markdown -> HTML); a spinner shows while the answer body is still
124
+ // being fetched from the answers API
125
+ const content = answer === undefined ? `<div class="miso-loading" aria-label="Loading" data-role="loading"></div>` : '';
126
+ return `<div class="${className}__answer miso-markdown miso-circled-citation-index" data-role="answer">${content}</div>`;
127
+ }
58
128
  function article(layout, state, data, meta) {
59
129
  const {
60
130
  templates
@@ -4,12 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _constants = require("../../constants.js");
7
8
  var _commons = require("@miso.ai/commons");
8
9
  var _template = _interopRequireDefault(require("../template.js"));
9
10
  const _excluded = ["className", "templates", "tag"];
10
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
12
  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; }
12
- const TYPE = 'text';
13
+ const TYPE = _constants.LAYOUT_TYPE.TEXT;
13
14
  const DEFAULT_CLASSNAME = 'miso-text';
14
15
  function root(layout, state) {
15
16
  const {
@@ -12,7 +12,7 @@ var _utils = require("./utils.js");
12
12
  const _excluded = ["className", "tag", "format", "tooltip", "speed", "acceleration", "nextCursorFn"];
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  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; }
15
- const TYPE = 'typewriter';
15
+ const TYPE = _constants.LAYOUT_TYPE.TYPEWRITER;
16
16
  const DEFAULT_CLASSNAME = 'miso-typewriter';
17
17
  class TypewriterLayout extends _progressive.default {
18
18
  static get type() {
@@ -72,10 +72,12 @@ class TypewriterLayout extends _progressive.default {
72
72
  }
73
73
  }
74
74
  async _setupForMarkdown() {
75
- const context = await this._view._views._extensions.require('markdown');
75
+ const client = this._view.workflow._client;
76
+ const plugin = await TypewriterLayout.MisoClient.plugins.install('std:ui-markdown');
76
77
  if (!this._view) {
77
78
  return; // destroyed
78
79
  }
80
+ const context = plugin.getContext(client);
79
81
  const cursorClass = (0, _utils.cursorClassName)(this.className);
80
82
  const {
81
83
  onDebug,
@@ -5,15 +5,18 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
- var _index = require("./workflow/index.js");
9
- var _index2 = require("./combo/index.js");
8
+ var _clientSdkWorkflow = require("@miso.ai/client-sdk-workflow");
9
+ var _defaults = require("./defaults.js");
10
+ var _index = require("./combo/index.js");
10
11
  var _layouts = _interopRequireDefault(require("./layouts.js"));
11
12
  var elements = _interopRequireWildcard(require("./element/index.js"));
12
13
  var layouts = _interopRequireWildcard(require("./layout/index.js"));
13
- var sources = _interopRequireWildcard(require("./source.js"));
14
14
  var defaults = _interopRequireWildcard(require("./defaults/index.js"));
15
+ var _templates = require("./defaults/ask/templates.js");
15
16
  var traits = _interopRequireWildcard(require("./trait/index.js"));
16
17
  var _styles = require("./styles.js");
18
+ var _confirm = _interopRequireDefault(require("./util/confirm.js"));
19
+ var _prompt = _interopRequireDefault(require("./util/prompt.js"));
17
20
  var _misoContainer = _interopRequireDefault(require("./element/container/miso-container.js"));
18
21
  var _misoContext = _interopRequireDefault(require("./element/context/miso-context.js"));
19
22
  var _misoCombo = _interopRequireDefault(require("./element/combo/miso-combo.js"));
@@ -29,23 +32,29 @@ class UiPlugin extends _commons.Component {
29
32
  constructor() {
30
33
  super('ui');
31
34
  this.layouts = new _layouts.default(this);
32
- this._recommendations = new WeakMap();
33
- this._explores = new WeakMap();
34
- this._asks = new WeakMap();
35
- this._extensions = new WeakMap();
36
35
  this._ready = new _commons.Resolution();
37
36
  }
38
- async install(MisoClient, {
39
- addSubtree,
40
- addExtensionPoints
41
- }) {
37
+ async install(MisoClient, context) {
38
+ const {
39
+ addSubtree,
40
+ addExtensionPoints
41
+ } = context;
42
+ this._pluginContext = context;
42
43
  addSubtree(this);
44
+
45
+ // make sure the workflow plugin is installed, then provide the layout
46
+ // registry and seed the default layout options
47
+ MisoClient.plugins.use(_clientSdkWorkflow.WorkflowPlugin);
48
+ context.workflows.plugin.setLayouts(this.layouts);
49
+ this._seedWorkflowDefaults(context.workflows.defaults);
43
50
  MisoClient.on('create', this._injectClient.bind(this));
44
51
 
45
52
  // the UI interface for MisoClient
46
53
  const ui = {
47
54
  defaults,
48
- traits
55
+ traits,
56
+ confirm: _confirm.default,
57
+ prompt: _prompt.default
49
58
  };
50
59
  (0, _commons.delegateGetters)(ui, this, ['layouts', 'ready']);
51
60
  (0, _commons.defineValues)(this, {
@@ -96,70 +105,33 @@ class UiPlugin extends _commons.Component {
96
105
  await (0, _styles.loadStylesIfNecessary)();
97
106
  this._ready.resolve();
98
107
  }
99
- async requireExtension(name) {
100
- switch (name) {
101
- case 'markdown':
102
- return await this.MisoClient.plugins.install('std:ui-markdown');
103
- default:
104
- throw new Error(`Unknown extension: ${name}`);
105
- }
106
- }
107
108
  get ready() {
108
109
  return this._ready.promise;
109
110
  }
111
+
112
+ /**
113
+ * Seed the workflow plugin's defaults store with the presentational default
114
+ * options: layouts of each workflow, plus UI templates.
115
+ */
116
+ _seedWorkflowDefaults(workflowDefaults) {
117
+ for (const [name, layouts] of Object.entries(_defaults.defaultLayouts)) {
118
+ workflowDefaults.set(name, {
119
+ layouts
120
+ });
121
+ }
122
+ workflowDefaults.set('ask', {
123
+ templates: {
124
+ followUp: _templates.followUp
125
+ }
126
+ });
127
+ }
110
128
  _injectClient(client) {
111
129
  (0, _commons.defineValues)(client, {
112
130
  ui: new Ui(this, client)
113
131
  });
114
132
  }
115
- _getExtensions(client) {
116
- if (this._extensions.has(client)) {
117
- return this._extensions.get(client);
118
- }
119
- const extensions = new Extensions(this, client);
120
- this._extensions.set(client, extensions);
121
- return extensions;
122
- }
123
- _getRecommendations(client) {
124
- let recommendations = this._recommendations.get(client);
125
- if (!recommendations) {
126
- this._recommendations.set(client, recommendations = new _index.Recommendations(this, client));
127
- }
128
- return recommendations;
129
- }
130
- _getExplores(client) {
131
- let explores = this._explores.get(client);
132
- if (!explores) {
133
- this._explores.set(client, explores = new _index.Explores(this, client));
134
- }
135
- return explores;
136
- }
137
- _getAsks(client) {
138
- let asks = this._asks.get(client);
139
- if (!asks) {
140
- this._asks.set(client, asks = new _index.Asks(this, client));
141
- }
142
- return asks;
143
- }
144
133
  }
145
-
146
- // TODO: are we able to eliminate the concept of extension, just use plugins?
147
134
  exports.default = UiPlugin;
148
- class Extensions {
149
- constructor(plugin, client) {
150
- this._plugin = plugin;
151
- this._client = client;
152
- this._contexts = {};
153
- }
154
- async require(name) {
155
- if (this._contexts[name]) {
156
- return this._contexts[name];
157
- }
158
- const plugin = await this._plugin.requireExtension(name);
159
- const context = this._contexts[name] = plugin.getContext(this._client);
160
- return context;
161
- }
162
- }
163
135
  function createUiPluginContext(plugin, ui, MisoClient) {
164
136
  async function addElementClasses(...ElementClasses) {
165
137
  for (const ElementClass of ElementClasses) {
@@ -187,6 +159,9 @@ function createUiPluginContext(plugin, ui, MisoClient) {
187
159
  };
188
160
  }
189
161
 
162
+ // workflow accessors delegated to client.workflows for backward compatibility
163
+ const WORKFLOW_ACCESSORS = ['search', 'hybridSearch', 'asks', 'ask', 'explores', 'explore', 'recommendations', 'recommendation', 'sources'];
164
+
190
165
  /**
191
166
  * The UI interface for the client.
192
167
  */
@@ -194,43 +169,7 @@ class Ui {
194
169
  constructor(plugin, client) {
195
170
  this._plugin = plugin;
196
171
  this._client = client;
197
- (0, _commons.defineValues)(this, {
198
- sources: {
199
- api: sources.api(client)
200
- }
201
- });
202
- }
203
- get recommendations() {
204
- return this._recommendations || (this._recommendations = this._plugin._getRecommendations(this._client));
205
- }
206
- get recommendation() {
207
- return this.recommendations.get(); // get default recommendation unit
208
- }
209
- get search() {
210
- if (!this._search) {
211
- this._search = new _index.Search(this._plugin, this._client);
212
- this._client._events.emit('postworkflow', this._search);
213
- }
214
- return this._search;
215
- }
216
- get asks() {
217
- return this._asks || (this._asks = this._plugin._getAsks(this._client));
218
- }
219
- get ask() {
220
- return this.asks.root;
221
- }
222
- get hybridSearch() {
223
- if (!this._hybridSearch) {
224
- this._hybridSearch = new _index.HybridSearch(this._plugin, this._client);
225
- this._client._events.emit('postworkflow', this._hybridSearch);
226
- }
227
- return this._hybridSearch;
228
- }
229
- get explores() {
230
- return this._explores || (this._explores = this._plugin._getExplores(this._client));
231
- }
232
- get explore() {
233
- return this.explores.get(); // get default explore unit
172
+ (0, _commons.delegateGetters)(this, client.workflows, WORKFLOW_ACCESSORS);
234
173
  }
235
174
  get ready() {
236
175
  return this._plugin.ready;
@@ -242,6 +181,6 @@ class Combo {
242
181
  this._MisoClient = MisoClient;
243
182
  }
244
183
  get ask() {
245
- return this._ask || (this._ask = new _index2.AskCombo(this._plugin, this._MisoClient));
184
+ return this._ask || (this._ask = new _index.AskCombo(this._plugin, this._MisoClient));
246
185
  }
247
186
  }