@miso.ai/client-sdk-ui 1.9.0-beta.9 → 1.9.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.
- package/dist/cjs/combo/ask/index.js +2 -0
- package/dist/cjs/combo/ask/options.js +32 -3
- package/dist/cjs/combo/ask/phrases.js +10 -0
- package/dist/cjs/combo/ask/templates.js +20 -19
- package/dist/cjs/plugin.js +6 -6
- package/dist/cjs/styles.js +77 -0
- package/dist/cjs/version.js +1 -1
- package/package.json +2 -2
- package/src/combo/ask/index.js +2 -0
- package/src/combo/ask/options.js +30 -1
- package/src/combo/ask/phrases.js +7 -0
- package/src/combo/ask/templates.js +16 -9
- package/src/plugin.js +8 -3
- package/src/styles.js +74 -0
- package/src/version.js +1 -1
|
@@ -115,6 +115,8 @@ class AskCombo extends _base.default {
|
|
|
115
115
|
const context = client.ui.asks;
|
|
116
116
|
const rootWorkflow = client.ui.ask;
|
|
117
117
|
|
|
118
|
+
// TODO: set placeholder is present in options
|
|
119
|
+
|
|
118
120
|
// when a answer is fully populated, insert a new section for the follow-up question
|
|
119
121
|
context.on('done', _ref => {
|
|
120
122
|
let {
|
|
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _commons = require("@miso.ai/commons");
|
|
8
8
|
var templates = _interopRequireWildcard(require("./templates.js"));
|
|
9
|
-
|
|
9
|
+
var phrases = _interopRequireWildcard(require("./phrases.js"));
|
|
10
|
+
const _excluded = ["api_key", "api_host", "templates", "phrases"];
|
|
10
11
|
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
12
|
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 && Object.prototype.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
13
|
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; }
|
|
@@ -17,6 +18,7 @@ const {
|
|
|
17
18
|
} = document;
|
|
18
19
|
const DEFAULT_OPTIONS = Object.freeze({
|
|
19
20
|
templates,
|
|
21
|
+
phrases,
|
|
20
22
|
autostart: true
|
|
21
23
|
});
|
|
22
24
|
class AskComboOptions {
|
|
@@ -51,12 +53,16 @@ function normalizeOptions() {
|
|
|
51
53
|
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
52
54
|
let {
|
|
53
55
|
api_key: apiKey,
|
|
54
|
-
api_host: apiHost
|
|
56
|
+
api_host: apiHost,
|
|
57
|
+
templates,
|
|
58
|
+
phrases
|
|
55
59
|
} = _ref,
|
|
56
60
|
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
57
61
|
return (0, _commons.trimObj)(Object.assign({
|
|
58
62
|
apiKey,
|
|
59
|
-
apiHost
|
|
63
|
+
apiHost,
|
|
64
|
+
templates: templateAsFunction(templates),
|
|
65
|
+
phrases: templateAsFunction(phrases)
|
|
60
66
|
}, options));
|
|
61
67
|
}
|
|
62
68
|
|
|
@@ -98,4 +104,27 @@ function readFromPageUrl() {
|
|
|
98
104
|
}
|
|
99
105
|
function coerceValue(value) {
|
|
100
106
|
return value === '' ? true : value === 'false' ? false : value;
|
|
107
|
+
}
|
|
108
|
+
function templateAsFunction(value) {
|
|
109
|
+
if (value === undefined || value === null) {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
switch (typeof value) {
|
|
113
|
+
case 'function':
|
|
114
|
+
return value;
|
|
115
|
+
case 'string':
|
|
116
|
+
case 'number':
|
|
117
|
+
return () => value;
|
|
118
|
+
case 'object':
|
|
119
|
+
return Array.isArray(value) ? value.map(templateAsFunction) : mappingObjectValues(value, templateAsFunction);
|
|
120
|
+
default:
|
|
121
|
+
throw new Error(`Unsupported template type: ${value}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function mappingObjectValues(obj, fn) {
|
|
125
|
+
const mapped = {};
|
|
126
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
127
|
+
mapped[key] = fn(value);
|
|
128
|
+
}
|
|
129
|
+
return mapped;
|
|
101
130
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sources = exports.relatedResources = exports.relatedQuestions = exports.question = void 0;
|
|
7
|
+
const question = exports.question = 'You asked...';
|
|
8
|
+
const sources = exports.sources = 'My reply is based on the following';
|
|
9
|
+
const relatedQuestions = exports.relatedQuestions = 'Related questions you can explore';
|
|
10
|
+
const relatedResources = exports.relatedResources = 'Go beyond, and learn more about this topic';
|
|
@@ -17,50 +17,50 @@ const root = options => `
|
|
|
17
17
|
<section class="${_constants.PREFIX}__section ${_constants.PREFIX}__answer">
|
|
18
18
|
${options.templates.answer(options)}
|
|
19
19
|
${options.templates.sources(options)}
|
|
20
|
+
<miso-ask class="${_constants.PREFIX}__bottom-spacing-container" visible-when="ongoing"></miso-ask>
|
|
20
21
|
</section>
|
|
21
22
|
<div id="${_constants.PREFIX}__follow-ups" class="${_constants.PREFIX}__follow-ups"></div>
|
|
22
23
|
<section id="${_constants.PREFIX}__related-resources" class="${_constants.PREFIX}__section ${_constants.PREFIX}__related-resources">
|
|
23
24
|
<miso-ask visible-when="nonempty" logo="true">
|
|
24
|
-
<h2 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-resources-phrase"
|
|
25
|
+
<h2 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-resources-phrase">${options.phrases.relatedResources(options)}</h2>
|
|
25
26
|
<miso-related-resources></miso-related-resources>
|
|
26
27
|
</miso-ask>
|
|
27
28
|
</section>
|
|
28
29
|
`.trim();
|
|
29
30
|
exports.root = root;
|
|
30
|
-
const followUp = (options
|
|
31
|
-
let {
|
|
31
|
+
const followUp = function (options) {
|
|
32
|
+
let session = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
33
|
+
const {
|
|
32
34
|
parentQuestionId
|
|
33
|
-
} =
|
|
35
|
+
} = session;
|
|
34
36
|
return `
|
|
35
37
|
<section class="${_constants.PREFIX}__section ${_constants.PREFIX}__follow-up">
|
|
36
38
|
<miso-ask class="${_constants.PREFIX}__query-suggestions-container" visible-when="initial+nonempty" parent-question-id="${parentQuestionId}">
|
|
37
|
-
<h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-questions-phrase"
|
|
39
|
+
<h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-questions-phrase">${options.phrases.relatedQuestions(options, session)}</h3>
|
|
38
40
|
<miso-query-suggestions></miso-query-suggestions>
|
|
39
41
|
</miso-ask>
|
|
40
42
|
<miso-ask class="${_constants.PREFIX}__query-container" visible-when="initial loading" parent-question-id="${parentQuestionId}">
|
|
41
43
|
<miso-query></miso-query>
|
|
42
44
|
</miso-ask>
|
|
43
|
-
${options.templates.answer(options,
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
${options.templates.sources(options, {
|
|
47
|
-
parentQuestionId
|
|
48
|
-
})}
|
|
45
|
+
${options.templates.answer(options, session)}
|
|
46
|
+
${options.templates.sources(options, session)}
|
|
47
|
+
<miso-ask class="${_constants.PREFIX}__bottom-spacing-container" visible-when="ongoing" parent-question-id="${parentQuestionId}"></miso-ask>
|
|
49
48
|
</section>
|
|
50
49
|
`.trim();
|
|
51
50
|
};
|
|
52
51
|
exports.followUp = followUp;
|
|
53
52
|
const answer = function (options) {
|
|
54
|
-
let {
|
|
55
|
-
parentQuestionId
|
|
56
|
-
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
53
|
+
let session = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
57
54
|
// TODO: include/omit miso-circled-citation-index by options
|
|
55
|
+
const {
|
|
56
|
+
parentQuestionId
|
|
57
|
+
} = session;
|
|
58
58
|
const openTag = `<miso-ask class="${_constants.PREFIX}__answer-container miso-circled-citation-index" visible-when="ready" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
|
|
59
59
|
const closeTag = '</miso-ask>';
|
|
60
60
|
return `
|
|
61
61
|
${openTag}
|
|
62
62
|
${parentQuestionId ? '<hr>' : ''}
|
|
63
|
-
<div class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__question-phrase"
|
|
63
|
+
<div class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__question-phrase">${options.phrases.question(options, session)}</div>
|
|
64
64
|
<miso-question></miso-question>
|
|
65
65
|
<miso-answer></miso-answer>
|
|
66
66
|
<miso-feedback></miso-feedback>
|
|
@@ -69,16 +69,17 @@ ${closeTag}
|
|
|
69
69
|
};
|
|
70
70
|
exports.answer = answer;
|
|
71
71
|
const sources = function (options) {
|
|
72
|
-
let {
|
|
73
|
-
parentQuestionId
|
|
74
|
-
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
72
|
+
let session = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
75
73
|
// TODO: include/omit miso-circled-citation-index by options
|
|
74
|
+
const {
|
|
75
|
+
parentQuestionId
|
|
76
|
+
} = session;
|
|
76
77
|
const openTag = `<miso-ask class="${_constants.PREFIX}__sources-container miso-circled-citation-index" visible-when="nonempty" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
|
|
77
78
|
const closeTag = '</miso-ask>';
|
|
78
79
|
return `
|
|
79
80
|
${openTag}
|
|
80
81
|
<hr>
|
|
81
|
-
<h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__sources-phrase"
|
|
82
|
+
<h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__sources-phrase">${options.phrases.sources(options, session)}</h3>
|
|
82
83
|
<miso-sources></miso-sources>
|
|
83
84
|
${closeTag}
|
|
84
85
|
`.trim();
|
package/dist/cjs/plugin.js
CHANGED
|
@@ -11,6 +11,7 @@ var _layouts = _interopRequireDefault(require("./layouts.js"));
|
|
|
11
11
|
var elements = _interopRequireWildcard(require("./element/index.js"));
|
|
12
12
|
var layouts = _interopRequireWildcard(require("./layout/index.js"));
|
|
13
13
|
var sources = _interopRequireWildcard(require("./source/index.js"));
|
|
14
|
+
var _styles = require("./styles.js");
|
|
14
15
|
var _misoContainer = _interopRequireDefault(require("./element/container/miso-container.js"));
|
|
15
16
|
var _misoCombo = _interopRequireDefault(require("./element/combo/miso-combo.js"));
|
|
16
17
|
const _excluded = ["containers", "roles", "combos"];
|
|
@@ -24,18 +25,13 @@ class UiPlugin extends _commons.Component {
|
|
|
24
25
|
return PLUGIN_ID;
|
|
25
26
|
}
|
|
26
27
|
constructor() {
|
|
27
|
-
let {
|
|
28
|
-
loadStyles = true
|
|
29
|
-
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
30
28
|
super('ui');
|
|
31
29
|
this.layouts = new _layouts.default(this);
|
|
32
30
|
this._recommendations = new WeakMap();
|
|
33
31
|
this._asks = new WeakMap();
|
|
34
32
|
this._extensions = new WeakMap();
|
|
35
|
-
// TODO: load CSS
|
|
36
33
|
}
|
|
37
|
-
|
|
38
|
-
install(MisoClient, context) {
|
|
34
|
+
async install(MisoClient, context) {
|
|
39
35
|
context.addSubtree(this);
|
|
40
36
|
MisoClient.on('create', this._injectClient.bind(this));
|
|
41
37
|
const ui = {};
|
|
@@ -75,6 +71,10 @@ class UiPlugin extends _commons.Component {
|
|
|
75
71
|
ElementClass.MisoClient = MisoClient; // TODO: find better way
|
|
76
72
|
}
|
|
77
73
|
|
|
74
|
+
// load styles
|
|
75
|
+
await (0, _styles.loadStylesIfNecessary)();
|
|
76
|
+
|
|
77
|
+
// define custom elements
|
|
78
78
|
for (const ElementClass of ElementClasses) {
|
|
79
79
|
(0, _commons.defineAndUpgrade)(ElementClass);
|
|
80
80
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.loadStyles = loadStyles;
|
|
7
|
+
exports.loadStylesIfNecessary = loadStylesIfNecessary;
|
|
8
|
+
var _version = _interopRequireDefault(require("./version.js"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const {
|
|
11
|
+
currentScript
|
|
12
|
+
} = document;
|
|
13
|
+
let cssUrl;
|
|
14
|
+
let stylesLoaded;
|
|
15
|
+
async function loadStylesIfNecessary() {
|
|
16
|
+
return stylesLoaded || (stylesLoaded = loadStyles());
|
|
17
|
+
}
|
|
18
|
+
async function loadStyles() {
|
|
19
|
+
try {
|
|
20
|
+
let link = getExistedLinkElement();
|
|
21
|
+
if (link) {
|
|
22
|
+
return waitForLinkLoaded(link);
|
|
23
|
+
}
|
|
24
|
+
link = document.createElement('link');
|
|
25
|
+
link.rel = 'stylesheet';
|
|
26
|
+
link.href = getCssUrl();
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
link.onload = resolve;
|
|
29
|
+
link.onerror = reject;
|
|
30
|
+
document.head.appendChild(link);
|
|
31
|
+
});
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error(e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// helpers //
|
|
38
|
+
function getCssUrl() {
|
|
39
|
+
return cssUrl || (cssUrl = resolveCssUrl());
|
|
40
|
+
}
|
|
41
|
+
function resolveCssUrl() {
|
|
42
|
+
// TODO: refactor with getPluginScriptUrl() in core
|
|
43
|
+
if (_version.default === 'dev') {
|
|
44
|
+
const src = currentScript.src;
|
|
45
|
+
const searchIndex = src.indexOf('?');
|
|
46
|
+
const k = searchIndex < 0 ? src.length : searchIndex;
|
|
47
|
+
const i = src.lastIndexOf('/', k); // .../dist/umd/*.min.js
|
|
48
|
+
return `${src.slice(0, i - 4)}/css/ui.css`;
|
|
49
|
+
} else {
|
|
50
|
+
return `https://cdn.jsdelivr.net/npm/@miso.ai/client-sdk@${_version.default}/dist/css/ui.css`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function getExistedLinkElement() {
|
|
54
|
+
return document.head.querySelector(`link[href="${getCssUrl()}"]`);
|
|
55
|
+
}
|
|
56
|
+
async function waitForLinkLoaded(element) {
|
|
57
|
+
if (element.sheet) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
let intervalId;
|
|
62
|
+
element.onload = () => {
|
|
63
|
+
intervalId && clearInterval(intervalId);
|
|
64
|
+
resolve();
|
|
65
|
+
};
|
|
66
|
+
element.onerror = () => {
|
|
67
|
+
intervalId && clearInterval(intervalId);
|
|
68
|
+
reject();
|
|
69
|
+
};
|
|
70
|
+
intervalId = setInterval(() => {
|
|
71
|
+
if (element.sheet) {
|
|
72
|
+
intervalId && clearInterval(intervalId);
|
|
73
|
+
resolve();
|
|
74
|
+
}
|
|
75
|
+
}, 100);
|
|
76
|
+
});
|
|
77
|
+
}
|
package/dist/cjs/version.js
CHANGED
package/package.json
CHANGED
package/src/combo/ask/index.js
CHANGED
|
@@ -105,6 +105,8 @@ export default class AskCombo extends Combo {
|
|
|
105
105
|
const context = client.ui.asks;
|
|
106
106
|
const rootWorkflow = client.ui.ask;
|
|
107
107
|
|
|
108
|
+
// TODO: set placeholder is present in options
|
|
109
|
+
|
|
108
110
|
// when a answer is fully populated, insert a new section for the follow-up question
|
|
109
111
|
context.on('done', ({ workflow }) => {
|
|
110
112
|
elements.followUpsSection.insertAdjacentHTML('beforeend', templates.followUp(options, { parentQuestionId: workflow.questionId }));
|
package/src/combo/ask/options.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { trimObj } from '@miso.ai/commons';
|
|
2
2
|
import * as templates from './templates.js';
|
|
3
|
+
import * as phrases from './phrases.js';
|
|
3
4
|
|
|
4
5
|
// TODO: generalize
|
|
5
6
|
|
|
@@ -7,6 +8,7 @@ const { currentScript } = document;
|
|
|
7
8
|
|
|
8
9
|
const DEFAULT_OPTIONS = Object.freeze({
|
|
9
10
|
templates,
|
|
11
|
+
phrases,
|
|
10
12
|
autostart: true,
|
|
11
13
|
});
|
|
12
14
|
|
|
@@ -41,10 +43,12 @@ function mergeTwoOptions(merged, overrides) {
|
|
|
41
43
|
});
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
function normalizeOptions({ api_key: apiKey, api_host: apiHost, ...options } = {}) {
|
|
46
|
+
function normalizeOptions({ api_key: apiKey, api_host: apiHost, templates, phrases, ...options } = {}) {
|
|
45
47
|
return trimObj({
|
|
46
48
|
apiKey,
|
|
47
49
|
apiHost,
|
|
50
|
+
templates: templateAsFunction(templates),
|
|
51
|
+
phrases: templateAsFunction(phrases),
|
|
48
52
|
...options,
|
|
49
53
|
});
|
|
50
54
|
}
|
|
@@ -90,3 +94,28 @@ function readFromPageUrl() {
|
|
|
90
94
|
function coerceValue(value) {
|
|
91
95
|
return value === '' ? true : value === 'false' ? false : value;
|
|
92
96
|
}
|
|
97
|
+
|
|
98
|
+
function templateAsFunction(value) {
|
|
99
|
+
if (value === undefined || value === null) {
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
switch (typeof value) {
|
|
103
|
+
case 'function':
|
|
104
|
+
return value;
|
|
105
|
+
case 'string':
|
|
106
|
+
case 'number':
|
|
107
|
+
return () => value;
|
|
108
|
+
case 'object':
|
|
109
|
+
return Array.isArray(value) ? value.map(templateAsFunction) : mappingObjectValues(value, templateAsFunction);
|
|
110
|
+
default:
|
|
111
|
+
throw new Error(`Unsupported template type: ${value}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function mappingObjectValues(obj, fn) {
|
|
116
|
+
const mapped = {};
|
|
117
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
118
|
+
mapped[key] = fn(value);
|
|
119
|
+
}
|
|
120
|
+
return mapped;
|
|
121
|
+
}
|
|
@@ -12,38 +12,44 @@ export const root = (options) => `
|
|
|
12
12
|
<section class="${PREFIX}__section ${PREFIX}__answer">
|
|
13
13
|
${options.templates.answer(options)}
|
|
14
14
|
${options.templates.sources(options)}
|
|
15
|
+
<miso-ask class="${PREFIX}__bottom-spacing-container" visible-when="ongoing"></miso-ask>
|
|
15
16
|
</section>
|
|
16
17
|
<div id="${PREFIX}__follow-ups" class="${PREFIX}__follow-ups"></div>
|
|
17
18
|
<section id="${PREFIX}__related-resources" class="${PREFIX}__section ${PREFIX}__related-resources">
|
|
18
19
|
<miso-ask visible-when="nonempty" logo="true">
|
|
19
|
-
<h2 class="${PREFIX}__phrase ${PREFIX}__related-resources-phrase"
|
|
20
|
+
<h2 class="${PREFIX}__phrase ${PREFIX}__related-resources-phrase">${options.phrases.relatedResources(options)}</h2>
|
|
20
21
|
<miso-related-resources></miso-related-resources>
|
|
21
22
|
</miso-ask>
|
|
22
23
|
</section>
|
|
23
24
|
`.trim();
|
|
24
25
|
|
|
25
|
-
export const followUp = (options,
|
|
26
|
+
export const followUp = (options, session = {}) => {
|
|
27
|
+
const { parentQuestionId } = session;
|
|
28
|
+
return `
|
|
26
29
|
<section class="${PREFIX}__section ${PREFIX}__follow-up">
|
|
27
30
|
<miso-ask class="${PREFIX}__query-suggestions-container" visible-when="initial+nonempty" parent-question-id="${parentQuestionId}">
|
|
28
|
-
<h3 class="${PREFIX}__phrase ${PREFIX}__related-questions-phrase"
|
|
31
|
+
<h3 class="${PREFIX}__phrase ${PREFIX}__related-questions-phrase">${options.phrases.relatedQuestions(options, session)}</h3>
|
|
29
32
|
<miso-query-suggestions></miso-query-suggestions>
|
|
30
33
|
</miso-ask>
|
|
31
34
|
<miso-ask class="${PREFIX}__query-container" visible-when="initial loading" parent-question-id="${parentQuestionId}">
|
|
32
35
|
<miso-query></miso-query>
|
|
33
36
|
</miso-ask>
|
|
34
|
-
${options.templates.answer(options,
|
|
35
|
-
${options.templates.sources(options,
|
|
37
|
+
${options.templates.answer(options, session)}
|
|
38
|
+
${options.templates.sources(options, session)}
|
|
39
|
+
<miso-ask class="${PREFIX}__bottom-spacing-container" visible-when="ongoing" parent-question-id="${parentQuestionId}"></miso-ask>
|
|
36
40
|
</section>
|
|
37
41
|
`.trim();
|
|
42
|
+
};
|
|
38
43
|
|
|
39
|
-
export const answer = (options,
|
|
44
|
+
export const answer = (options, session = {}) => {
|
|
40
45
|
// TODO: include/omit miso-circled-citation-index by options
|
|
46
|
+
const { parentQuestionId } = session;
|
|
41
47
|
const openTag = `<miso-ask class="${PREFIX}__answer-container miso-circled-citation-index" visible-when="ready" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
|
|
42
48
|
const closeTag = '</miso-ask>';
|
|
43
49
|
return `
|
|
44
50
|
${openTag}
|
|
45
51
|
${ parentQuestionId ? '<hr>' : '' }
|
|
46
|
-
<div class="${PREFIX}__phrase ${PREFIX}__question-phrase"
|
|
52
|
+
<div class="${PREFIX}__phrase ${PREFIX}__question-phrase">${options.phrases.question(options, session)}</div>
|
|
47
53
|
<miso-question></miso-question>
|
|
48
54
|
<miso-answer></miso-answer>
|
|
49
55
|
<miso-feedback></miso-feedback>
|
|
@@ -51,14 +57,15 @@ ${closeTag}
|
|
|
51
57
|
`.trim();
|
|
52
58
|
};
|
|
53
59
|
|
|
54
|
-
export const sources = (options,
|
|
60
|
+
export const sources = (options, session = {}) => {
|
|
55
61
|
// TODO: include/omit miso-circled-citation-index by options
|
|
62
|
+
const { parentQuestionId } = session;
|
|
56
63
|
const openTag = `<miso-ask class="${PREFIX}__sources-container miso-circled-citation-index" visible-when="nonempty" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
|
|
57
64
|
const closeTag = '</miso-ask>';
|
|
58
65
|
return `
|
|
59
66
|
${openTag}
|
|
60
67
|
<hr>
|
|
61
|
-
<h3 class="${PREFIX}__phrase ${PREFIX}__sources-phrase"
|
|
68
|
+
<h3 class="${PREFIX}__phrase ${PREFIX}__sources-phrase">${options.phrases.sources(options, session)}</h3>
|
|
62
69
|
<miso-sources></miso-sources>
|
|
63
70
|
${closeTag}
|
|
64
71
|
`.trim();
|
package/src/plugin.js
CHANGED
|
@@ -5,6 +5,7 @@ import Layouts from './layouts.js';
|
|
|
5
5
|
import * as elements from './element/index.js';
|
|
6
6
|
import * as layouts from './layout/index.js';
|
|
7
7
|
import * as sources from './source/index.js';
|
|
8
|
+
import { loadStylesIfNecessary } from './styles.js';
|
|
8
9
|
|
|
9
10
|
import MisoContainerElement from './element/container/miso-container.js';
|
|
10
11
|
import MisoComboElement from './element/combo/miso-combo.js';
|
|
@@ -17,16 +18,15 @@ export default class UiPlugin extends Component {
|
|
|
17
18
|
return PLUGIN_ID;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
constructor(
|
|
21
|
+
constructor() {
|
|
21
22
|
super('ui');
|
|
22
23
|
this.layouts = new Layouts(this);
|
|
23
24
|
this._recommendations = new WeakMap();
|
|
24
25
|
this._asks = new WeakMap();
|
|
25
26
|
this._extensions = new WeakMap();
|
|
26
|
-
// TODO: load CSS
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
install(MisoClient, context) {
|
|
29
|
+
async install(MisoClient, context) {
|
|
30
30
|
context.addSubtree(this);
|
|
31
31
|
MisoClient.on('create', this._injectClient.bind(this));
|
|
32
32
|
|
|
@@ -61,6 +61,11 @@ export default class UiPlugin extends Component {
|
|
|
61
61
|
for (const ElementClass of ElementClasses) {
|
|
62
62
|
ElementClass.MisoClient = MisoClient; // TODO: find better way
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
// load styles
|
|
66
|
+
await loadStylesIfNecessary();
|
|
67
|
+
|
|
68
|
+
// define custom elements
|
|
64
69
|
for (const ElementClass of ElementClasses) {
|
|
65
70
|
defineAndUpgrade(ElementClass);
|
|
66
71
|
}
|
package/src/styles.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import version from './version.js';
|
|
2
|
+
|
|
3
|
+
const { currentScript } = document;
|
|
4
|
+
|
|
5
|
+
let cssUrl;
|
|
6
|
+
let stylesLoaded;
|
|
7
|
+
|
|
8
|
+
export async function loadStylesIfNecessary() {
|
|
9
|
+
return stylesLoaded || (stylesLoaded = loadStyles());
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function loadStyles() {
|
|
13
|
+
try {
|
|
14
|
+
let link = getExistedLinkElement();
|
|
15
|
+
if (link) {
|
|
16
|
+
return waitForLinkLoaded(link)
|
|
17
|
+
}
|
|
18
|
+
link = document.createElement('link');
|
|
19
|
+
link.rel = 'stylesheet';
|
|
20
|
+
link.href = getCssUrl();
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
link.onload = resolve;
|
|
23
|
+
link.onerror = reject;
|
|
24
|
+
document.head.appendChild(link);
|
|
25
|
+
});
|
|
26
|
+
} catch(e) {
|
|
27
|
+
console.error(e);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// helpers //
|
|
32
|
+
function getCssUrl() {
|
|
33
|
+
return cssUrl || (cssUrl = resolveCssUrl());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resolveCssUrl() {
|
|
37
|
+
// TODO: refactor with getPluginScriptUrl() in core
|
|
38
|
+
if (version === 'dev') {
|
|
39
|
+
const src = currentScript.src;
|
|
40
|
+
const searchIndex = src.indexOf('?');
|
|
41
|
+
const k = searchIndex < 0 ? src.length : searchIndex;
|
|
42
|
+
const i = src.lastIndexOf('/', k); // .../dist/umd/*.min.js
|
|
43
|
+
return `${src.slice(0, i - 4)}/css/ui.css`;
|
|
44
|
+
} else {
|
|
45
|
+
return `https://cdn.jsdelivr.net/npm/@miso.ai/client-sdk@${version}/dist/css/ui.css`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getExistedLinkElement() {
|
|
50
|
+
return document.head.querySelector(`link[href="${getCssUrl()}"]`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function waitForLinkLoaded(element) {
|
|
54
|
+
if (element.sheet) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
let intervalId;
|
|
59
|
+
element.onload = () => {
|
|
60
|
+
intervalId && clearInterval(intervalId);
|
|
61
|
+
resolve();
|
|
62
|
+
};
|
|
63
|
+
element.onerror = () => {
|
|
64
|
+
intervalId && clearInterval(intervalId);
|
|
65
|
+
reject();
|
|
66
|
+
};
|
|
67
|
+
intervalId = setInterval(() => {
|
|
68
|
+
if (element.sheet) {
|
|
69
|
+
intervalId && clearInterval(intervalId);
|
|
70
|
+
resolve();
|
|
71
|
+
}
|
|
72
|
+
}, 100);
|
|
73
|
+
});
|
|
74
|
+
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.9.0
|
|
1
|
+
export default '1.9.0';
|