@miso.ai/client-sdk-ui 1.9.8 → 1.9.9-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ class AskComboElements {
17
17
  (0, _commons.defineValues)(this, {
18
18
  root,
19
19
  followUpsSection: root.querySelector(`.${classPrefix}__follow-ups`),
20
+ relatedResourcesSection: root.querySelector(`.${classPrefix}__related-resources`),
20
21
  relatedResourcesContainer: root.querySelector(`.${classPrefix}__related-resources miso-ask`)
21
22
  });
22
23
  }
@@ -104,10 +104,15 @@ class AskCombo extends _base.default {
104
104
  }
105
105
  async _setupWorkflows() {
106
106
  const {
107
+ MisoClient,
107
108
  client,
108
109
  elements,
109
110
  resolvedOptions: options
110
111
  } = this;
112
+ const {
113
+ wireFollowUps,
114
+ wireRelatedResources
115
+ } = MisoClient.ui.defaults.ask;
111
116
  const {
112
117
  templates = {},
113
118
  features = {},
@@ -121,34 +126,13 @@ class AskCombo extends _base.default {
121
126
 
122
127
  // TODO: set placeholder if present in options
123
128
 
124
- if (elements.followUpsSection && features.followUpQuestions !== false) {
125
- // when a answer is fully populated, insert a new section for the follow-up question
126
- context.on('done', _ref => {
127
- let {
128
- workflow
129
- } = _ref;
130
- elements.followUpsSection.insertAdjacentHTML('beforeend', templates.followUp(Object.assign({}, options, {
131
- parentQuestionId: workflow.questionId
132
- })));
133
- });
134
- // if user starts over, clean up current follow-up questions
135
- rootWorkflow.on('loading', () => {
136
- // clean up the entire follow-ups section
137
- elements.followUpsSection.innerHTML = '';
138
- // destroy all follow-up workflows
139
- context.reset({
140
- root: false
141
- });
129
+ if (features.followUpQuestions !== false) {
130
+ wireFollowUps(client, elements.followUpsSection, {
131
+ template: templates.followUp
142
132
  });
143
133
  }
144
- if (elements.relatedResourcesContainer && features.relatedResources !== false && features.followUpQuestions !== false) {
145
- // when a new query starts, associate the last section container (for related resources) to that workflow
146
- context.on('loading', _ref2 => {
147
- let {
148
- workflow
149
- } = _ref2;
150
- elements.relatedResourcesContainer.workflow = workflow;
151
- });
134
+ if (features.relatedResources !== false && features.followUpQuestions !== false) {
135
+ wireRelatedResources(client, elements.relatedResourcesSection);
152
136
  }
153
137
 
154
138
  // start query if specified in URL
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.wireFollowUps = wireFollowUps;
7
+ exports.wireRelatedResources = wireRelatedResources;
8
+ var _templates = require("./templates.js");
9
+ function wireFollowUps(client, element) {
10
+ let {
11
+ template = _templates.followUp
12
+ } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
13
+ if (!client) {
14
+ throw new Error('client is required');
15
+ }
16
+ if (typeof template !== 'function') {
17
+ throw new Error('template must be a function or undefined');
18
+ }
19
+ if (!element) {
20
+ return;
21
+ }
22
+ const context = client.ui.asks;
23
+ const rootWorkflow = client.ui.ask;
24
+
25
+ // 1. when an answer is fully populated, insert a new section for the follow-up question
26
+ context.on('done', event => {
27
+ element.insertAdjacentHTML('beforeend', template({
28
+ parentQuestionId: event.workflow.questionId
29
+ }));
30
+ });
31
+ // 2. if user starts over, clean up existing follow-up questions
32
+ rootWorkflow.on('loading', () => {
33
+ // clean up the entire follow-ups section
34
+ element.innerHTML = '';
35
+ // destroy all follow-up workflows
36
+ context.reset({
37
+ root: false
38
+ });
39
+ });
40
+ }
41
+ function wireRelatedResources(client, element) {
42
+ if (!client) {
43
+ throw new Error('client is required');
44
+ }
45
+ if (!element) {
46
+ return;
47
+ }
48
+ client.ui.asks.on('loading', event => {
49
+ // When a new query starts, associate the last section container (for related resources) to that workflow
50
+ for (const container of element.querySelectorAll('miso-ask')) {
51
+ container.workflow = event.workflow;
52
+ }
53
+ });
54
+ }
@@ -3,10 +3,27 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ var _exportNames = {
7
+ constants: true,
8
+ phrases: true,
9
+ templates: true
10
+ };
6
11
  exports.templates = exports.phrases = exports.constants = void 0;
7
12
  var _constants = _interopRequireWildcard(require("./constants.js"));
8
13
  var _phrases = _interopRequireWildcard(require("./phrases.js"));
9
14
  var _templates = _interopRequireWildcard(require("./templates.js"));
15
+ var _controls = require("./controls.js");
16
+ Object.keys(_controls).forEach(function (key) {
17
+ if (key === "default" || key === "__esModule") return;
18
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
19
+ if (key in exports && exports[key] === _controls[key]) return;
20
+ Object.defineProperty(exports, key, {
21
+ enumerable: true,
22
+ get: function () {
23
+ return _controls[key];
24
+ }
25
+ });
26
+ });
10
27
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
28
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
29
  const constants = exports.constants = Object.freeze(_constants);
@@ -12,52 +12,53 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
12
12
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
13
13
  const TYPE = 'feedback';
14
14
  const DEFAULT_CLASSNAME = 'miso-feedback';
15
- function root(layout) {
16
- const {
17
- className,
18
- role,
19
- templates,
20
- options
21
- } = layout;
22
- const roleAttr = role ? `data-role="${role}"` : '';
23
- return `
24
- <div class="${className}" ${roleAttr}>
25
- ${options.options.map(option => templates.option(layout, option))}
26
- </div>
27
- `;
28
- }
29
- const OPTIONS = [{
30
- text: 'Helpful',
31
- value: 'helpful',
32
- icon: _svgs.THUMB
33
- }, {
34
- text: 'Not helpful',
35
- value: 'unhelpful',
36
- icon: _svgs.THUMB
37
- }];
15
+ const OPTIONS = ['helpful', 'unhelpful'];
38
16
  function options(layout) {
39
17
  const {
40
18
  templates
41
19
  } = layout;
42
- return OPTIONS.map(data => templates.option(layout, data)).join('');
20
+ return OPTIONS.map(value => templates.option(layout, {
21
+ value
22
+ })).join('');
43
23
  }
44
24
  function content(layout, _ref) {
45
25
  let {
46
- text,
47
- icon
26
+ value
48
27
  } = _ref;
49
28
  const {
50
29
  className,
30
+ templates,
51
31
  options = {}
52
32
  } = layout;
53
33
  return `
54
- ${options.icon !== false ? `<i class="${className}__icon">${icon}</i>` : ''}
55
- ${options.text !== false ? `<span class="${className}__text">${text}</span>` : ''}
34
+ ${options.icon !== false ? `<i class="${className}__icon">${templates.icon(layout, value)}</i>` : ''}
35
+ ${options.text !== false ? `<span class="${className}__text">${templates.text(layout, value)}</span>` : ''}
56
36
  `;
57
37
  }
38
+ function icon(layout, value) {
39
+ switch (value) {
40
+ case 'helpful':
41
+ case 'unhelpful':
42
+ return _svgs.THUMB;
43
+ default:
44
+ return '';
45
+ }
46
+ }
47
+ function text(layout, value) {
48
+ switch (value) {
49
+ case 'helpful':
50
+ return 'Helpful';
51
+ case 'unhelpful':
52
+ return 'Not helpful';
53
+ default:
54
+ return '';
55
+ }
56
+ }
58
57
  const DEFAULT_TEMPLATES = Object.freeze({
59
58
  options,
60
- content
59
+ content,
60
+ icon,
61
+ text
61
62
  });
62
63
  class FeedbackLayout extends _radio.default {
63
64
  static get category() {
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = exports.default = '1.9.8';
7
+ var _default = exports.default = '1.9.9-beta.0';
@@ -229,18 +229,6 @@ class Ask extends _base.default {
229
229
  })
230
230
  });
231
231
  }
232
- _onDataUpdate(data) {
233
- // TODO: can we just put this in _defaultProcessData?
234
- if (this._questionId) {
235
- return;
236
- }
237
- const questionId = data && data.value && data.value.question_id;
238
- // capture question ID and register at context
239
- if (questionId) {
240
- this._questionId = questionId;
241
- this._context._byQid.set(questionId, this);
242
- }
243
- }
244
232
  _onAnswerViewUpdate(_ref2) {
245
233
  let {
246
234
  session,
package/package.json CHANGED
@@ -26,7 +26,7 @@
26
26
  "url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
27
27
  },
28
28
  "dependencies": {
29
- "@miso.ai/commons": "1.9.8"
29
+ "@miso.ai/commons": "1.9.9-beta.0"
30
30
  },
31
- "version": "1.9.8"
31
+ "version": "1.9.9-beta.0"
32
32
  }
@@ -10,6 +10,7 @@ export default class AskComboElements {
10
10
  defineValues(this, {
11
11
  root,
12
12
  followUpsSection: root.querySelector(`.${classPrefix}__follow-ups`),
13
+ relatedResourcesSection: root.querySelector(`.${classPrefix}__related-resources`),
13
14
  relatedResourcesContainer: root.querySelector(`.${classPrefix}__related-resources miso-ask`),
14
15
  });
15
16
  }
@@ -98,7 +98,8 @@ export default class AskCombo extends Combo {
98
98
  }
99
99
 
100
100
  async _setupWorkflows() {
101
- const { client, elements, resolvedOptions: options } = this;
101
+ const { MisoClient, client, elements, resolvedOptions: options } = this;
102
+ const { wireFollowUps, wireRelatedResources } = MisoClient.ui.defaults.ask;
102
103
  const { templates = {}, features = {}, api } = options;
103
104
 
104
105
  const context = client.ui.asks;
@@ -110,25 +111,11 @@ export default class AskCombo extends Combo {
110
111
 
111
112
  // TODO: set placeholder if present in options
112
113
 
113
- if (elements.followUpsSection && features.followUpQuestions !== false) {
114
- // when a answer is fully populated, insert a new section for the follow-up question
115
- context.on('done', ({ workflow }) => {
116
- elements.followUpsSection.insertAdjacentHTML('beforeend', templates.followUp({ ...options, parentQuestionId: workflow.questionId }));
117
- });
118
- // if user starts over, clean up current follow-up questions
119
- rootWorkflow.on('loading', () => {
120
- // clean up the entire follow-ups section
121
- elements.followUpsSection.innerHTML = '';
122
- // destroy all follow-up workflows
123
- context.reset({ root: false });
124
- });
114
+ if (features.followUpQuestions !== false) {
115
+ wireFollowUps(client, elements.followUpsSection, { template: templates.followUp });
125
116
  }
126
-
127
- if (elements.relatedResourcesContainer && features.relatedResources !== false && features.followUpQuestions !== false) {
128
- // when a new query starts, associate the last section container (for related resources) to that workflow
129
- context.on('loading', ({ workflow }) => {
130
- elements.relatedResourcesContainer.workflow = workflow;
131
- });
117
+ if (features.relatedResources !== false && features.followUpQuestions !== false) {
118
+ wireRelatedResources(client, elements.relatedResourcesSection);
132
119
  }
133
120
 
134
121
  // start query if specified in URL
@@ -0,0 +1,42 @@
1
+ import { followUp as followUpTemplate } from './templates.js';
2
+
3
+ export function wireFollowUps(client, element, { template = followUpTemplate } = {}) {
4
+ if (!client) {
5
+ throw new Error('client is required');
6
+ }
7
+ if (typeof template !== 'function') {
8
+ throw new Error('template must be a function or undefined');
9
+ }
10
+ if (!element) {
11
+ return;
12
+ }
13
+ const context = client.ui.asks;
14
+ const rootWorkflow = client.ui.ask;
15
+
16
+ // 1. when an answer is fully populated, insert a new section for the follow-up question
17
+ context.on('done', (event) => {
18
+ element.insertAdjacentHTML('beforeend', template({ parentQuestionId: event.workflow.questionId }));
19
+ });
20
+ // 2. if user starts over, clean up existing follow-up questions
21
+ rootWorkflow.on('loading', () => {
22
+ // clean up the entire follow-ups section
23
+ element.innerHTML = '';
24
+ // destroy all follow-up workflows
25
+ context.reset({ root: false });
26
+ });
27
+ }
28
+
29
+ export function wireRelatedResources(client, element) {
30
+ if (!client) {
31
+ throw new Error('client is required');
32
+ }
33
+ if (!element) {
34
+ return;
35
+ }
36
+ client.ui.asks.on('loading', (event) => {
37
+ // When a new query starts, associate the last section container (for related resources) to that workflow
38
+ for (const container of element.querySelectorAll('miso-ask')) {
39
+ container.workflow = event.workflow;
40
+ }
41
+ });
42
+ }
@@ -2,6 +2,8 @@ import * as _constants from './constants.js';
2
2
  import * as _phrases from './phrases.js';
3
3
  import * as _templates from './templates.js';
4
4
 
5
+ export * from './controls.js';
6
+
5
7
  export const constants = Object.freeze(_constants);
6
8
  export const phrases = Object.freeze(_phrases);
7
9
  export const templates = Object.freeze(_templates);
@@ -5,45 +5,47 @@ import { THUMB } from '../svgs.js';
5
5
  const TYPE = 'feedback';
6
6
  const DEFAULT_CLASSNAME = 'miso-feedback';
7
7
 
8
- function root(layout) {
9
- const { className, role, templates, options } = layout;
10
- const roleAttr = role ? `data-role="${role}"` : '';
11
- return `
12
- <div class="${className}" ${roleAttr}>
13
- ${options.options.map((option) => templates.option(layout, option))}
14
- </div>
15
- `;
16
- }
17
-
18
- const OPTIONS = [
19
- {
20
- text: 'Helpful',
21
- value: 'helpful',
22
- icon: THUMB,
23
- },
24
- {
25
- text: 'Not helpful',
26
- value: 'unhelpful',
27
- icon: THUMB,
28
- },
29
- ];
8
+ const OPTIONS = [ 'helpful', 'unhelpful' ];
30
9
 
31
10
  function options(layout) {
32
11
  const { templates } = layout;
33
- return OPTIONS.map((data) => templates.option(layout, data)).join('');
12
+ return OPTIONS.map(value => templates.option(layout, { value })).join('');
34
13
  }
35
14
 
36
- function content(layout, { text, icon }) {
37
- const { className, options = {} } = layout;
15
+ function content(layout, { value }) {
16
+ const { className, templates, options = {} } = layout;
38
17
  return `
39
- ${options.icon !== false ? `<i class="${className}__icon">${icon}</i>` : ''}
40
- ${options.text !== false ? `<span class="${className}__text">${text}</span>` : ''}
18
+ ${options.icon !== false ? `<i class="${className}__icon">${templates.icon(layout, value)}</i>` : ''}
19
+ ${options.text !== false ? `<span class="${className}__text">${templates.text(layout, value)}</span>` : ''}
41
20
  `;
42
21
  }
43
22
 
23
+ function icon(layout, value) {
24
+ switch (value) {
25
+ case 'helpful':
26
+ case 'unhelpful':
27
+ return THUMB;
28
+ default:
29
+ return '';
30
+ }
31
+ }
32
+
33
+ function text(layout, value) {
34
+ switch (value) {
35
+ case 'helpful':
36
+ return 'Helpful';
37
+ case 'unhelpful':
38
+ return 'Not helpful';
39
+ default:
40
+ return '';
41
+ }
42
+ }
43
+
44
44
  const DEFAULT_TEMPLATES = Object.freeze({
45
45
  options,
46
46
  content,
47
+ icon,
48
+ text,
47
49
  });
48
50
 
49
51
  export default class FeedbackLayout extends RadioLayout {
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export default '1.9.8';
1
+ export default '1.9.9-beta.0';
@@ -190,19 +190,6 @@ export default class Ask extends Workflow {
190
190
  };
191
191
  }
192
192
 
193
- _onDataUpdate(data) {
194
- // TODO: can we just put this in _defaultProcessData?
195
- if (this._questionId) {
196
- return;
197
- }
198
- const questionId = data && data.value && data.value.question_id;
199
- // capture question ID and register at context
200
- if (questionId) {
201
- this._questionId = questionId;
202
- this._context._byQid.set(questionId, this);
203
- }
204
- }
205
-
206
193
  _onAnswerViewUpdate({ session, status, ongoing }) {
207
194
  if (status === STATUS.INITIAL) {
208
195
  return;