@miso.ai/client-sdk-ui 1.9.0-beta.9 → 1.9.1-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.
- package/dist/cjs/actor/views.js +1 -1
- package/dist/cjs/combo/ask/elements.js +0 -7
- package/dist/cjs/combo/ask/index.js +5 -21
- package/dist/cjs/combo/ask/options.js +32 -7
- package/dist/cjs/defaults/ask/constants.js +7 -0
- package/dist/cjs/defaults/ask/index.js +14 -0
- package/dist/cjs/defaults/ask/phrases.js +25 -0
- package/dist/cjs/defaults/ask/templates.js +128 -0
- package/dist/cjs/defaults/index.js +10 -0
- package/dist/cjs/layout/input/search-box.js +49 -0
- package/dist/cjs/plugin.js +19 -14
- package/dist/cjs/styles.js +97 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/ask.js +23 -0
- package/dist/cjs/workflow/base.js +3 -0
- package/dist/cjs/workflow/search.js +23 -0
- package/package.json +2 -2
- package/src/actor/views.js +1 -1
- package/src/combo/ask/elements.js +0 -8
- package/src/combo/ask/index.js +4 -16
- package/src/combo/ask/options.js +29 -2
- package/src/defaults/ask/constants.js +1 -0
- package/src/defaults/ask/index.js +7 -0
- package/src/defaults/ask/phrases.js +19 -0
- package/src/defaults/ask/templates.js +107 -0
- package/src/defaults/index.js +3 -0
- package/src/layout/input/search-box.js +51 -0
- package/src/plugin.js +24 -10
- package/src/styles.js +97 -0
- package/src/version.js +1 -1
- package/src/workflow/ask.js +16 -0
- package/src/workflow/base.js +4 -0
- package/src/workflow/search.js +16 -0
- package/dist/cjs/combo/ask/templates.js +0 -86
- package/src/combo/ask/templates.js +0 -65
package/package.json
CHANGED
package/src/actor/views.js
CHANGED
|
@@ -9,14 +9,10 @@ export default class AskComboElements {
|
|
|
9
9
|
}
|
|
10
10
|
defineValues(this, {
|
|
11
11
|
root,
|
|
12
|
-
rootQuery: root.querySelector(`#${PREFIX}__question miso-query`),
|
|
13
12
|
followUpsSection: root.querySelector(`#${PREFIX}__follow-ups`),
|
|
14
13
|
relatedResourcesContainer: root.querySelector(`#${PREFIX}__related-resources miso-ask`),
|
|
15
14
|
});
|
|
16
15
|
|
|
17
|
-
if (!this.rootQuery) {
|
|
18
|
-
throw new Error(`Root question query element not found.`);
|
|
19
|
-
}
|
|
20
16
|
if (!this.followUpsSection) {
|
|
21
17
|
throw new Error(`Follow-ups section element not found.`);
|
|
22
18
|
}
|
|
@@ -25,8 +21,4 @@ export default class AskComboElements {
|
|
|
25
21
|
}
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
get rootInput() {
|
|
29
|
-
return this.rootQuery.querySelector(`[data-role="input"]`);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
24
|
}
|
package/src/combo/ask/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { defineValues, waitForDomContentLoaded } from '@miso.ai/commons';
|
|
2
|
-
import { fields } from '../../actor/index.js';
|
|
3
|
-
import { ROLE } from '../../constants.js';
|
|
4
2
|
import Combo from '../base.js';
|
|
5
3
|
import AskComboOptions from './options.js';
|
|
6
4
|
import AskComboElements from './elements.js';
|
|
@@ -105,9 +103,11 @@ export default class AskCombo extends Combo {
|
|
|
105
103
|
const context = client.ui.asks;
|
|
106
104
|
const rootWorkflow = client.ui.ask;
|
|
107
105
|
|
|
106
|
+
// TODO: set placeholder is present in options
|
|
107
|
+
|
|
108
108
|
// when a answer is fully populated, insert a new section for the follow-up question
|
|
109
109
|
context.on('done', ({ workflow }) => {
|
|
110
|
-
elements.followUpsSection.insertAdjacentHTML('beforeend', templates.followUp(options,
|
|
110
|
+
elements.followUpsSection.insertAdjacentHTML('beforeend', templates.followUp({ ...options, parentQuestionId: workflow.questionId }));
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
// when a new query starts, associate the last section container (for related resources) to that workflow
|
|
@@ -123,20 +123,8 @@ export default class AskCombo extends Combo {
|
|
|
123
123
|
context.reset({ root: false });
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
-
// wait for miso-query content to be populated
|
|
127
|
-
const QUERY = fields.view(ROLE.QUERY);
|
|
128
|
-
if (!rootWorkflow.states[QUERY]) {
|
|
129
|
-
await rootWorkflow._hub.once(QUERY);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
126
|
// start query if specified in URL
|
|
133
|
-
|
|
134
|
-
if (q) {
|
|
135
|
-
elements.rootInput.value = q;
|
|
136
|
-
rootWorkflow.query({ q });
|
|
137
|
-
} else {
|
|
138
|
-
elements.rootInput.focus();
|
|
139
|
-
}
|
|
127
|
+
rootWorkflow.autoQuery();
|
|
140
128
|
}
|
|
141
129
|
|
|
142
130
|
}
|
package/src/combo/ask/options.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { trimObj } from '@miso.ai/commons';
|
|
2
|
-
import
|
|
2
|
+
import { templates } from '../../defaults/ask/index.js';
|
|
3
3
|
|
|
4
4
|
// TODO: generalize
|
|
5
5
|
|
|
@@ -41,10 +41,12 @@ function mergeTwoOptions(merged, overrides) {
|
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function normalizeOptions({ api_key: apiKey, api_host: apiHost, ...options } = {}) {
|
|
44
|
+
function normalizeOptions({ api_key: apiKey, api_host: apiHost, templates, phrases, ...options } = {}) {
|
|
45
45
|
return trimObj({
|
|
46
46
|
apiKey,
|
|
47
47
|
apiHost,
|
|
48
|
+
templates: templateAsFunction(templates),
|
|
49
|
+
phrases,
|
|
48
50
|
...options,
|
|
49
51
|
});
|
|
50
52
|
}
|
|
@@ -90,3 +92,28 @@ function readFromPageUrl() {
|
|
|
90
92
|
function coerceValue(value) {
|
|
91
93
|
return value === '' ? true : value === 'false' ? false : value;
|
|
92
94
|
}
|
|
95
|
+
|
|
96
|
+
function templateAsFunction(value) {
|
|
97
|
+
if (value === undefined || value === null) {
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
switch (typeof value) {
|
|
101
|
+
case 'function':
|
|
102
|
+
return value;
|
|
103
|
+
case 'string':
|
|
104
|
+
case 'number':
|
|
105
|
+
return () => value;
|
|
106
|
+
case 'object':
|
|
107
|
+
return Array.isArray(value) ? value.map(templateAsFunction) : mappingObjectValues(value, templateAsFunction);
|
|
108
|
+
default:
|
|
109
|
+
throw new Error(`Unsupported template type: ${value}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function mappingObjectValues(obj, fn) {
|
|
114
|
+
const mapped = {};
|
|
115
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
116
|
+
mapped[key] = fn(value);
|
|
117
|
+
}
|
|
118
|
+
return mapped;
|
|
119
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CLASS_PREFIX = 'miso-ask-combo';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as _constants from './constants.js';
|
|
2
|
+
import * as _phrases from './phrases.js';
|
|
3
|
+
import * as _templates from './templates.js';
|
|
4
|
+
|
|
5
|
+
export const constants = Object.freeze(_constants);
|
|
6
|
+
export const phrases = Object.freeze(_phrases);
|
|
7
|
+
export const templates = Object.freeze(_templates);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The phrase displayed right before <miso-question>
|
|
3
|
+
*/
|
|
4
|
+
export const question = 'You asked...';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The phrase displayed right before <miso-sources>
|
|
8
|
+
*/
|
|
9
|
+
export const sources = 'My reply is based on the following';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The phrase displayed right before <miso-query-suggestions>
|
|
13
|
+
*/
|
|
14
|
+
export const relatedQuestions = 'Related questions you can explore';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The phrase displayed right before <miso-related-resources>
|
|
18
|
+
*/
|
|
19
|
+
export const relatedResources = 'Go beyond, and learn more about this topic';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { CLASS_PREFIX } from './constants.js';
|
|
2
|
+
import * as DEFAULT_PHRASES from './phrases.js';
|
|
3
|
+
|
|
4
|
+
// TODO: refactor
|
|
5
|
+
// TODO: make ids constants
|
|
6
|
+
// TODO: placeholder
|
|
7
|
+
|
|
8
|
+
export function root(options = {}) {
|
|
9
|
+
const { classPrefix = CLASS_PREFIX } = options;
|
|
10
|
+
return `
|
|
11
|
+
<section id="${classPrefix}__question" class="${classPrefix}__section ${classPrefix}__question">
|
|
12
|
+
<miso-ask class="${classPrefix}__query-container">
|
|
13
|
+
<miso-query></miso-query>
|
|
14
|
+
</miso-ask>
|
|
15
|
+
</section>
|
|
16
|
+
<section class="${classPrefix}__section ${classPrefix}__answer">
|
|
17
|
+
${answer(options)}
|
|
18
|
+
${sources(options)}
|
|
19
|
+
<miso-ask class="${classPrefix}__bottom-spacing-container" visible-when="ongoing"></miso-ask>
|
|
20
|
+
</section>
|
|
21
|
+
<div id="${classPrefix}__follow-ups" class="${classPrefix}__follow-ups"></div>
|
|
22
|
+
<section id="${classPrefix}__related-resources" class="${classPrefix}__section ${classPrefix}__related-resources">
|
|
23
|
+
<miso-ask visible-when="nonempty" logo="true">
|
|
24
|
+
<h2 class="${classPrefix}__phrase ${classPrefix}__related-resources-phrase">${phraseText(options, 'relatedResources')}</h2>
|
|
25
|
+
<miso-related-resources></miso-related-resources>
|
|
26
|
+
</miso-ask>
|
|
27
|
+
</section>`.trim();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function followUp(options = {}) {
|
|
31
|
+
const { classPrefix = CLASS_PREFIX, parentQuestionId } = options;
|
|
32
|
+
return `
|
|
33
|
+
<section class="${classPrefix}__section ${classPrefix}__follow-up">
|
|
34
|
+
<miso-ask class="${classPrefix}__query-suggestions-container" visible-when="initial+nonempty" parent-question-id="${parentQuestionId}">
|
|
35
|
+
<h3 class="${classPrefix}__phrase ${classPrefix}__related-questions-phrase">${phraseText(options, 'relatedQuestions')}</h3>
|
|
36
|
+
<miso-query-suggestions></miso-query-suggestions>
|
|
37
|
+
</miso-ask>
|
|
38
|
+
<miso-ask class="${classPrefix}__query-container" visible-when="initial loading" parent-question-id="${parentQuestionId}">
|
|
39
|
+
<miso-query></miso-query>
|
|
40
|
+
</miso-ask>
|
|
41
|
+
${answer(options)}
|
|
42
|
+
${sources(options)}
|
|
43
|
+
<miso-ask class="${classPrefix}__bottom-spacing-container" visible-when="ongoing" parent-question-id="${parentQuestionId}"></miso-ask>
|
|
44
|
+
</section>`.trim();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
// helpers //
|
|
50
|
+
function answer(options) {
|
|
51
|
+
const { classPrefix = CLASS_PREFIX } = options;
|
|
52
|
+
return `
|
|
53
|
+
${containerOpenTag('answer', { ...options, visibleWhen: 'ready' })}
|
|
54
|
+
${ options.parentQuestionId ? '<hr>' : '' }
|
|
55
|
+
<div class="${classPrefix}__phrase ${classPrefix}__question-phrase">${phraseText(options, 'question')}</div>
|
|
56
|
+
<miso-question></miso-question>
|
|
57
|
+
<miso-answer></miso-answer>
|
|
58
|
+
<miso-feedback></miso-feedback>
|
|
59
|
+
</miso-ask>`.trim();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function sources(options) {
|
|
63
|
+
const { classPrefix = CLASS_PREFIX } = options;
|
|
64
|
+
return `
|
|
65
|
+
${containerOpenTag('sources', { ...options, visibleWhen: 'nonempty' })}
|
|
66
|
+
<hr>
|
|
67
|
+
<h3 class="${classPrefix}__phrase ${classPrefix}__sources-phrase">${phraseText(options, 'sources')}</h3>
|
|
68
|
+
<miso-sources></miso-sources>
|
|
69
|
+
</miso-ask>`.trim();
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function phraseText(options, key) {
|
|
73
|
+
const { phrases = {} } = options;
|
|
74
|
+
const fn = phrases[key] || DEFAULT_PHRASES[key];
|
|
75
|
+
switch (typeof fn) {
|
|
76
|
+
case 'function':
|
|
77
|
+
return fn(options);
|
|
78
|
+
case 'string':
|
|
79
|
+
return fn;
|
|
80
|
+
default:
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function containerOpenTag(name, {
|
|
86
|
+
visibleWhen,
|
|
87
|
+
classPrefix = CLASS_PREFIX,
|
|
88
|
+
logo = false,
|
|
89
|
+
circledCitationIndex = true,
|
|
90
|
+
parentQuestionId,
|
|
91
|
+
}) {
|
|
92
|
+
let className = `${classPrefix}__${name}-container`;
|
|
93
|
+
if (circledCitationIndex) {
|
|
94
|
+
className += ` miso-circled-citation-index`;
|
|
95
|
+
}
|
|
96
|
+
const attributes = [
|
|
97
|
+
` class="${className}"`,
|
|
98
|
+
` logo="${logo ? 'true' : 'false'}"`,
|
|
99
|
+
];
|
|
100
|
+
if (visibleWhen) {
|
|
101
|
+
attributes.push(` visible-when="${visibleWhen}"`);
|
|
102
|
+
}
|
|
103
|
+
if (parentQuestionId) {
|
|
104
|
+
attributes.push(` parent-question-id="${parentQuestionId}"`);
|
|
105
|
+
}
|
|
106
|
+
return `<miso-ask${attributes.join('')}>`;
|
|
107
|
+
}
|
|
@@ -91,6 +91,23 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
focus() {
|
|
95
|
+
if (this._element) {
|
|
96
|
+
this._context().focus();
|
|
97
|
+
} else {
|
|
98
|
+
// take a rain check, wait for render
|
|
99
|
+
this._focusRequested = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
set value(value) {
|
|
104
|
+
if (this._element) {
|
|
105
|
+
this._context().value = value;
|
|
106
|
+
} else {
|
|
107
|
+
this._valueRequested = value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
_preprocess({ state }) {
|
|
95
112
|
state = super._preprocess({ state });
|
|
96
113
|
const { autocomplete } = this.options;
|
|
@@ -108,6 +125,8 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
108
125
|
}
|
|
109
126
|
this._setupAutocomplete(element);
|
|
110
127
|
this._renderSuggestions(element, data, controls);
|
|
128
|
+
this._fullfillFocusRequest(element);
|
|
129
|
+
this._fullfillValueRequest(element);
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
_setupAutocomplete(element) {
|
|
@@ -142,6 +161,22 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
|
|
|
142
161
|
}
|
|
143
162
|
}
|
|
144
163
|
|
|
164
|
+
_fullfillFocusRequest(element) {
|
|
165
|
+
if (!element || !this._focusRequested) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this._focusRequested = false;
|
|
169
|
+
this._context(element).focus();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
_fullfillValueRequest(element) {
|
|
173
|
+
if (!element || !this._valueRequested) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this._context(element).value = this._valueRequested;
|
|
177
|
+
this._valueRequested = undefined;
|
|
178
|
+
}
|
|
179
|
+
|
|
145
180
|
_context(element) {
|
|
146
181
|
element = element || this._view.element;
|
|
147
182
|
if (!element) {
|
|
@@ -240,6 +275,22 @@ class Context {
|
|
|
240
275
|
}
|
|
241
276
|
}
|
|
242
277
|
|
|
278
|
+
focus() {
|
|
279
|
+
if (!this._element) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const { inputElement } = this;
|
|
283
|
+
inputElement && inputElement.focus();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
set value(value) {
|
|
287
|
+
if (!this._element) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const { inputElement } = this;
|
|
291
|
+
inputElement && (inputElement.value = value);
|
|
292
|
+
}
|
|
293
|
+
|
|
243
294
|
_get(role) {
|
|
244
295
|
return !this._element ? undefined : this._cache[role] || (this._cache[role] = this._element.querySelector(`[data-role="${role}"]`));
|
|
245
296
|
}
|
package/src/plugin.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Component, defineAndUpgrade, delegateGetters, defineValues } from '@miso.ai/commons';
|
|
1
|
+
import { Component, Resolution, defineAndUpgrade, delegateGetters, defineValues } from '@miso.ai/commons';
|
|
2
2
|
import { Asks, Explore, Search, Recommendations } from './workflow/index.js';
|
|
3
3
|
import { AskCombo } from './combo/index.js';
|
|
4
4
|
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 * as defaults from './defaults/index.js';
|
|
9
|
+
import { loadStylesIfNecessary } from './styles.js';
|
|
8
10
|
|
|
9
11
|
import MisoContainerElement from './element/container/miso-container.js';
|
|
10
12
|
import MisoComboElement from './element/combo/miso-combo.js';
|
|
@@ -17,21 +19,21 @@ export default class UiPlugin extends Component {
|
|
|
17
19
|
return PLUGIN_ID;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
constructor(
|
|
22
|
+
constructor() {
|
|
21
23
|
super('ui');
|
|
22
24
|
this.layouts = new Layouts(this);
|
|
23
25
|
this._recommendations = new WeakMap();
|
|
24
26
|
this._asks = new WeakMap();
|
|
25
27
|
this._extensions = new WeakMap();
|
|
26
|
-
|
|
28
|
+
this._ready = new Resolution();
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
install(MisoClient, context) {
|
|
31
|
+
async install(MisoClient, context) {
|
|
30
32
|
context.addSubtree(this);
|
|
31
33
|
MisoClient.on('create', this._injectClient.bind(this));
|
|
32
34
|
|
|
33
|
-
const ui = {};
|
|
34
|
-
delegateGetters(ui, this, ['layouts', 'combo']);
|
|
35
|
+
const ui = { defaults };
|
|
36
|
+
delegateGetters(ui, this, ['layouts', 'combo', 'ready']);
|
|
35
37
|
defineValues(this, { MisoClient });
|
|
36
38
|
defineValues(MisoClient, { ui });
|
|
37
39
|
|
|
@@ -61,9 +63,16 @@ export default class UiPlugin extends Component {
|
|
|
61
63
|
for (const ElementClass of ElementClasses) {
|
|
62
64
|
ElementClass.MisoClient = MisoClient; // TODO: find better way
|
|
63
65
|
}
|
|
66
|
+
|
|
67
|
+
// load styles
|
|
68
|
+
await loadStylesIfNecessary();
|
|
69
|
+
|
|
70
|
+
// define custom elements
|
|
64
71
|
for (const ElementClass of ElementClasses) {
|
|
65
72
|
defineAndUpgrade(ElementClass);
|
|
66
73
|
}
|
|
74
|
+
|
|
75
|
+
this._ready.resolve();
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
async requireExtension(name) {
|
|
@@ -75,6 +84,13 @@ export default class UiPlugin extends Component {
|
|
|
75
84
|
}
|
|
76
85
|
}
|
|
77
86
|
|
|
87
|
+
get ready() {
|
|
88
|
+
return Promise.all([
|
|
89
|
+
this._ready.promise,
|
|
90
|
+
MisoClient.any(), // TODO: we need to wait for element connection
|
|
91
|
+
]).then(() => {});
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
_injectClient(client) {
|
|
79
95
|
defineValues(client, {
|
|
80
96
|
ui: new Ui(this, client),
|
|
@@ -164,11 +180,9 @@ class Ui {
|
|
|
164
180
|
return this._explore || (this._explore = new Explore(this._plugin, this._client));
|
|
165
181
|
}
|
|
166
182
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// TODO
|
|
183
|
+
get ready() {
|
|
184
|
+
return this._plugin._ready.promise;
|
|
170
185
|
}
|
|
171
|
-
*/
|
|
172
186
|
|
|
173
187
|
}
|
|
174
188
|
|
package/src/styles.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
link = document.createElement('link');
|
|
17
|
+
link.rel = 'stylesheet';
|
|
18
|
+
link.href = getCssUrl();
|
|
19
|
+
document.head.appendChild(link);
|
|
20
|
+
}
|
|
21
|
+
return waitForStylesApplied(link);
|
|
22
|
+
} catch(e) {
|
|
23
|
+
console.error(e);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// helpers //
|
|
28
|
+
function getCssUrl() {
|
|
29
|
+
return cssUrl || (cssUrl = resolveCssUrl());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resolveCssUrl() {
|
|
33
|
+
// TODO: refactor with getPluginScriptUrl() in core
|
|
34
|
+
if (version === 'dev') {
|
|
35
|
+
const src = currentScript.src;
|
|
36
|
+
const searchIndex = src.indexOf('?');
|
|
37
|
+
const k = searchIndex < 0 ? src.length : searchIndex;
|
|
38
|
+
const i = src.lastIndexOf('/', k); // .../dist/umd/*.min.js
|
|
39
|
+
return `${src.slice(0, i - 4)}/css/ui.css`;
|
|
40
|
+
} else {
|
|
41
|
+
return `https://cdn.jsdelivr.net/npm/@miso.ai/client-sdk@${version}/dist/css/ui.css`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getExistedLinkElement() {
|
|
46
|
+
return document.head.querySelector(`link[href="${getCssUrl()}"]`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function waitForStylesApplied(element) {
|
|
50
|
+
await waitForSheetAvailable(element);
|
|
51
|
+
await waitForSheetIncluded(element);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function waitForSheetAvailable(element) {
|
|
55
|
+
if (element.sheet) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
let intervalId;
|
|
60
|
+
element.onerror = () => {
|
|
61
|
+
intervalId && clearInterval(intervalId);
|
|
62
|
+
reject();
|
|
63
|
+
};
|
|
64
|
+
intervalId = setInterval(() => {
|
|
65
|
+
if (!element.sheet) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
intervalId && clearInterval(intervalId);
|
|
69
|
+
resolve();
|
|
70
|
+
}, 100);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function waitForSheetIncluded(element) {
|
|
75
|
+
if (isSheetIncluded(element)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
return new Promise((resolve) => {
|
|
79
|
+
let intervalId;
|
|
80
|
+
intervalId = setInterval(() => {
|
|
81
|
+
if (!isSheetIncluded(element)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
intervalId && clearInterval(intervalId);
|
|
85
|
+
resolve();
|
|
86
|
+
}, 100);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isSheetIncluded(element) {
|
|
91
|
+
for (const sheet of document.styleSheets) {
|
|
92
|
+
if (sheet.ownerNode === element) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.9.
|
|
1
|
+
export default '1.9.1-beta.0';
|
package/src/workflow/ask.js
CHANGED
|
@@ -108,6 +108,22 @@ export default class Ask extends Workflow {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// lifecycle //
|
|
111
|
+
autoQuery({ setValue = true, focus = true } = {}) {
|
|
112
|
+
const q = new URLSearchParams(window.location.search).get('q');
|
|
113
|
+
const { layout } = this._views.get(ROLE.QUERY);
|
|
114
|
+
if (layout) {
|
|
115
|
+
if (q && setValue) {
|
|
116
|
+
layout.value = q;
|
|
117
|
+
}
|
|
118
|
+
if (!q && focus) {
|
|
119
|
+
layout.focus();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (q) {
|
|
123
|
+
this.query({ q });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
111
127
|
query({ q: question, ...payload } = {}) {
|
|
112
128
|
payload = { ...payload, question };
|
|
113
129
|
if (this.parentQuestionId) {
|
package/src/workflow/base.js
CHANGED
package/src/workflow/search.js
CHANGED
|
@@ -43,6 +43,22 @@ export default class Search extends Workflow {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// lifecycle //
|
|
46
|
+
autoQuery({ setValue = true, focus = true } = {}) {
|
|
47
|
+
const q = new URLSearchParams(window.location.search).get('q');
|
|
48
|
+
const { layout } = this._views.get(ROLE.QUERY);
|
|
49
|
+
if (layout) {
|
|
50
|
+
if (q && setValue) {
|
|
51
|
+
layout.value = q;
|
|
52
|
+
}
|
|
53
|
+
if (!q && focus) {
|
|
54
|
+
layout.focus();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (q) {
|
|
58
|
+
this.query({ q });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
46
62
|
query(payload) {
|
|
47
63
|
this.restart();
|
|
48
64
|
const { session } = this;
|