@miso.ai/client-sdk-ui 1.14.0-beta.2 → 1.14.0-beta.4
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/asset/svgs.js +4 -2
- package/dist/cjs/constants.js +2 -0
- package/dist/cjs/defaults/ask/index.js +2 -1
- package/dist/cjs/defaults/ask/templates.js +2 -1
- package/dist/cjs/defaults/hybrid-search/index.js +2 -1
- package/dist/cjs/defaults/hybrid-search/templates.js +2 -1
- package/dist/cjs/defaults/index.js +2 -1
- package/dist/cjs/defaults.js +107 -10
- package/dist/cjs/element/container/index.js +14 -0
- package/dist/cjs/element/container/miso-message-item.js +91 -0
- package/dist/cjs/element/container/miso-thread-item.js +91 -0
- package/dist/cjs/element/index.js +2 -1
- package/dist/cjs/element/role/index.js +7 -0
- package/dist/cjs/element/role/miso-delete.js +20 -0
- package/dist/cjs/layout/button/button.js +45 -5
- package/dist/cjs/layout/button/checkbox.js +2 -1
- package/dist/cjs/layout/container/item-container.js +99 -0
- package/dist/cjs/layout/index.js +14 -0
- package/dist/cjs/layout/input/search-box.js +9 -4
- package/dist/cjs/layout/list/collection.js +21 -4
- package/dist/cjs/layout/list/messages.js +261 -224
- package/dist/cjs/layout/list/threads.js +106 -150
- package/dist/cjs/layout/templates.js +98 -38
- package/dist/cjs/layout/text/question.js +71 -0
- package/dist/cjs/layout/text/typewriter/index.js +15 -21
- package/dist/cjs/plugin.js +6 -3
- package/dist/cjs/util/dom.js +21 -0
- package/dist/cjs/util/notify.js +74 -0
- package/dist/cjs/version.js +1 -1
- package/package.json +3 -3
- package/src/CLAUDE.md +7 -2
- package/src/asset/svgs.js +3 -1
- package/src/constants.js +2 -0
- package/src/defaults.js +75 -5
- package/src/element/container/index.js +2 -0
- package/src/element/container/miso-message-item.js +94 -0
- package/src/element/container/miso-thread-item.js +94 -0
- package/src/element/role/index.js +1 -0
- package/src/element/role/miso-delete.js +16 -0
- package/src/layout/button/button.js +40 -4
- package/src/layout/button/checkbox.js +2 -1
- package/src/layout/container/item-container.js +99 -0
- package/src/layout/index.js +2 -0
- package/src/layout/input/search-box.js +4 -2
- package/src/layout/list/collection.js +22 -5
- package/src/layout/list/messages.js +231 -201
- package/src/layout/list/threads.js +107 -128
- package/src/layout/templates.js +100 -38
- package/src/layout/text/question.js +58 -0
- package/src/layout/text/typewriter/index.js +11 -15
- package/src/plugin.js +3 -2
- package/src/util/dom.js +16 -0
- package/src/util/notify.js +68 -0
- package/src/version.js +1 -1
package/dist/cjs/asset/svgs.js
CHANGED
|
@@ -28,7 +28,8 @@ const ICON_NAME = {
|
|
|
28
28
|
PLUS: 'plus',
|
|
29
29
|
PENCIL: 'pencil',
|
|
30
30
|
BELL: 'bell',
|
|
31
|
-
BELL_FILL: 'bell-fill'
|
|
31
|
+
BELL_FILL: 'bell-fill',
|
|
32
|
+
TRASH: 'trash'
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
// CC0 SVGs
|
|
@@ -48,7 +49,8 @@ const ICON_PLUS = `<symbol id="${PREFIX}-${ICON_NAME.PLUS}" viewBox="0 0 16 16">
|
|
|
48
49
|
const ICON_PENCIL = `<symbol id="${PREFIX}-${ICON_NAME.PENCIL}" viewBox="0 0 16 16"><path fill="currentColor" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.325-.175"/></symbol>`;
|
|
49
50
|
const ICON_BELL = `<symbol id="${PREFIX}-${ICON_NAME.BELL}" viewBox="0 0 16 16"><path fill="currentColor" d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2M8 1.918l-.797.161A4 4 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4 4 0 0 0-3.203-3.92zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5 5 0 0 1 13 6c0 .88.32 4.2 1.22 6"/></symbol>`;
|
|
50
51
|
const ICON_BELL_FILL = `<symbol id="${PREFIX}-${ICON_NAME.BELL_FILL}" viewBox="0 0 16 16"><path fill="currentColor" d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2m.995-14.901a1 1 0 1 0-1.99 0A5 5 0 0 0 3 6c0 1.098-.5 6-2 7h14c-1.5-1-2-5.902-2-7 0-2.42-1.72-4.44-4.005-4.901"/></symbol>`;
|
|
51
|
-
const
|
|
52
|
+
const ICON_TRASH = `<symbol id="${PREFIX}-${ICON_NAME.TRASH}" viewBox="0 0 16 16"><path fill="currentColor" d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/><path fill="currentColor" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"/></symbol>`;
|
|
53
|
+
const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE, ICON_BULB, ICON_DOTS_VERTICAL, ICON_PLUS, ICON_PENCIL, ICON_BELL, ICON_BELL_FILL, ICON_TRASH];
|
|
52
54
|
const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
|
|
53
55
|
let loaded = false;
|
|
54
56
|
function loadSvgSprites() {
|
package/dist/cjs/constants.js
CHANGED
|
@@ -108,6 +108,7 @@ const ATTR_DATA_MISO_UNIT_ID = exports.ATTR_DATA_MISO_UNIT_ID = `data-miso-unit-
|
|
|
108
108
|
const ATTR_DATA_MISO_PRODUCT_ID = exports.ATTR_DATA_MISO_PRODUCT_ID = `data-miso-product-id`;
|
|
109
109
|
const LAYOUT_TYPE = exports.LAYOUT_TYPE = Object.freeze({
|
|
110
110
|
CONTAINER: 'container',
|
|
111
|
+
ITEM_CONTAINER: 'item-container',
|
|
111
112
|
ERROR: 'error',
|
|
112
113
|
BANNER: 'banner',
|
|
113
114
|
AFFILIATION: 'affiliation',
|
|
@@ -127,5 +128,6 @@ const LAYOUT_TYPE = exports.LAYOUT_TYPE = Object.freeze({
|
|
|
127
128
|
CHECKBOX: 'checkbox',
|
|
128
129
|
FEEDBACK: 'feedback',
|
|
129
130
|
TEXT: 'text',
|
|
131
|
+
QUESTION: 'question',
|
|
130
132
|
TYPEWRITER: 'typewriter'
|
|
131
133
|
});
|
|
@@ -24,7 +24,8 @@ Object.keys(_controls).forEach(function (key) {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
|
-
|
|
27
|
+
var cache;
|
|
28
|
+
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
28
29
|
const constants = exports.constants = Object.freeze(_constants);
|
|
29
30
|
const phrases = exports.phrases = Object.freeze(_phrases);
|
|
30
31
|
const templates = exports.templates = Object.freeze(_templates);
|
|
@@ -12,7 +12,8 @@ var CONSTANTS = _interopRequireWildcard(require("./constants.js"));
|
|
|
12
12
|
var DEFAULT_PHRASES = _interopRequireWildcard(require("./phrases.js"));
|
|
13
13
|
var _svgs = require("../../asset/svgs.js");
|
|
14
14
|
var _templates = require("../common/templates.js");
|
|
15
|
-
|
|
15
|
+
var cache;
|
|
16
|
+
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
16
17
|
class Sections extends _templates.Sections {
|
|
17
18
|
constructor() {
|
|
18
19
|
super({
|
|
@@ -24,7 +24,8 @@ Object.keys(_controls).forEach(function (key) {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
|
-
|
|
27
|
+
var cache;
|
|
28
|
+
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
28
29
|
const constants = exports.constants = Object.freeze(_constants);
|
|
29
30
|
const phrases = exports.phrases = Object.freeze(_phrases);
|
|
30
31
|
const templates = exports.templates = Object.freeze(_templates);
|
|
@@ -10,7 +10,8 @@ var _commons = require("@miso.ai/commons");
|
|
|
10
10
|
var CONSTANTS = _interopRequireWildcard(require("./constants.js"));
|
|
11
11
|
var DEFAULT_PHRASES = _interopRequireWildcard(require("./phrases.js"));
|
|
12
12
|
var _templates = require("../common/templates.js");
|
|
13
|
-
|
|
13
|
+
var cache;
|
|
14
|
+
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
14
15
|
class Sections extends _templates.Sections {
|
|
15
16
|
constructor() {
|
|
16
17
|
super({
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.hybridSearch = exports.ask = void 0;
|
|
7
7
|
var _ask = _interopRequireWildcard(require("./ask/index.js"));
|
|
8
8
|
var _hybridSearch = _interopRequireWildcard(require("./hybrid-search/index.js"));
|
|
9
|
-
|
|
9
|
+
var cache;
|
|
10
|
+
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
10
11
|
const ask = exports.ask = Object.freeze(_ask);
|
|
11
12
|
const hybridSearch = exports.hybridSearch = Object.freeze(_hybridSearch);
|
package/dist/cjs/defaults.js
CHANGED
|
@@ -4,8 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.defaultLayouts = void 0;
|
|
7
|
+
var _commons = require("@miso.ai/commons");
|
|
7
8
|
var _constants = require("./constants.js");
|
|
8
9
|
var _templates = require("./layout/templates.js");
|
|
10
|
+
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; }
|
|
11
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
12
|
+
function _toPrimitive(t, e) { if ("object" != typeof t || !t) return t; var r; if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) { var i = r.call(t, e || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === e ? String : Number)(t); }
|
|
9
13
|
/**
|
|
10
14
|
* Default layout options of each workflow, keyed by workflow name. The UI
|
|
11
15
|
* plugin seeds the workflow plugin's defaults store with these values at
|
|
@@ -57,6 +61,29 @@ function totalContent(layout, {
|
|
|
57
61
|
const label = value === 1 ? 'result' : 'results';
|
|
58
62
|
return `${formatted} ${label}`;
|
|
59
63
|
}
|
|
64
|
+
const _ROLE$QUERY = _constants.ROLE.QUERY,
|
|
65
|
+
MESSAGE_LAYOUTS = _objectWithoutPropertiesLoose(ANSWER_BASED_LAYOUTS, [_ROLE$QUERY].map(_toPropertyKey));
|
|
66
|
+
|
|
67
|
+
// the rename/delete button controls of a thread (the conversation header's,
|
|
68
|
+
// and a thread list item's context menu's): mapped to the thread record —
|
|
69
|
+
// the dialogs work with its title, and the buttons disable while the record
|
|
70
|
+
// has no thread id yet (a thread being created is not addressable until
|
|
71
|
+
// resolved; the workflows guard all the same)
|
|
72
|
+
const THREAD_CONTROL_OPTIONS = Object.freeze({
|
|
73
|
+
value: thread => thread && thread.title,
|
|
74
|
+
disabled: thread => !(thread && thread.thread_id)
|
|
75
|
+
});
|
|
76
|
+
const THREAD_RENAME_PROMPT = Object.freeze({
|
|
77
|
+
title: 'Rename thread',
|
|
78
|
+
placeholder: 'Thread name',
|
|
79
|
+
confirmText: 'Rename'
|
|
80
|
+
});
|
|
81
|
+
const THREAD_DELETE_CONFIRM = Object.freeze({
|
|
82
|
+
title: 'Delete thread',
|
|
83
|
+
message: title => `Are you sure you want to delete "${title || 'this thread'}"? This cannot be undone.`,
|
|
84
|
+
confirmText: 'Delete',
|
|
85
|
+
danger: true
|
|
86
|
+
});
|
|
60
87
|
const SEARCH_BASED_LAYOUTS = Object.assign({}, BASE_LAYOUTS, {
|
|
61
88
|
[_constants.ROLE.QUERY]: [_constants.LAYOUT_TYPE.SEARCH_BOX],
|
|
62
89
|
[_constants.ROLE.PRODUCTS]: [_constants.LAYOUT_TYPE.LIST, {
|
|
@@ -124,20 +151,90 @@ const defaultLayouts = exports.defaultLayouts = Object.freeze({
|
|
|
124
151
|
placeholder: 'Ask a question'
|
|
125
152
|
}]
|
|
126
153
|
})),
|
|
154
|
+
// the thread list's own roles plus its thread item subworkflows' — the
|
|
155
|
+
// items share the history workflow's options, so one bag serves both.
|
|
156
|
+
// The item roles: the item-container layout (the standard container
|
|
157
|
+
// duties plus the items' context menus, driven by the item-menu
|
|
158
|
+
// data-role contract — it only ever drives its own item's menu, so
|
|
159
|
+
// hosting it on the panel is inert, and the panel never triggers the
|
|
160
|
+
// auto logo either, having no main-role component), the title text
|
|
161
|
+
// (with a presentation fallback for untitled threads), the context
|
|
162
|
+
// menu's rename (ask-then-submit through the prompt dialog) and delete
|
|
163
|
+
// (confirm-then-submit) buttons, and its subscription toggle — a menu
|
|
164
|
+
// item like the other two, so text only, labeled by the action a click
|
|
165
|
+
// takes rather than by the state
|
|
127
166
|
'history': Object.freeze(Object.assign({}, BASE_LAYOUTS, {
|
|
167
|
+
[_constants.ROLE.CONTAINER]: [_constants.LAYOUT_TYPE.ITEM_CONTAINER, {
|
|
168
|
+
logo: false
|
|
169
|
+
}],
|
|
128
170
|
[_constants.ROLE.THREADS]: [_constants.LAYOUT_TYPE.THREADS, {
|
|
129
171
|
itemType: 'thread',
|
|
130
|
-
incremental: true
|
|
172
|
+
incremental: true,
|
|
173
|
+
infiniteScroll: true
|
|
131
174
|
}],
|
|
132
175
|
[_constants.ROLE.NEW_THREAD]: [_constants.LAYOUT_TYPE.BUTTON, {
|
|
133
176
|
icon: 'plus',
|
|
134
177
|
text: 'New chat'
|
|
178
|
+
}],
|
|
179
|
+
[_constants.ROLE.TITLE]: [_constants.LAYOUT_TYPE.TEXT, {
|
|
180
|
+
tag: 'div',
|
|
181
|
+
templates: {
|
|
182
|
+
content: (layout, {
|
|
183
|
+
value
|
|
184
|
+
}) => (0, _commons.escapeHtml)(value || 'Untitled')
|
|
185
|
+
}
|
|
186
|
+
}],
|
|
187
|
+
[_constants.ROLE.RENAME]: [_constants.LAYOUT_TYPE.BUTTON, Object.assign({}, THREAD_CONTROL_OPTIONS, {
|
|
188
|
+
text: 'Rename',
|
|
189
|
+
prompt: THREAD_RENAME_PROMPT
|
|
190
|
+
})],
|
|
191
|
+
[_constants.ROLE.DELETE]: [_constants.LAYOUT_TYPE.BUTTON, Object.assign({}, THREAD_CONTROL_OPTIONS, {
|
|
192
|
+
text: 'Delete',
|
|
193
|
+
confirm: THREAD_DELETE_CONFIRM
|
|
194
|
+
})],
|
|
195
|
+
[_constants.ROLE.SUBSCRIPTION]: [_constants.LAYOUT_TYPE.CHECKBOX, {
|
|
196
|
+
text: 'Subscribe',
|
|
197
|
+
checkedText: 'Unsubscribe'
|
|
135
198
|
}]
|
|
136
199
|
})),
|
|
137
|
-
|
|
200
|
+
// the conversation panel's own roles plus its message item subworkflows'
|
|
201
|
+
// — the items share the conversation workflow's options, so one bag
|
|
202
|
+
// serves both. The message roles: the answer-based layouts minus the
|
|
203
|
+
// query role (a message has no query flow of its own; the query entry
|
|
204
|
+
// below is the panel's composer), with the question layout (text plus
|
|
205
|
+
// authorship attributes, off the whole record), the answer typewriter
|
|
206
|
+
// with `instant: true` (an answer starts at what is already available: a
|
|
207
|
+
// finished one renders in one shot, an ongoing one types out only the rest),
|
|
208
|
+
// the error notice worded for a message (messageErrorMessage),
|
|
209
|
+
// and the sources as the compact horizontal cards of the hybrid-search
|
|
210
|
+
// UI. logo: false turns the per-message banner off; the panel never
|
|
211
|
+
// triggers the auto logo anyway, having no main-role component
|
|
212
|
+
'conversation': Object.freeze(Object.assign({}, MESSAGE_LAYOUTS, {
|
|
213
|
+
[_constants.ROLE.CONTAINER]: [_constants.LAYOUT_TYPE.CONTAINER, {
|
|
214
|
+
logo: false
|
|
215
|
+
}],
|
|
216
|
+
[_constants.ROLE.QUESTION]: _constants.LAYOUT_TYPE.QUESTION,
|
|
217
|
+
[_constants.ROLE.ANSWER]: [_constants.LAYOUT_TYPE.TYPEWRITER, {
|
|
218
|
+
instant: true
|
|
219
|
+
}],
|
|
220
|
+
[_constants.ROLE.ERROR]: [_constants.LAYOUT_TYPE.ERROR, {
|
|
221
|
+
templates: {
|
|
222
|
+
message: _templates.messageErrorMessage
|
|
223
|
+
}
|
|
224
|
+
}],
|
|
225
|
+
[_constants.ROLE.SOURCES]: [_constants.LAYOUT_TYPE.HORIZONTAL, {
|
|
226
|
+
incremental: true,
|
|
227
|
+
itemType: 'article',
|
|
228
|
+
templates: {
|
|
229
|
+
ordered: true,
|
|
230
|
+
article: _templates.compactArticle,
|
|
231
|
+
articleInfoBlock: _templates.compactArticleInfoBlock
|
|
232
|
+
}
|
|
233
|
+
}],
|
|
138
234
|
[_constants.ROLE.MESSAGES]: [_constants.LAYOUT_TYPE.MESSAGES, {
|
|
139
235
|
itemType: 'message',
|
|
140
|
-
incremental: true
|
|
236
|
+
incremental: true,
|
|
237
|
+
infiniteScroll: true
|
|
141
238
|
}],
|
|
142
239
|
[_constants.ROLE.QUERY]: [_constants.LAYOUT_TYPE.SEARCH_BOX, {
|
|
143
240
|
placeholder: 'Ask a follow-up question',
|
|
@@ -151,14 +248,14 @@ const defaultLayouts = exports.defaultLayouts = Object.freeze({
|
|
|
151
248
|
[_constants.ROLE.TITLE]: [_constants.LAYOUT_TYPE.TEXT, {
|
|
152
249
|
tag: 'div'
|
|
153
250
|
}],
|
|
154
|
-
[_constants.ROLE.RENAME]: [_constants.LAYOUT_TYPE.BUTTON, {
|
|
251
|
+
[_constants.ROLE.RENAME]: [_constants.LAYOUT_TYPE.BUTTON, Object.assign({}, THREAD_CONTROL_OPTIONS, {
|
|
155
252
|
icon: 'pencil',
|
|
156
|
-
prompt:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}],
|
|
253
|
+
prompt: THREAD_RENAME_PROMPT
|
|
254
|
+
})],
|
|
255
|
+
[_constants.ROLE.DELETE]: [_constants.LAYOUT_TYPE.BUTTON, Object.assign({}, THREAD_CONTROL_OPTIONS, {
|
|
256
|
+
icon: 'trash',
|
|
257
|
+
confirm: THREAD_DELETE_CONFIRM
|
|
258
|
+
})],
|
|
162
259
|
[_constants.ROLE.SUBSCRIPTION]: [_constants.LAYOUT_TYPE.CHECKBOX, {
|
|
163
260
|
icon: 'bell',
|
|
164
261
|
text: 'Subscribe',
|
|
@@ -33,6 +33,12 @@ Object.defineProperty(exports, "MisoHybridSearchElement", {
|
|
|
33
33
|
return _misoHybridSearch.default;
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
+
Object.defineProperty(exports, "MisoMessageItemElement", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _misoMessageItem.default;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
36
42
|
Object.defineProperty(exports, "MisoRecommendationElement", {
|
|
37
43
|
enumerable: true,
|
|
38
44
|
get: function () {
|
|
@@ -45,10 +51,18 @@ Object.defineProperty(exports, "MisoSearchElement", {
|
|
|
45
51
|
return _misoSearch.default;
|
|
46
52
|
}
|
|
47
53
|
});
|
|
54
|
+
Object.defineProperty(exports, "MisoThreadItemElement", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _misoThreadItem.default;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
48
60
|
var _misoAsk = _interopRequireDefault(require("./miso-ask.js"));
|
|
49
61
|
var _misoExplore = _interopRequireDefault(require("./miso-explore.js"));
|
|
50
62
|
var _misoHistory = _interopRequireDefault(require("./miso-history.js"));
|
|
51
63
|
var _misoConversation = _interopRequireDefault(require("./miso-conversation.js"));
|
|
64
|
+
var _misoMessageItem = _interopRequireDefault(require("./miso-message-item.js"));
|
|
65
|
+
var _misoThreadItem = _interopRequireDefault(require("./miso-thread-item.js"));
|
|
52
66
|
var _misoHybridSearch = _interopRequireDefault(require("./miso-hybrid-search.js"));
|
|
53
67
|
var _misoSearch = _interopRequireDefault(require("./miso-search.js"));
|
|
54
68
|
var _misoRecommendation = _interopRequireDefault(require("./miso-recommendation.js"));
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _misoContainer = _interopRequireDefault(require("./miso-container.js"));
|
|
8
|
+
var _utils = require("../utils.js");
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
const TAG_NAME = 'miso-message-item';
|
|
11
|
+
const ATTR_QUESTION_ID = 'question-id';
|
|
12
|
+
const OBSERVED_ATTRIBUTES = Object.freeze([..._misoContainer.default.observedAttributes, ATTR_QUESTION_ID]);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A container element for one message (question-answer pair) of the
|
|
16
|
+
* conversation panel, placed inside <miso-conversation> — a container
|
|
17
|
+
* element inside another container element hosting an item subworkflow (the
|
|
18
|
+
* `message` workflow). Normally bound implicitly: the messages layout
|
|
19
|
+
* renders one <miso-message-item> per item and assigns the workflow off the item
|
|
20
|
+
* binding (element.workflow = parent workflow's _getMessageWorkflow(record)),
|
|
21
|
+
* which also covers a just-posted message that has no question id yet. A
|
|
22
|
+
* `question-id` attribute binds explicitly instead, through the parent
|
|
23
|
+
* container's workflow. Role elements inside (question, answer, sources,
|
|
24
|
+
* ...) bind to the message workflow as usual — getContainer() resolves to
|
|
25
|
+
* the closest container ancestor.
|
|
26
|
+
*/
|
|
27
|
+
class MisoMessageItemElement extends _misoContainer.default {
|
|
28
|
+
static get tagName() {
|
|
29
|
+
return TAG_NAME;
|
|
30
|
+
}
|
|
31
|
+
static get observedAttributes() {
|
|
32
|
+
return OBSERVED_ATTRIBUTES;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// properties //
|
|
36
|
+
get questionId() {
|
|
37
|
+
return this.getAttribute(ATTR_QUESTION_ID) || undefined;
|
|
38
|
+
}
|
|
39
|
+
set questionId(value) {
|
|
40
|
+
value = value !== undefined ? `${value}` : undefined;
|
|
41
|
+
if (value === this.questionId) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (value) {
|
|
45
|
+
this.setAttribute(ATTR_QUESTION_ID, value);
|
|
46
|
+
} else {
|
|
47
|
+
this.removeAttribute(ATTR_QUESTION_ID);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
_getWorkflow(client) {
|
|
51
|
+
const {
|
|
52
|
+
questionId
|
|
53
|
+
} = this;
|
|
54
|
+
if (!questionId) {
|
|
55
|
+
// implicitly bound: the messages layout assigns element.workflow off
|
|
56
|
+
// the item binding — keep whatever is (or will be) assigned
|
|
57
|
+
return this._workflow;
|
|
58
|
+
}
|
|
59
|
+
const container = this._getParentContainer();
|
|
60
|
+
const workflow = container && container.workflow;
|
|
61
|
+
// the parent workflow hands out the item subworkflow; the parent binds
|
|
62
|
+
// its own workflow first (its connectedCallback resolves earlier), so
|
|
63
|
+
// it is normally present by now
|
|
64
|
+
return workflow && typeof workflow._getMessageWorkflow === 'function' ? workflow._getMessageWorkflow(questionId) : undefined;
|
|
65
|
+
}
|
|
66
|
+
_getParentContainer() {
|
|
67
|
+
try {
|
|
68
|
+
return this.parentNode ? (0, _utils.getContainer)(this.parentNode) : undefined;
|
|
69
|
+
} catch (_) {
|
|
70
|
+
return undefined; // not inside a container element
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
attributeChangedCallback(attr, oldValue, newValue) {
|
|
74
|
+
switch (attr) {
|
|
75
|
+
case ATTR_QUESTION_ID:
|
|
76
|
+
this._handleQuestionIdUpdate(oldValue, newValue);
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
super.attributeChangedCallback(attr, oldValue, newValue);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
_handleQuestionIdUpdate(oldValue, newValue) {
|
|
83
|
+
oldValue = oldValue || undefined; // null -> undefined
|
|
84
|
+
newValue = newValue || undefined;
|
|
85
|
+
if (oldValue === newValue || !this._client) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this._setWorkflow(this._getWorkflow(this._client));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.default = MisoMessageItemElement;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _misoContainer = _interopRequireDefault(require("./miso-container.js"));
|
|
8
|
+
var _utils = require("../utils.js");
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
const TAG_NAME = 'miso-thread-item';
|
|
11
|
+
const ATTR_THREAD_ID = 'thread-id';
|
|
12
|
+
const OBSERVED_ATTRIBUTES = Object.freeze([..._misoContainer.default.observedAttributes, ATTR_THREAD_ID]);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A container element for one thread item of the thread list, placed inside
|
|
16
|
+
* <miso-history> — a container element inside another container element
|
|
17
|
+
* hosting an item subworkflow (the `thread` workflow). Normally bound
|
|
18
|
+
* implicitly: the threads layout renders one <miso-thread-item> per item and
|
|
19
|
+
* assigns the workflow off the item binding (element.workflow = parent
|
|
20
|
+
* workflow's _getThreadWorkflow(record)), which also covers a thread being
|
|
21
|
+
* created that has no thread id yet. A `thread-id` attribute binds
|
|
22
|
+
* explicitly instead, through the parent container's workflow. Role
|
|
23
|
+
* elements inside (title, rename, delete, subscription) bind to the thread
|
|
24
|
+
* workflow as usual — getContainer() resolves to the closest container
|
|
25
|
+
* ancestor.
|
|
26
|
+
*/
|
|
27
|
+
class MisoThreadItemElement extends _misoContainer.default {
|
|
28
|
+
static get tagName() {
|
|
29
|
+
return TAG_NAME;
|
|
30
|
+
}
|
|
31
|
+
static get observedAttributes() {
|
|
32
|
+
return OBSERVED_ATTRIBUTES;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// properties //
|
|
36
|
+
get threadId() {
|
|
37
|
+
return this.getAttribute(ATTR_THREAD_ID) || undefined;
|
|
38
|
+
}
|
|
39
|
+
set threadId(value) {
|
|
40
|
+
value = value !== undefined ? `${value}` : undefined;
|
|
41
|
+
if (value === this.threadId) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (value) {
|
|
45
|
+
this.setAttribute(ATTR_THREAD_ID, value);
|
|
46
|
+
} else {
|
|
47
|
+
this.removeAttribute(ATTR_THREAD_ID);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
_getWorkflow(client) {
|
|
51
|
+
const {
|
|
52
|
+
threadId
|
|
53
|
+
} = this;
|
|
54
|
+
if (!threadId) {
|
|
55
|
+
// implicitly bound: the threads layout assigns element.workflow off
|
|
56
|
+
// the item binding — keep whatever is (or will be) assigned
|
|
57
|
+
return this._workflow;
|
|
58
|
+
}
|
|
59
|
+
const container = this._getParentContainer();
|
|
60
|
+
const workflow = container && container.workflow;
|
|
61
|
+
// the parent workflow hands out the item subworkflow; the parent binds
|
|
62
|
+
// its own workflow first (its connectedCallback resolves earlier), so
|
|
63
|
+
// it is normally present by now
|
|
64
|
+
return workflow && typeof workflow._getThreadWorkflow === 'function' ? workflow._getThreadWorkflow(threadId) : undefined;
|
|
65
|
+
}
|
|
66
|
+
_getParentContainer() {
|
|
67
|
+
try {
|
|
68
|
+
return this.parentNode ? (0, _utils.getContainer)(this.parentNode) : undefined;
|
|
69
|
+
} catch (_) {
|
|
70
|
+
return undefined; // not inside a container element
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
attributeChangedCallback(attr, oldValue, newValue) {
|
|
74
|
+
switch (attr) {
|
|
75
|
+
case ATTR_THREAD_ID:
|
|
76
|
+
this._handleThreadIdUpdate(oldValue, newValue);
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
super.attributeChangedCallback(attr, oldValue, newValue);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
_handleThreadIdUpdate(oldValue, newValue) {
|
|
83
|
+
oldValue = oldValue || undefined; // null -> undefined
|
|
84
|
+
newValue = newValue || undefined;
|
|
85
|
+
if (oldValue === newValue || !this._client) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this._setWorkflow(this._getWorkflow(this._client));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.default = MisoThreadItemElement;
|
|
@@ -30,4 +30,5 @@ Object.keys(_index5).forEach(function (key) {
|
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
|
-
|
|
33
|
+
var cache;
|
|
34
|
+
function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var r, c, a = Object.defineProperty, n = { __proto__: null, default: e }; if (Object(e) !== e) return n; if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) { if (cache.has(e)) return cache.get(e); cache.set(e, n); } for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]); return n; }
|
|
@@ -21,6 +21,12 @@ Object.defineProperty(exports, "MisoComponentElement", {
|
|
|
21
21
|
return _misoComponent.default;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "MisoDeleteElement", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _misoDelete.default;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
24
30
|
Object.defineProperty(exports, "MisoErrorElement", {
|
|
25
31
|
enumerable: true,
|
|
26
32
|
get: function () {
|
|
@@ -189,6 +195,7 @@ var _misoThreads = _interopRequireDefault(require("./miso-threads.js"));
|
|
|
189
195
|
var _misoNewThread = _interopRequireDefault(require("./miso-new-thread.js"));
|
|
190
196
|
var _misoTitle = _interopRequireDefault(require("./miso-title.js"));
|
|
191
197
|
var _misoRename = _interopRequireDefault(require("./miso-rename.js"));
|
|
198
|
+
var _misoDelete = _interopRequireDefault(require("./miso-delete.js"));
|
|
192
199
|
var _misoSubscription = _interopRequireDefault(require("./miso-subscription.js"));
|
|
193
200
|
var _misoMessages = _interopRequireDefault(require("./miso-messages.js"));
|
|
194
201
|
var _misoError = _interopRequireDefault(require("./miso-error.js"));
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _misoComponent = _interopRequireDefault(require("./miso-component.js"));
|
|
8
|
+
var _constants = require("../../constants.js");
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
class MisoDeleteElement extends _misoComponent.default {
|
|
11
|
+
constructor() {
|
|
12
|
+
super({
|
|
13
|
+
role: _constants.ROLE.DELETE
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
static get tagName() {
|
|
17
|
+
return 'miso-delete';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.default = MisoDeleteElement;
|
|
@@ -9,7 +9,9 @@ var _constants = require("../../constants.js");
|
|
|
9
9
|
var _template = _interopRequireDefault(require("../template.js"));
|
|
10
10
|
var _svgs = require("../../asset/svgs.js");
|
|
11
11
|
var _prompt = _interopRequireDefault(require("../../util/prompt.js"));
|
|
12
|
-
|
|
12
|
+
var _confirm = _interopRequireDefault(require("../../util/confirm.js"));
|
|
13
|
+
const _excluded = ["className", "templates"],
|
|
14
|
+
_excluded2 = ["message"];
|
|
13
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
16
|
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
17
|
const TYPE = _constants.LAYOUT_TYPE.BUTTON;
|
|
@@ -21,7 +23,8 @@ function root(layout, state) {
|
|
|
21
23
|
templates
|
|
22
24
|
} = layout;
|
|
23
25
|
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
24
|
-
|
|
26
|
+
const disabledAttr = layout._isDisabled(state) ? ' disabled' : '';
|
|
27
|
+
return `<button type="button" class="${className}"${roleAttr}${disabledAttr}>${templates.icon(layout, state)}${templates.text(layout, state)}</button>`;
|
|
25
28
|
}
|
|
26
29
|
function icon(layout) {
|
|
27
30
|
const {
|
|
@@ -60,6 +63,19 @@ const DEFAULT_TEMPLATES = Object.freeze({
|
|
|
60
63
|
* dialog submits nothing. Use it for actions that take a text input, such
|
|
61
64
|
* as the rename button (role `rename`) of the conversation header, whose
|
|
62
65
|
* role maps to `'thread.title'`.
|
|
66
|
+
*
|
|
67
|
+
* With a `confirm` option, the click asks through the shared confirm dialog
|
|
68
|
+
* first, and submits only when confirmed; the option's `message` may be a
|
|
69
|
+
* function of the control's current value. Use it for destructive actions,
|
|
70
|
+
* such as the delete button (role `delete`) of a thread item's context menu.
|
|
71
|
+
*
|
|
72
|
+
* The control's current value is the role's mapped data value, put through
|
|
73
|
+
* the `value` option when given — map the role to a record and let `value`
|
|
74
|
+
* pick the text the dialogs work with. A `disabled` option (a boolean, or a
|
|
75
|
+
* function of the mapped value) renders the button's disabled state from
|
|
76
|
+
* the data, re-evaluated on every commit — e.g. rename/delete disable while
|
|
77
|
+
* their thread record has no thread id yet (a thread being created is not
|
|
78
|
+
* addressable), enabling in place when the resolution patches the record.
|
|
63
79
|
*/
|
|
64
80
|
class ButtonLayout extends _template.default {
|
|
65
81
|
static get type() {
|
|
@@ -94,7 +110,7 @@ class ButtonLayout extends _template.default {
|
|
|
94
110
|
if (!button || button.disabled) {
|
|
95
111
|
return;
|
|
96
112
|
}
|
|
97
|
-
this.options.prompt ? this._submitViaPrompt(event) : this._submit(event);
|
|
113
|
+
this.options.prompt ? this._submitViaPrompt(event) : this.options.confirm ? this._submitViaConfirm(event) : this._submit(event);
|
|
98
114
|
}
|
|
99
115
|
_submit(event, payload) {
|
|
100
116
|
const {
|
|
@@ -117,14 +133,38 @@ class ButtonLayout extends _template.default {
|
|
|
117
133
|
value
|
|
118
134
|
});
|
|
119
135
|
}
|
|
136
|
+
async _submitViaConfirm(event) {
|
|
137
|
+
const _this$options$confirm = this.options.confirm,
|
|
138
|
+
{
|
|
139
|
+
message
|
|
140
|
+
} = _this$options$confirm,
|
|
141
|
+
options = _objectWithoutPropertiesLoose(_this$options$confirm, _excluded2);
|
|
142
|
+
const confirmed = await (0, _confirm.default)(Object.assign({}, options, {
|
|
143
|
+
message: typeof message === 'function' ? message(this._currentValue()) : message
|
|
144
|
+
}));
|
|
145
|
+
if (!confirmed) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this._submit(event);
|
|
149
|
+
}
|
|
120
150
|
|
|
121
151
|
/**
|
|
122
152
|
* The current value of the control: the role's mapped data value, as of
|
|
123
|
-
* the latest render.
|
|
153
|
+
* the latest render, put through the `value` option when given.
|
|
124
154
|
*/
|
|
125
155
|
_currentValue() {
|
|
126
156
|
const state = this._element && this._rendered.get(this._element);
|
|
127
|
-
|
|
157
|
+
const raw = state && state.value;
|
|
158
|
+
const {
|
|
159
|
+
value
|
|
160
|
+
} = this.options;
|
|
161
|
+
return typeof value === 'function' ? value(raw) : raw;
|
|
162
|
+
}
|
|
163
|
+
_isDisabled(state) {
|
|
164
|
+
const {
|
|
165
|
+
disabled
|
|
166
|
+
} = this.options;
|
|
167
|
+
return typeof disabled === 'function' ? !!disabled(state && state.value) : !!disabled;
|
|
128
168
|
}
|
|
129
169
|
}
|
|
130
170
|
exports.default = ButtonLayout;
|
|
@@ -22,7 +22,8 @@ function root(layout, state) {
|
|
|
22
22
|
const checked = isChecked(state);
|
|
23
23
|
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
24
24
|
const checkedAttr = checked ? ' data-checked' : '';
|
|
25
|
-
|
|
25
|
+
const disabledAttr = layout._isDisabled(state) ? ' disabled' : '';
|
|
26
|
+
return `<button type="button" class="${className}" role="switch" aria-checked="${checked}"${roleAttr}${checkedAttr}${disabledAttr}>${templates.icon(layout, state)}${templates.text(layout, state)}</button>`;
|
|
26
27
|
}
|
|
27
28
|
function icon(layout, state) {
|
|
28
29
|
const {
|