@miso.ai/client-sdk-ui 1.13.2-beta.1 → 1.14.0-beta.3
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 +17 -4
- package/dist/cjs/combo/ask/index.js +2 -2
- package/dist/cjs/constants.js +120 -98
- package/dist/cjs/defaults/ask/controls.js +1 -1
- package/dist/cjs/defaults/hybrid-search/answer-box.js +4 -4
- package/dist/cjs/defaults.js +259 -0
- package/dist/cjs/element/container/index.js +28 -0
- package/dist/cjs/element/container/miso-ask.js +3 -3
- package/dist/cjs/element/container/miso-conversation.js +21 -0
- package/dist/cjs/element/container/miso-explore.js +1 -1
- package/dist/cjs/element/container/miso-history.js +21 -0
- package/dist/cjs/element/container/miso-hybrid-search.js +1 -1
- package/dist/cjs/element/container/miso-message-item.js +91 -0
- package/dist/cjs/element/container/miso-recommendation.js +1 -1
- package/dist/cjs/element/container/miso-search.js +1 -1
- package/dist/cjs/element/container/miso-thread-item.js +91 -0
- package/dist/cjs/element/context/miso-follow-ups.js +1 -1
- package/dist/cjs/element/role/index.js +49 -0
- package/dist/cjs/element/role/miso-delete.js +20 -0
- package/dist/cjs/element/role/miso-messages.js +20 -0
- package/dist/cjs/element/role/miso-new-thread.js +20 -0
- package/dist/cjs/element/role/miso-rename.js +20 -0
- package/dist/cjs/element/role/miso-subscription.js +20 -0
- package/dist/cjs/element/role/miso-threads.js +20 -0
- package/dist/cjs/element/role/miso-title.js +20 -0
- package/dist/cjs/layout/affiliation/affiliation.js +1 -1
- package/dist/cjs/layout/banner/banner.js +2 -1
- package/dist/cjs/layout/button/button.js +170 -0
- package/dist/cjs/layout/button/checkbox.js +116 -0
- package/dist/cjs/layout/button/more-button.js +3 -3
- package/dist/cjs/layout/container/container.js +1 -1
- package/dist/cjs/layout/container/item-container.js +99 -0
- package/dist/cjs/layout/error/error.js +2 -1
- package/dist/cjs/layout/index.js +42 -0
- package/dist/cjs/layout/input/facets.js +4 -3
- package/dist/cjs/layout/input/option-list.js +3 -2
- package/dist/cjs/layout/input/search-box.js +50 -12
- package/dist/cjs/layout/input/select.js +2 -1
- package/dist/cjs/layout/list/cards.js +2 -1
- package/dist/cjs/layout/list/carousel.js +2 -1
- package/dist/cjs/layout/list/collection.js +13 -1
- package/dist/cjs/layout/list/gallery.js +2 -1
- package/dist/cjs/layout/list/horizontal.js +2 -1
- package/dist/cjs/layout/list/list.js +2 -1
- package/dist/cjs/layout/list/messages.js +359 -0
- package/dist/cjs/layout/list/threads.js +199 -0
- package/dist/cjs/layout/mixin/trackable.js +4 -5
- package/dist/cjs/layout/mixin/triggerable.js +2 -2
- package/dist/cjs/layout/radio/feedback.js +4 -3
- package/dist/cjs/layout/templates.js +97 -0
- package/dist/cjs/layout/text/question.js +71 -0
- package/dist/cjs/layout/text/text.js +2 -1
- package/dist/cjs/layout/text/typewriter/index.js +18 -23
- package/dist/cjs/plugin.js +43 -104
- package/dist/cjs/util/confirm.js +33 -0
- package/dist/cjs/util/dom.js +21 -0
- package/dist/cjs/util/modal.js +48 -0
- package/dist/cjs/util/prompt.js +47 -0
- package/dist/cjs/version.js +1 -1
- package/package.json +5 -4
- package/src/CLAUDE.md +51 -104
- package/src/asset/svgs.js +16 -3
- package/src/combo/ask/index.js +2 -2
- package/src/constants.js +39 -147
- package/src/defaults/ask/controls.js +1 -1
- package/src/defaults/hybrid-search/answer-box.js +2 -2
- package/src/defaults.js +174 -0
- package/src/element/container/index.js +4 -0
- package/src/element/container/miso-ask.js +3 -3
- package/src/element/container/miso-conversation.js +19 -0
- package/src/element/container/miso-explore.js +1 -1
- package/src/element/container/miso-history.js +19 -0
- package/src/element/container/miso-hybrid-search.js +1 -1
- package/src/element/container/miso-message-item.js +94 -0
- package/src/element/container/miso-recommendation.js +1 -1
- package/src/element/container/miso-search.js +1 -1
- package/src/element/container/miso-thread-item.js +94 -0
- package/src/element/context/miso-follow-ups.js +1 -1
- package/src/element/role/index.js +7 -0
- package/src/element/role/miso-delete.js +16 -0
- package/src/element/role/miso-messages.js +16 -0
- package/src/element/role/miso-new-thread.js +16 -0
- package/src/element/role/miso-rename.js +16 -0
- package/src/element/role/miso-subscription.js +16 -0
- package/src/element/role/miso-threads.js +16 -0
- package/src/element/role/miso-title.js +16 -0
- package/src/layout/affiliation/affiliation.js +2 -2
- package/src/layout/banner/banner.js +2 -1
- package/src/layout/button/button.js +152 -0
- package/src/layout/button/checkbox.js +92 -0
- package/src/layout/button/more-button.js +3 -3
- package/src/layout/container/container.js +2 -2
- package/src/layout/container/item-container.js +99 -0
- package/src/layout/error/error.js +2 -1
- package/src/layout/index.js +6 -0
- package/src/layout/input/facets.js +3 -2
- package/src/layout/input/option-list.js +3 -2
- package/src/layout/input/search-box.js +45 -8
- package/src/layout/input/select.js +2 -1
- package/src/layout/list/cards.js +2 -1
- package/src/layout/list/carousel.js +2 -1
- package/src/layout/list/collection.js +15 -2
- package/src/layout/list/gallery.js +2 -1
- package/src/layout/list/horizontal.js +2 -1
- package/src/layout/list/list.js +2 -1
- package/src/layout/list/messages.js +316 -0
- package/src/layout/list/threads.js +166 -0
- package/src/layout/mixin/trackable.js +2 -3
- package/src/layout/mixin/triggerable.js +1 -1
- package/src/layout/radio/feedback.js +3 -2
- package/src/layout/templates.js +97 -0
- package/src/layout/text/question.js +58 -0
- package/src/layout/text/text.js +2 -1
- package/src/layout/text/typewriter/index.js +15 -18
- package/src/plugin.js +31 -117
- package/src/util/confirm.js +28 -0
- package/src/util/dom.js +16 -0
- package/src/util/modal.js +49 -0
- package/src/util/prompt.js +42 -0
- package/src/version.js +1 -1
- package/dist/cjs/actor/data.js +0 -132
- package/dist/cjs/actor/feedback.js +0 -29
- package/dist/cjs/actor/fields.js +0 -57
- package/dist/cjs/actor/filters.js +0 -161
- package/dist/cjs/actor/hub.js +0 -57
- package/dist/cjs/actor/index.js +0 -73
- package/dist/cjs/actor/interactions.js +0 -36
- package/dist/cjs/actor/sessions.js +0 -25
- package/dist/cjs/actor/tracker-states.js +0 -61
- package/dist/cjs/actor/tracker.js +0 -109
- package/dist/cjs/actor/trackers.js +0 -52
- package/dist/cjs/actor/utils.js +0 -15
- package/dist/cjs/actor/view.js +0 -294
- package/dist/cjs/actor/views.js +0 -209
- package/dist/cjs/source.js +0 -27
- package/dist/cjs/util/proxy.js +0 -88
- package/dist/cjs/util/trackers.js +0 -88
- package/dist/cjs/workflow/affiliations.js +0 -140
- package/dist/cjs/workflow/answer-based.js +0 -337
- package/dist/cjs/workflow/ask.js +0 -319
- package/dist/cjs/workflow/asks.js +0 -150
- package/dist/cjs/workflow/autocompletable.js +0 -63
- package/dist/cjs/workflow/autocomplete.js +0 -120
- package/dist/cjs/workflow/base.js +0 -418
- package/dist/cjs/workflow/context.js +0 -19
- package/dist/cjs/workflow/explore.js +0 -210
- package/dist/cjs/workflow/explores.js +0 -21
- package/dist/cjs/workflow/hybrid-search-answer.js +0 -88
- package/dist/cjs/workflow/hybrid-search-views.js +0 -109
- package/dist/cjs/workflow/hybrid-search.js +0 -213
- package/dist/cjs/workflow/index.js +0 -41
- package/dist/cjs/workflow/options/api.js +0 -41
- package/dist/cjs/workflow/options/auto-query.js +0 -97
- package/dist/cjs/workflow/options/configurable.js +0 -45
- package/dist/cjs/workflow/options/data-processor.js +0 -20
- package/dist/cjs/workflow/options/filters.js +0 -15
- package/dist/cjs/workflow/options/index.js +0 -126
- package/dist/cjs/workflow/options/interactions.js +0 -41
- package/dist/cjs/workflow/options/layouts.js +0 -79
- package/dist/cjs/workflow/options/options.js +0 -156
- package/dist/cjs/workflow/options/pagination.js +0 -25
- package/dist/cjs/workflow/options/roles.js +0 -15
- package/dist/cjs/workflow/options/templates.js +0 -30
- package/dist/cjs/workflow/options/trackers.js +0 -83
- package/dist/cjs/workflow/options/utils.js +0 -33
- package/dist/cjs/workflow/processors.js +0 -607
- package/dist/cjs/workflow/recommendation.js +0 -57
- package/dist/cjs/workflow/recommendations.js +0 -18
- package/dist/cjs/workflow/search-based.js +0 -337
- package/dist/cjs/workflow/search.js +0 -64
- package/dist/cjs/workflow/unit.js +0 -57
- package/dist/cjs/workflow/units.js +0 -42
- package/dist/cjs/workflow/use-link.js +0 -49
- package/src/actor/data.js +0 -106
- package/src/actor/feedback.js +0 -28
- package/src/actor/fields.js +0 -51
- package/src/actor/filters.js +0 -149
- package/src/actor/hub.js +0 -47
- package/src/actor/index.js +0 -10
- package/src/actor/interactions.js +0 -32
- package/src/actor/sessions.js +0 -21
- package/src/actor/tracker-states.js +0 -57
- package/src/actor/tracker.js +0 -104
- package/src/actor/trackers.js +0 -45
- package/src/actor/utils.js +0 -7
- package/src/actor/view.js +0 -272
- package/src/actor/views.js +0 -224
- package/src/source.js +0 -17
- package/src/util/proxy.js +0 -81
- package/src/util/trackers.js +0 -84
- package/src/workflow/affiliations.js +0 -121
- package/src/workflow/answer-based.js +0 -312
- package/src/workflow/ask.js +0 -284
- package/src/workflow/asks.js +0 -143
- package/src/workflow/autocompletable.js +0 -67
- package/src/workflow/autocomplete.js +0 -114
- package/src/workflow/base.js +0 -396
- package/src/workflow/context.js +0 -16
- package/src/workflow/explore.js +0 -194
- package/src/workflow/explores.js +0 -18
- package/src/workflow/hybrid-search-answer.js +0 -73
- package/src/workflow/hybrid-search-views.js +0 -116
- package/src/workflow/hybrid-search.js +0 -230
- package/src/workflow/index.js +0 -5
- package/src/workflow/options/api.js +0 -31
- package/src/workflow/options/auto-query.js +0 -70
- package/src/workflow/options/configurable.js +0 -48
- package/src/workflow/options/data-processor.js +0 -15
- package/src/workflow/options/filters.js +0 -10
- package/src/workflow/options/index.js +0 -11
- package/src/workflow/options/interactions.js +0 -36
- package/src/workflow/options/layouts.js +0 -73
- package/src/workflow/options/options.js +0 -175
- package/src/workflow/options/pagination.js +0 -18
- package/src/workflow/options/roles.js +0 -12
- package/src/workflow/options/templates.js +0 -27
- package/src/workflow/options/trackers.js +0 -80
- package/src/workflow/options/utils.js +0 -26
- package/src/workflow/processors.js +0 -490
- package/src/workflow/recommendation.js +0 -63
- package/src/workflow/recommendations.js +0 -14
- package/src/workflow/search-based.js +0 -329
- package/src/workflow/search.js +0 -73
- package/src/workflow/unit.js +0 -51
- package/src/workflow/units.js +0 -43
- package/src/workflow/use-link.js +0 -41
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import MisoContainerElement from './miso-container.js';
|
|
2
|
+
import { getContainer } from '../utils.js';
|
|
3
|
+
|
|
4
|
+
const TAG_NAME = 'miso-thread-item';
|
|
5
|
+
|
|
6
|
+
const ATTR_THREAD_ID = 'thread-id';
|
|
7
|
+
const OBSERVED_ATTRIBUTES = Object.freeze([
|
|
8
|
+
...MisoContainerElement.observedAttributes,
|
|
9
|
+
ATTR_THREAD_ID,
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A container element for one thread item of the thread list, placed inside
|
|
14
|
+
* <miso-history> — a container element inside another container element
|
|
15
|
+
* hosting an item subworkflow (the `thread` workflow). Normally bound
|
|
16
|
+
* implicitly: the threads layout renders one <miso-thread-item> per item and
|
|
17
|
+
* assigns the workflow off the item binding (element.workflow = parent
|
|
18
|
+
* workflow's _getThreadWorkflow(record)), which also covers a thread being
|
|
19
|
+
* created that has no thread id yet. A `thread-id` attribute binds
|
|
20
|
+
* explicitly instead, through the parent container's workflow. Role
|
|
21
|
+
* elements inside (title, rename, delete, subscription) bind to the thread
|
|
22
|
+
* workflow as usual — getContainer() resolves to the closest container
|
|
23
|
+
* ancestor.
|
|
24
|
+
*/
|
|
25
|
+
export default class MisoThreadItemElement extends MisoContainerElement {
|
|
26
|
+
|
|
27
|
+
static get tagName() {
|
|
28
|
+
return TAG_NAME;
|
|
29
|
+
}
|
|
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
|
+
|
|
40
|
+
set threadId(value) {
|
|
41
|
+
value = value !== undefined ? `${value}` : undefined;
|
|
42
|
+
if (value === this.threadId) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (value) {
|
|
46
|
+
this.setAttribute(ATTR_THREAD_ID, value);
|
|
47
|
+
} else {
|
|
48
|
+
this.removeAttribute(ATTR_THREAD_ID);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
_getWorkflow(client) {
|
|
53
|
+
const { threadId } = 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
|
+
|
|
67
|
+
_getParentContainer() {
|
|
68
|
+
try {
|
|
69
|
+
return this.parentNode ? getContainer(this.parentNode) : undefined;
|
|
70
|
+
} catch (_) {
|
|
71
|
+
return undefined; // not inside a container element
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
attributeChangedCallback(attr, oldValue, newValue) {
|
|
76
|
+
switch (attr) {
|
|
77
|
+
case ATTR_THREAD_ID:
|
|
78
|
+
this._handleThreadIdUpdate(oldValue, newValue);
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
super.attributeChangedCallback(attr, oldValue, newValue);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_handleThreadIdUpdate(oldValue, newValue) {
|
|
86
|
+
oldValue = oldValue || undefined; // null -> undefined
|
|
87
|
+
newValue = newValue || undefined;
|
|
88
|
+
if (oldValue === newValue || !this._client) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this._setWorkflow(this._getWorkflow(this._client));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
@@ -18,4 +18,11 @@ export { default as MisoTotalElement } from './miso-total.js';
|
|
|
18
18
|
export { default as MisoFacetsElement } from './miso-facets.js';
|
|
19
19
|
export { default as MisoMoreElement } from './miso-more.js';
|
|
20
20
|
export { default as MisoSortElement } from './miso-sort.js';
|
|
21
|
+
export { default as MisoThreadsElement } from './miso-threads.js';
|
|
22
|
+
export { default as MisoNewThreadElement } from './miso-new-thread.js';
|
|
23
|
+
export { default as MisoTitleElement } from './miso-title.js';
|
|
24
|
+
export { default as MisoRenameElement } from './miso-rename.js';
|
|
25
|
+
export { default as MisoDeleteElement } from './miso-delete.js';
|
|
26
|
+
export { default as MisoSubscriptionElement } from './miso-subscription.js';
|
|
27
|
+
export { default as MisoMessagesElement } from './miso-messages.js';
|
|
21
28
|
export { default as MisoErrorElement } from './miso-error.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoDeleteElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.DELETE,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-delete';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoMessagesElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.MESSAGES,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-messages';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoNewThreadElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.NEW_THREAD,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-new-thread';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoRenameElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.RENAME,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-rename';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoSubscriptionElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.SUBSCRIPTION,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-subscription';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoThreadsElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.THREADS,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-threads';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import MisoComponentElement from './miso-component.js';
|
|
2
|
+
import { ROLE } from '../../constants.js';
|
|
3
|
+
|
|
4
|
+
export default class MisoTitleElement extends MisoComponentElement {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
role: ROLE.TITLE,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
static get tagName() {
|
|
13
|
+
return 'miso-title';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { CarouselItemViewabilityObserver, requestAnimationFrame as raf } from '@miso.ai/commons';
|
|
2
|
-
import { STATUS } from '../../constants.js';
|
|
2
|
+
import { STATUS, LAYOUT_TYPE } from '../../constants.js';
|
|
3
3
|
import CollectionLayout from '../list/collection.js';
|
|
4
4
|
import { affiliation, helpers } from '../templates.js';
|
|
5
5
|
import { TRIANGLE } from '../../asset/svgs.js';
|
|
6
6
|
import { setOrRemoveAttribute } from '../../util/dom.js';
|
|
7
7
|
|
|
8
|
-
const TYPE =
|
|
8
|
+
const TYPE = LAYOUT_TYPE.AFFILIATION;
|
|
9
9
|
const DEFAULT_CLASSNAME = 'miso-affiliation';
|
|
10
10
|
|
|
11
11
|
function root(layout, state) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { LAYOUT_TYPE } from '../../constants.js';
|
|
1
2
|
import TemplateBasedLayout from '../template.js';
|
|
2
3
|
import { LOGO } from '../svgs.js';
|
|
3
4
|
|
|
4
|
-
const TYPE =
|
|
5
|
+
const TYPE = LAYOUT_TYPE.BANNER;
|
|
5
6
|
const DEFAULT_CLASSNAME = 'miso-banner';
|
|
6
7
|
|
|
7
8
|
function root(layout) {
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { escapeHtml } from '@miso.ai/commons';
|
|
2
|
+
import { LAYOUT_TYPE } from '../../constants.js';
|
|
3
|
+
import TemplateBasedLayout from '../template.js';
|
|
4
|
+
import { getIcon } from '../../asset/svgs.js';
|
|
5
|
+
import prompt from '../../util/prompt.js';
|
|
6
|
+
import confirm from '../../util/confirm.js';
|
|
7
|
+
|
|
8
|
+
const TYPE = LAYOUT_TYPE.BUTTON;
|
|
9
|
+
const DEFAULT_CLASSNAME = 'miso-button';
|
|
10
|
+
|
|
11
|
+
function root(layout, state) {
|
|
12
|
+
const { className, role, templates } = layout;
|
|
13
|
+
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
14
|
+
const disabledAttr = layout._isDisabled(state) ? ' disabled' : '';
|
|
15
|
+
return `<button type="button" class="${className}"${roleAttr}${disabledAttr}>${templates.icon(layout, state)}${templates.text(layout, state)}</button>`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function icon(layout) {
|
|
19
|
+
const { icon } = layout.options;
|
|
20
|
+
return icon ? getIcon(icon) : '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function text(layout) {
|
|
24
|
+
const { className, options: { text } } = layout;
|
|
25
|
+
return text ? `<span class="${className}__text">${escapeHtml(text)}</span>` : '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const DEFAULT_TEMPLATES = Object.freeze({
|
|
29
|
+
root,
|
|
30
|
+
icon,
|
|
31
|
+
text,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A generic button: an icon and a label, both configurable (`icon` is an icon
|
|
36
|
+
* name, `text` the label; either can be omitted), emitting a `submit` view
|
|
37
|
+
* event when clicked — for the workflow to act on, per role.
|
|
38
|
+
*
|
|
39
|
+
* It carries no data of its own, so it renders in any state; use it for
|
|
40
|
+
* actions that stand apart from the data they act on, such as the new chat
|
|
41
|
+
* button (role `new_thread`) of the chat history interface.
|
|
42
|
+
*
|
|
43
|
+
* With a `prompt` option, the click asks for a text through the shared
|
|
44
|
+
* prompt dialog first, pre-filled with the control's current value — the
|
|
45
|
+
* role's mapped data value, as of the latest render — and the submit event
|
|
46
|
+
* carries the confirmed text as `value`; a cancelled, cleared, or unchanged
|
|
47
|
+
* dialog submits nothing. Use it for actions that take a text input, such
|
|
48
|
+
* as the rename button (role `rename`) of the conversation header, whose
|
|
49
|
+
* role maps to `'thread.title'`.
|
|
50
|
+
*
|
|
51
|
+
* With a `confirm` option, the click asks through the shared confirm dialog
|
|
52
|
+
* first, and submits only when confirmed; the option's `message` may be a
|
|
53
|
+
* function of the control's current value. Use it for destructive actions,
|
|
54
|
+
* such as the delete button (role `delete`) of a thread item's context menu.
|
|
55
|
+
*
|
|
56
|
+
* The control's current value is the role's mapped data value, put through
|
|
57
|
+
* the `value` option when given — map the role to a record and let `value`
|
|
58
|
+
* pick the text the dialogs work with. A `disabled` option (a boolean, or a
|
|
59
|
+
* function of the mapped value) renders the button's disabled state from
|
|
60
|
+
* the data, re-evaluated on every commit — e.g. rename/delete disable while
|
|
61
|
+
* their thread record has no thread id yet (a thread being created is not
|
|
62
|
+
* addressable), enabling in place when the resolution patches the record.
|
|
63
|
+
*/
|
|
64
|
+
export default class ButtonLayout extends TemplateBasedLayout {
|
|
65
|
+
|
|
66
|
+
static get type() {
|
|
67
|
+
return TYPE;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static get defaultTemplates() {
|
|
71
|
+
return DEFAULT_TEMPLATES;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static get defaultClassName() {
|
|
75
|
+
return DEFAULT_CLASSNAME;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
constructor({ className = DEFAULT_CLASSNAME, templates, ...options } = {}) {
|
|
79
|
+
super({
|
|
80
|
+
className,
|
|
81
|
+
templates: { ...DEFAULT_TEMPLATES, ...templates },
|
|
82
|
+
...options,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
initialize(view) {
|
|
87
|
+
this._unsubscribes = [
|
|
88
|
+
...this._unsubscribes,
|
|
89
|
+
view.proxyElement.on('click', event => this._handleClick(event)),
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_handleClick(event) {
|
|
94
|
+
// only left click
|
|
95
|
+
if (event.button !== 0) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const button = event.target.closest(`button.${this.className}`);
|
|
99
|
+
if (!button || button.disabled) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.options.prompt ? this._submitViaPrompt(event) :
|
|
103
|
+
this.options.confirm ? this._submitViaConfirm(event) :
|
|
104
|
+
this._submit(event);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
_submit(event, payload) {
|
|
108
|
+
const { session } = this._view._state || {};
|
|
109
|
+
this._view._emit('submit', { session, domEvent: event, ...payload });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async _submitViaPrompt(event) {
|
|
113
|
+
const current = this._currentValue();
|
|
114
|
+
const value = await prompt({
|
|
115
|
+
value: typeof current === 'string' ? current : '',
|
|
116
|
+
...this.options.prompt,
|
|
117
|
+
});
|
|
118
|
+
if (!value || value === current) {
|
|
119
|
+
return; // cancelled, cleared, or unchanged
|
|
120
|
+
}
|
|
121
|
+
this._submit(event, { value });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async _submitViaConfirm(event) {
|
|
125
|
+
const { message, ...options } = this.options.confirm;
|
|
126
|
+
const confirmed = await confirm({
|
|
127
|
+
...options,
|
|
128
|
+
message: typeof message === 'function' ? message(this._currentValue()) : message,
|
|
129
|
+
});
|
|
130
|
+
if (!confirmed) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this._submit(event);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The current value of the control: the role's mapped data value, as of
|
|
138
|
+
* the latest render, put through the `value` option when given.
|
|
139
|
+
*/
|
|
140
|
+
_currentValue() {
|
|
141
|
+
const state = this._element && this._rendered.get(this._element);
|
|
142
|
+
const raw = state && state.value;
|
|
143
|
+
const { value } = this.options;
|
|
144
|
+
return typeof value === 'function' ? value(raw) : raw;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
_isDisabled(state) {
|
|
148
|
+
const { disabled } = this.options;
|
|
149
|
+
return typeof disabled === 'function' ? !!disabled(state && state.value) : !!disabled;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { escapeHtml } from '@miso.ai/commons';
|
|
2
|
+
import { LAYOUT_TYPE } from '../../constants.js';
|
|
3
|
+
import ButtonLayout from './button.js';
|
|
4
|
+
import { getIcon } from '../../asset/svgs.js';
|
|
5
|
+
|
|
6
|
+
const TYPE = LAYOUT_TYPE.CHECKBOX;
|
|
7
|
+
const DEFAULT_CLASSNAME = 'miso-checkbox';
|
|
8
|
+
|
|
9
|
+
function root(layout, state) {
|
|
10
|
+
const { className, role, templates } = layout;
|
|
11
|
+
const checked = isChecked(state);
|
|
12
|
+
const roleAttr = role ? ` data-role="${role}"` : '';
|
|
13
|
+
const checkedAttr = checked ? ' data-checked' : '';
|
|
14
|
+
const disabledAttr = layout._isDisabled(state) ? ' disabled' : '';
|
|
15
|
+
return `<button type="button" class="${className}" role="switch" aria-checked="${checked}"${roleAttr}${checkedAttr}${disabledAttr}>${templates.icon(layout, state)}${templates.text(layout, state)}</button>`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function icon(layout, state) {
|
|
19
|
+
const { icon, checkedIcon = icon } = layout.options;
|
|
20
|
+
const name = isChecked(state) ? checkedIcon : icon;
|
|
21
|
+
return name ? getIcon(name) : '';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function text(layout, state) {
|
|
25
|
+
const { className, options: { text, checkedText = text } } = layout;
|
|
26
|
+
const value = isChecked(state) ? checkedText : text;
|
|
27
|
+
return value ? `<span class="${className}__text">${escapeHtml(value)}</span>` : '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// the checked state is the mapped data value, so it renders from data alone
|
|
31
|
+
function isChecked({ value } = {}) {
|
|
32
|
+
return value === true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const DEFAULT_TEMPLATES = Object.freeze({
|
|
36
|
+
root,
|
|
37
|
+
icon,
|
|
38
|
+
text,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A checkbox that looks like a button: an icon and a label, each with an
|
|
43
|
+
* optional checked variant (`icon`/`text` and `checkedIcon`/`checkedText`,
|
|
44
|
+
* the latter falling back to the former). It is a switch — semantically a
|
|
45
|
+
* checkbox (`role="switch"`, `aria-checked`), visually a button — for
|
|
46
|
+
* on/off state a user toggles, such as the answer-updates subscription of
|
|
47
|
+
* the conversation panel (role `subscription`).
|
|
48
|
+
*
|
|
49
|
+
* The checked state comes from the data (the mapped value is the boolean —
|
|
50
|
+
* e.g. role `subscription` maps to `'thread.subscribed'`), so a click emits
|
|
51
|
+
* a `change` view event carrying the requested state (`{ checked }`) and
|
|
52
|
+
* nothing else: the workflow acts on it and the new state arrives back down
|
|
53
|
+
* the data path, like any other rendering.
|
|
54
|
+
*/
|
|
55
|
+
export default class CheckboxLayout extends ButtonLayout {
|
|
56
|
+
|
|
57
|
+
static get type() {
|
|
58
|
+
return TYPE;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static get defaultTemplates() {
|
|
62
|
+
return DEFAULT_TEMPLATES;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static get defaultClassName() {
|
|
66
|
+
return DEFAULT_CLASSNAME;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
constructor({ className = DEFAULT_CLASSNAME, templates, ...options } = {}) {
|
|
70
|
+
super({
|
|
71
|
+
className,
|
|
72
|
+
templates: { ...DEFAULT_TEMPLATES, ...templates },
|
|
73
|
+
...options,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_handleClick(event) {
|
|
78
|
+
// only left click
|
|
79
|
+
if (event.button !== 0) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const button = event.target.closest(`button.${this.className}`);
|
|
83
|
+
if (!button || button.disabled) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// what the user toggles is the control's current value
|
|
87
|
+
const checked = this._currentValue() === true;
|
|
88
|
+
const { session } = this._view._state || {};
|
|
89
|
+
this._view._emit('change', { session, checked: !checked, domEvent: event });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { STATUS } from '../../constants.js';
|
|
2
|
-
import { fields } from '
|
|
1
|
+
import { STATUS, LAYOUT_TYPE } from '../../constants.js';
|
|
2
|
+
import { fields } from '@miso.ai/client-sdk-workflow';
|
|
3
3
|
import TemplateBasedLayout from '../template.js';
|
|
4
4
|
import { helpers } from '../templates.js';
|
|
5
5
|
|
|
6
|
-
const TYPE =
|
|
6
|
+
const TYPE = LAYOUT_TYPE.MORE_BUTTON;
|
|
7
7
|
const DEFAULT_CLASSNAME = 'miso-more-button';
|
|
8
8
|
|
|
9
9
|
function root(layout, state) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ROLE, STATUS } from '../../constants.js';
|
|
1
|
+
import { ROLE, STATUS, LAYOUT_TYPE } from '../../constants.js';
|
|
2
2
|
import RafLayout from '../raf.js';
|
|
3
3
|
import MisoBannerElement from '../../element/util/miso-banner.js';
|
|
4
4
|
import Viewables from '../../util/viewables.js';
|
|
5
5
|
import { setOrRemoveAttribute } from '../../util/dom.js';
|
|
6
6
|
|
|
7
|
-
const TYPE =
|
|
7
|
+
const TYPE = LAYOUT_TYPE.CONTAINER;
|
|
8
8
|
|
|
9
9
|
export default class ContainerLayout extends RafLayout {
|
|
10
10
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { LAYOUT_TYPE } from '../../constants.js';
|
|
2
|
+
import ContainerLayout from './container.js';
|
|
3
|
+
|
|
4
|
+
const TYPE = LAYOUT_TYPE.ITEM_CONTAINER;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The container layout of a collection's item subworkflow (a thread of the
|
|
8
|
+
* thread list, a message of the conversation panel): the standard container
|
|
9
|
+
* duties (status attributes, banner, trackings), plus the item-level
|
|
10
|
+
* behaviors — currently the context menu (vertical dots + popup).
|
|
11
|
+
*
|
|
12
|
+
* The menu is handled by contract, not rendered here: the item template
|
|
13
|
+
* supplies the markup (e.g. the threads layout's threadMenuBlock), marking
|
|
14
|
+
* the toggle button `data-role="item-menu-button"` and the popup
|
|
15
|
+
* `data-role="item-menu"`, and this layout drives their open/close behavior
|
|
16
|
+
* — toggle on the button; any other click on the item (a menu action
|
|
17
|
+
* included) closes it, and so does a click outside the item, which is also
|
|
18
|
+
* how opening one item's menu closes another's. The menu contents are
|
|
19
|
+
* typically role elements binding to the item workflow (e.g. the thread
|
|
20
|
+
* item's `<miso-rename>`/`<miso-delete>` buttons), so the actions stay the
|
|
21
|
+
* workflow's own controls. Collection shells treat clicks carrying the
|
|
22
|
+
* menu data-roles as item-internal (e.g. the threads layout does not
|
|
23
|
+
* select); an item template without menu markup simply has nothing to
|
|
24
|
+
* drive. Ownership is guarded: the layout only ever drives its own item's
|
|
25
|
+
* menu — a menu or click inside a nested container element is that
|
|
26
|
+
* container's own layout's — so the layout is inert on the list panel
|
|
27
|
+
* itself, whose options bag it shares with the items.
|
|
28
|
+
*/
|
|
29
|
+
export default class ItemContainerLayout extends ContainerLayout {
|
|
30
|
+
|
|
31
|
+
static get type() {
|
|
32
|
+
return TYPE;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
initialize(view) {
|
|
36
|
+
this._unsubscribes.push(view.proxyElement.on('click', event => this._handleClick(event)));
|
|
37
|
+
if (typeof document !== 'undefined') {
|
|
38
|
+
const onDocumentClick = (event) => {
|
|
39
|
+
const element = this._element;
|
|
40
|
+
if (element && !element.contains(event.target)) {
|
|
41
|
+
this._closeMenu();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
document.addEventListener('click', onDocumentClick);
|
|
45
|
+
this._unsubscribes.push(() => document.removeEventListener('click', onDocumentClick));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// menu //
|
|
50
|
+
_handleClick(event) {
|
|
51
|
+
// only left click
|
|
52
|
+
if (event.button !== 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// a click inside a nested container element belongs to that
|
|
56
|
+
// container's own layout (this layout may also host the list panel,
|
|
57
|
+
// whose subtree holds the items)
|
|
58
|
+
if (!this._owns(event.target)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (event.target.closest(`[data-role="item-menu-button"]`)) {
|
|
62
|
+
this._toggleMenu();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// any other click on the item — a menu action included — closes the menu
|
|
66
|
+
this._closeMenu();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_getMenu() {
|
|
70
|
+
const menu = this._element && this._element.querySelector(`[data-role="item-menu"]`);
|
|
71
|
+
// only its own item's menu: one found inside a nested container
|
|
72
|
+
// element is that container's own layout's to drive
|
|
73
|
+
return menu && this._owns(menu) ? menu : undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_owns(node) {
|
|
77
|
+
for (let el = node; el && el !== this._element; el = el.parentElement) {
|
|
78
|
+
if (el.isContainer) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_toggleMenu() {
|
|
86
|
+
const menu = this._getMenu();
|
|
87
|
+
if (menu) {
|
|
88
|
+
menu.hidden = !menu.hidden;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
_closeMenu() {
|
|
93
|
+
const menu = this._getMenu();
|
|
94
|
+
if (menu && !menu.hidden) {
|
|
95
|
+
menu.hidden = true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
}
|
package/src/layout/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export { default as TemplateBasedLayout } from './template.js';
|
|
2
2
|
export { default as ContainerLayout } from './container/container.js';
|
|
3
|
+
export { default as ItemContainerLayout } from './container/item-container.js';
|
|
3
4
|
export { default as ErrorLayout } from './error/error.js';
|
|
4
5
|
export { default as BannerLayout } from './banner/banner.js';
|
|
5
6
|
export { default as CollectionLayout } from './list/collection.js';
|
|
6
7
|
export { default as ListLayout } from './list/list.js';
|
|
8
|
+
export { default as ThreadsLayout } from './list/threads.js';
|
|
9
|
+
export { default as MessagesLayout } from './list/messages.js';
|
|
7
10
|
export { default as HorizontalLayout } from './list/horizontal.js';
|
|
8
11
|
export { default as CardsLayout } from './list/cards.js';
|
|
9
12
|
export { default as CarouselLayout } from './list/carousel.js';
|
|
@@ -12,8 +15,11 @@ export { default as SearchBoxLayout } from './input/search-box.js';
|
|
|
12
15
|
export { default as OptionListLayout } from './input/option-list.js';
|
|
13
16
|
export { default as FeedbackLayout } from './radio/feedback.js';
|
|
14
17
|
export { default as TextLayout } from './text/text.js';
|
|
18
|
+
export { default as QuestionLayout } from './text/question.js';
|
|
15
19
|
export { default as TypewriterLayout } from './text/typewriter/index.js';
|
|
16
20
|
export { default as AffiliationLayout } from './affiliation/affiliation.js';
|
|
17
21
|
export { default as FacetsLayout } from './input/facets.js';
|
|
18
22
|
export { default as SelectLayout } from './input/select.js';
|
|
19
23
|
export { default as MoreButtonLayout } from './button/more-button.js';
|
|
24
|
+
export { default as ButtonLayout } from './button/button.js';
|
|
25
|
+
export { default as CheckboxLayout } from './button/checkbox.js';
|