@tylertech/forge-ai 0.14.0 → 0.15.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/custom-elements.json +520 -278
- package/dist/ai-agent-selector/ai-agent-selector.mjs +1 -1
- package/dist/ai-chat-header/ai-chat-header.d.ts +5 -0
- package/dist/ai-chat-header/ai-chat-header.mjs +9 -3
- package/dist/ai-chat-header/ai-chat-header.scss.mjs +1 -1
- package/dist/ai-chatbot/agent-adapter.d.ts +1 -0
- package/dist/ai-chatbot/ai-chatbot-base.mjs +0 -1
- package/dist/ai-chatbot/ai-chatbot.d.ts +5 -1
- package/dist/ai-chatbot/ai-chatbot.mjs +18 -5
- package/dist/ai-chatbot/index.d.ts +1 -0
- package/dist/ai-chatbot/index.mjs +4 -1
- package/dist/ai-chatbot/message-state-controller.d.ts +8 -11
- package/dist/ai-chatbot/message-state-controller.mjs +7 -129
- package/dist/ai-chatbot/request-serialization.d.ts +33 -0
- package/dist/ai-chatbot/request-serialization.mjs +31 -0
- package/dist/ai-chatbot/types.d.ts +0 -73
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.d.ts +14 -2
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +47 -11
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.scss.mjs +1 -1
- package/dist/ai-conversations-panel/ai-conversations-panel.d.ts +10 -0
- package/dist/ai-conversations-panel/ai-conversations-panel.mjs +68 -7
- package/dist/ai-conversations-panel/ai-conversations-panel.scss.mjs +1 -1
- package/dist/ai-dialog/ai-dialog.mjs +1 -1
- package/dist/ai-dropdown-menu/ai-dropdown-menu.mjs +1 -1
- package/dist/ai-dropdown-menu/index.d.ts +1 -1
- package/dist/ai-edit-thread/ai-edit-thread.d.ts +5 -0
- package/dist/ai-edit-thread/ai-edit-thread.mjs +16 -9
- package/dist/ai-error-message/ai-error-message.d.ts +7 -1
- package/dist/ai-error-message/ai-error-message.mjs +40 -5
- package/dist/ai-error-message/ai-error-message.scss.mjs +1 -1
- package/dist/ai-error-message/index.d.ts +1 -0
- package/dist/ai-fab/ai-fab.d.ts +2 -0
- package/dist/ai-fab/ai-fab.mjs +5 -1
- package/dist/ai-icon-button/ai-icon-button.mjs +4 -1
- package/dist/ai-message-thread/ai-message-thread.mjs +1 -1
- package/dist/ai-sidebar/ai-sidebar.mjs +2 -2
- package/dist/ai-thread-actions-menu/ai-thread-actions-menu.d.ts +5 -0
- package/dist/ai-thread-actions-menu/ai-thread-actions-menu.mjs +6 -2
- package/dist/ai-threads-search/ai-threads-search.d.ts +13 -1
- package/dist/ai-threads-search/ai-threads-search.mjs +87 -30
- package/dist/ai-threads-search/ai-threads-search.scss.mjs +1 -1
- package/dist/ai-tool-call-indicator/ai-tool-call-indicator.scss.mjs +1 -1
- package/dist/ai-voice-input/ai-voice-input.mjs +2 -2
- package/dist/core/chatbot-core-controller.mjs +6 -8
- package/dist/index.mjs +4 -1
- package/package.json +1 -1
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
import { unsafeCSS, LitElement, html } from "lit";
|
|
2
|
-
import { customElement } from "lit/decorators.js";
|
|
2
|
+
import { property, queryAssignedNodes, customElement } from "lit/decorators.js";
|
|
3
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
3
4
|
import styles from "./ai-error-message.scss.mjs";
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
4
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __typeError = (msg) => {
|
|
8
|
+
throw TypeError(msg);
|
|
9
|
+
};
|
|
5
10
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
6
11
|
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
7
12
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
8
13
|
if (decorator = decorators[i])
|
|
9
|
-
result = decorator(result) || result;
|
|
14
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
15
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
16
|
return result;
|
|
11
17
|
};
|
|
18
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
19
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
20
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
21
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
22
|
+
var _AiErrorMessageComponent_instances, handleTitleSlotChange_fn, title_get;
|
|
12
23
|
const AiErrorMessageComponentTagName = "forge-ai-error-message";
|
|
13
24
|
let AiErrorMessageComponent = class extends LitElement {
|
|
25
|
+
constructor() {
|
|
26
|
+
super(...arguments);
|
|
27
|
+
__privateAdd(this, _AiErrorMessageComponent_instances);
|
|
28
|
+
this.density = "medium";
|
|
29
|
+
}
|
|
14
30
|
render() {
|
|
15
31
|
return html`
|
|
16
32
|
<div class="forge-inline-message">
|
|
@@ -25,9 +41,7 @@ let AiErrorMessageComponent = class extends LitElement {
|
|
|
25
41
|
<path fill="none" d="M0 0h24v24H0z" />
|
|
26
42
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m1 15h-2v-2h2zm0-4h-2V7h2z" />
|
|
27
43
|
</svg>
|
|
28
|
-
|
|
29
|
-
<slot name="title"></slot>
|
|
30
|
-
</div>
|
|
44
|
+
${__privateGet(this, _AiErrorMessageComponent_instances, title_get)}
|
|
31
45
|
<div class="forge-inline-message__content">
|
|
32
46
|
<slot></slot>
|
|
33
47
|
</div>
|
|
@@ -35,7 +49,28 @@ let AiErrorMessageComponent = class extends LitElement {
|
|
|
35
49
|
`;
|
|
36
50
|
}
|
|
37
51
|
};
|
|
52
|
+
_AiErrorMessageComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
53
|
+
handleTitleSlotChange_fn = function() {
|
|
54
|
+
this.requestUpdate();
|
|
55
|
+
};
|
|
56
|
+
title_get = function() {
|
|
57
|
+
const classes = classMap({
|
|
58
|
+
"forge-inline-message__title": true,
|
|
59
|
+
"forge-inline-message__title--empty": this._titleNodes.length === 0
|
|
60
|
+
});
|
|
61
|
+
return html`
|
|
62
|
+
<div class=${classes}>
|
|
63
|
+
<slot name="title" @slotchange=${__privateMethod(this, _AiErrorMessageComponent_instances, handleTitleSlotChange_fn)}></slot>
|
|
64
|
+
</div>
|
|
65
|
+
`;
|
|
66
|
+
};
|
|
38
67
|
AiErrorMessageComponent.styles = unsafeCSS(styles);
|
|
68
|
+
__decorateClass([
|
|
69
|
+
property({ type: String, reflect: true })
|
|
70
|
+
], AiErrorMessageComponent.prototype, "density", 2);
|
|
71
|
+
__decorateClass([
|
|
72
|
+
queryAssignedNodes({ slot: "title", flatten: true })
|
|
73
|
+
], AiErrorMessageComponent.prototype, "_titleNodes", 2);
|
|
39
74
|
AiErrorMessageComponent = __decorateClass([
|
|
40
75
|
customElement(AiErrorMessageComponentTagName)
|
|
41
76
|
], AiErrorMessageComponent);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const styles = '/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc.\n * License: Apache-2.0\n */\n.forge-inline-message {\n --_inline-message-background:var(--forge-inline-message-background, var(--forge-theme-info-container-low, #e3edf7));\n --_inline-message-color:var(--forge-inline-message-color, var(--forge-theme-text-high, rgba(0, 0, 0, 0.87)));\n --_inline-message-shape:var(--forge-inline-message-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_inline-message-padding:var(--forge-inline-message-padding, var(--forge-spacing-small, 12px));\n --_inline-message-padding-inline:var(--forge-inline-message-padding-inline, var(--_inline-message-padding));\n --_inline-message-padding-block:var(--forge-inline-message-padding-block, var(--_inline-message-padding));\n --_inline-message-border-width:var(--forge-inline-message-border-width, var(--forge-border-thin, 1px));\n --_inline-message-border-style:var(--forge-inline-message-border-style, none);\n --_inline-message-border-color:var(--forge-inline-message-border-color, var(--forge-theme-info-container, #c7daf0));\n --_inline-message-gap:var(--forge-inline-message-gap, var(--forge-spacing-small, 12px));\n --_inline-message-icon-gap:var(--forge-inline-message-icon-gap, var(--_inline-message-gap));\n --_inline-message-content-gap:var(--forge-inline-message-content-gap, var(--_inline-message-gap));\n --_inline-message-icon-color:var(--forge-inline-message-icon-color, var(--forge-theme-on-info-container-low, #0b3768));\n}\n\n.forge-inline-message {\n display: block;\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n background: var(--_inline-message-background);\n color: var(--_inline-message-color);\n border-radius: var(--_inline-message-shape);\n border-width: var(--_inline-message-border-width);\n border-style: var(--_inline-message-border-style);\n border-color: var(--_inline-message-border-color);\n display: flex;\n align-items: center;\n gap: var(--_inline-message-icon-gap);\n box-sizing: border-box;\n padding-inline: var(--_inline-message-padding-inline);\n padding-block: var(--_inline-message-padding-block);\n display: grid;\n grid-template-columns: auto 1fr;\n grid-template-rows: auto 1fr;\n}\n\n.forge-inline-message:not(:has(.forge-inline-message__icon)) {\n grid-template-columns: 1fr;\n}\n\n.forge-inline-message__title {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-heading1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-heading1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-heading1-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-heading1-font-weight, 500);\n line-height: var(--forge-typography-heading1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-heading1-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-heading1-letter-spacing, 0.0178571429em);\n text-transform: var(--forge-typography-heading1-text-transform, inherit);\n text-decoration: var(--forge-typography-heading1-text-decoration, inherit);\n}\n\n.forge-inline-message__icon {\n color: var(--_inline-message-icon-color);\n align-self: start;\n grid-row: 1/span 2;\n}\n\n:host {\n display: block;\n}\n\n.forge-inline-message {\n --forge-inline-message-background: var(--forge-theme-error-container-low, #f6e0e4);\n --forge-inline-message-color: var(--forge-theme-on-error-container-low, #5f0011);\n --forge-inline-message-icon-color: var(--forge-theme-on-error-container-low, #5f0011);\n --forge-inline-message-border-color: var(--forge-theme-error-container, #ecc2c9);\n --forge-inline-message-border-style: solid;\n}\n.forge-inline-message__title {\n font-weight: bold;\n}\n.forge-inline-message__content {\n overflow-wrap: anywhere;\n}\n\n::slotted(*) {\n margin-block: 0;\n overflow-wrap: anywhere;\n}';
|
|
1
|
+
const styles = '/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc.\n * License: Apache-2.0\n */\n.forge-inline-message {\n --_inline-message-background:var(--forge-inline-message-background, var(--forge-theme-info-container-low, #e3edf7));\n --_inline-message-color:var(--forge-inline-message-color, var(--forge-theme-text-high, rgba(0, 0, 0, 0.87)));\n --_inline-message-shape:var(--forge-inline-message-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_inline-message-padding:var(--forge-inline-message-padding, var(--forge-spacing-small, 12px));\n --_inline-message-padding-inline:var(--forge-inline-message-padding-inline, var(--_inline-message-padding));\n --_inline-message-padding-block:var(--forge-inline-message-padding-block, var(--_inline-message-padding));\n --_inline-message-border-width:var(--forge-inline-message-border-width, var(--forge-border-thin, 1px));\n --_inline-message-border-style:var(--forge-inline-message-border-style, none);\n --_inline-message-border-color:var(--forge-inline-message-border-color, var(--forge-theme-info-container, #c7daf0));\n --_inline-message-gap:var(--forge-inline-message-gap, var(--forge-spacing-small, 12px));\n --_inline-message-icon-gap:var(--forge-inline-message-icon-gap, var(--_inline-message-gap));\n --_inline-message-content-gap:var(--forge-inline-message-content-gap, var(--_inline-message-gap));\n --_inline-message-icon-color:var(--forge-inline-message-icon-color, var(--forge-theme-on-info-container-low, #0b3768));\n}\n\n.forge-inline-message {\n display: block;\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n background: var(--_inline-message-background);\n color: var(--_inline-message-color);\n border-radius: var(--_inline-message-shape);\n border-width: var(--_inline-message-border-width);\n border-style: var(--_inline-message-border-style);\n border-color: var(--_inline-message-border-color);\n display: flex;\n align-items: center;\n gap: var(--_inline-message-icon-gap);\n box-sizing: border-box;\n padding-inline: var(--_inline-message-padding-inline);\n padding-block: var(--_inline-message-padding-block);\n display: grid;\n grid-template-columns: auto 1fr;\n grid-template-rows: auto 1fr;\n}\n\n.forge-inline-message:not(:has(.forge-inline-message__icon)) {\n grid-template-columns: 1fr;\n}\n\n.forge-inline-message__title {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-heading1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-heading1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-heading1-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-heading1-font-weight, 500);\n line-height: var(--forge-typography-heading1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-heading1-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-heading1-letter-spacing, 0.0178571429em);\n text-transform: var(--forge-typography-heading1-text-transform, inherit);\n text-decoration: var(--forge-typography-heading1-text-decoration, inherit);\n}\n\n.forge-inline-message__icon {\n color: var(--_inline-message-icon-color);\n align-self: start;\n grid-row: 1/span 2;\n}\n\n:host {\n display: block;\n}\n\n.forge-inline-message {\n --forge-inline-message-background: var(--forge-theme-error-container-low, #f6e0e4);\n --forge-inline-message-color: var(--forge-theme-on-error-container-low, #5f0011);\n --forge-inline-message-icon-color: var(--forge-theme-on-error-container-low, #5f0011);\n --forge-inline-message-border-color: var(--forge-theme-error-container, #ecc2c9);\n --forge-inline-message-border-style: solid;\n}\n.forge-inline-message__title {\n font-weight: bold;\n}\n.forge-inline-message__title--empty {\n display: none;\n}\n.forge-inline-message__content {\n overflow-wrap: anywhere;\n}\n.forge-inline-message:has(.forge-inline-message__title--empty) {\n grid-template-rows: auto;\n}\n.forge-inline-message:has(.forge-inline-message__title--empty) .forge-inline-message__icon {\n grid-row: auto;\n align-self: center;\n}\n\n:host([density=small]) .forge-inline-message {\n --forge-inline-message-padding: var(--forge-spacing-xsmall, 8px);\n --forge-inline-message-gap: var(--forge-spacing-xsmall, 8px);\n --forge-inline-message-content-gap: var(--forge-spacing-xxsmall, 4px);\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body2-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body2-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 1)));\n font-weight: var(--forge-typography-body2-font-weight, 400);\n line-height: var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375)));\n letter-spacing: var(--forge-typography-body2-letter-spacing, 0.015625em);\n text-transform: var(--forge-typography-body2-text-transform, inherit);\n text-decoration: var(--forge-typography-body2-text-decoration, inherit);\n}\n:host([density=small]) .forge-inline-message__icon {\n height: 20px;\n width: 20px;\n}\n\n::slotted(*) {\n margin-block: 0;\n overflow-wrap: anywhere;\n}';
|
|
2
2
|
export {
|
|
3
3
|
styles as default
|
|
4
4
|
};
|
package/dist/ai-fab/ai-fab.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export declare class AiFabComponent extends LitElement {
|
|
|
22
22
|
disabled: boolean;
|
|
23
23
|
/** Whether the button is extended */
|
|
24
24
|
extended: boolean;
|
|
25
|
+
/** Accessible label for the button, announced by screen readers. */
|
|
26
|
+
label: string;
|
|
25
27
|
constructor();
|
|
26
28
|
willUpdate(changedProperties: PropertyValues<this>): void;
|
|
27
29
|
render(): TemplateResult;
|
package/dist/ai-fab/ai-fab.mjs
CHANGED
|
@@ -30,6 +30,7 @@ let AiFabComponent = class extends LitElement {
|
|
|
30
30
|
__privateAdd(this, _AiFabComponent_instances);
|
|
31
31
|
this.disabled = false;
|
|
32
32
|
this.extended = false;
|
|
33
|
+
this.label = "Launch chatbot";
|
|
33
34
|
__privateAdd(this, _internals);
|
|
34
35
|
__privateSet(this, _internals, this.attachInternals());
|
|
35
36
|
__privateMethod(this, _AiFabComponent_instances, setCssState_fn).call(this);
|
|
@@ -43,7 +44,7 @@ let AiFabComponent = class extends LitElement {
|
|
|
43
44
|
return html`
|
|
44
45
|
<forge-ai-gradient-container variant=${this.disabled ? "disabled" : "high"}>
|
|
45
46
|
<button
|
|
46
|
-
aria-label
|
|
47
|
+
aria-label=${this.label}
|
|
47
48
|
class="forge-fab ai-fab ${this.extended ? "forge-fab--small forge-fab--extended" : ""}"
|
|
48
49
|
.disabled=${this.disabled}>
|
|
49
50
|
<slot name="icon">
|
|
@@ -68,6 +69,9 @@ __decorateClass([
|
|
|
68
69
|
__decorateClass([
|
|
69
70
|
property({ type: Boolean, reflect: true })
|
|
70
71
|
], AiFabComponent.prototype, "extended", 2);
|
|
72
|
+
__decorateClass([
|
|
73
|
+
property({ type: String })
|
|
74
|
+
], AiFabComponent.prototype, "label", 2);
|
|
71
75
|
AiFabComponent = __decorateClass([
|
|
72
76
|
customElement(AiFabComponentTagName)
|
|
73
77
|
], AiFabComponent);
|
|
@@ -39,7 +39,10 @@ let AiIconButtonComponent = class extends LitElement {
|
|
|
39
39
|
}
|
|
40
40
|
render() {
|
|
41
41
|
return html`
|
|
42
|
-
<button
|
|
42
|
+
<button
|
|
43
|
+
aria-label="AI Icon Button"
|
|
44
|
+
class="forge-icon-button forge-icon-button--medium ai-icon-button"
|
|
45
|
+
.disabled=${this.disabled}>
|
|
43
46
|
<forge-ai-icon></forge-ai-icon>
|
|
44
47
|
</button>
|
|
45
48
|
`;
|
|
@@ -87,9 +87,9 @@ let AiMessageThreadComponent = class extends LitElement {
|
|
|
87
87
|
render() {
|
|
88
88
|
return html`
|
|
89
89
|
<div class="message-thread" @scroll=${this.autoScroll ? __privateGet(this, _handleScroll) : void 0}>
|
|
90
|
+
${__privateGet(this, _AiMessageThreadComponent_instances, scrollToBottomButton_get)}
|
|
90
91
|
<div class="message-thread-content">${__privateGet(this, _AiMessageThreadComponent_instances, emptyState_get)} ${__privateGet(this, _AiMessageThreadComponent_instances, messages_get)} ${__privateGet(this, _AiMessageThreadComponent_instances, thinkingIndicator_get)}</div>
|
|
91
92
|
</div>
|
|
92
|
-
${__privateGet(this, _AiMessageThreadComponent_instances, scrollToBottomButton_get)}
|
|
93
93
|
`;
|
|
94
94
|
}
|
|
95
95
|
};
|
|
@@ -85,9 +85,9 @@ let AiSidebarComponent = class extends LitElement {
|
|
|
85
85
|
<div
|
|
86
86
|
${ref(__privateGet(this, _resizeHandleRef))}
|
|
87
87
|
class=${classMap(handleClasses)}
|
|
88
|
-
role="
|
|
88
|
+
role="slider"
|
|
89
89
|
aria-orientation="vertical"
|
|
90
|
-
aria-label="Resize
|
|
90
|
+
aria-label="Resize chatbot panel, use left and right arrow keys"
|
|
91
91
|
aria-valuemin="${MIN_WIDTH}"
|
|
92
92
|
aria-valuemax="${MAX_WIDTH}"
|
|
93
93
|
aria-valuenow=${this._width}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LitElement, TemplateResult, CSSResult } from 'lit';
|
|
2
2
|
import { Thread } from '../ai-threads';
|
|
3
|
+
import { DropdownMenuDensity } from '../ai-dropdown-menu';
|
|
3
4
|
declare global {
|
|
4
5
|
interface HTMLElementTagNameMap {
|
|
5
6
|
'forge-ai-thread-actions-menu': AiThreadActionsMenuComponent;
|
|
@@ -40,5 +41,9 @@ export declare class AiThreadActionsMenuComponent extends LitElement {
|
|
|
40
41
|
thread: Thread;
|
|
41
42
|
showRename: boolean;
|
|
42
43
|
showDelete: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The density of the trigger button
|
|
46
|
+
*/
|
|
47
|
+
density: DropdownMenuDensity;
|
|
43
48
|
render(): TemplateResult;
|
|
44
49
|
}
|
|
@@ -28,15 +28,16 @@ let AiThreadActionsMenuComponent = class extends LitElement {
|
|
|
28
28
|
__privateAdd(this, _AiThreadActionsMenuComponent_instances);
|
|
29
29
|
this.showRename = false;
|
|
30
30
|
this.showDelete = false;
|
|
31
|
+
this.density = "small";
|
|
31
32
|
}
|
|
32
33
|
render() {
|
|
33
34
|
return html`
|
|
34
35
|
<forge-ai-dropdown-menu
|
|
35
36
|
variant="icon-button-squared"
|
|
36
|
-
density
|
|
37
|
+
density=${this.density}
|
|
37
38
|
selection-mode="none"
|
|
38
39
|
popover-placement="bottom-start"
|
|
39
|
-
trigger-label="
|
|
40
|
+
trigger-label="More actions for ${this.thread.title}"
|
|
40
41
|
@keydown=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuKeyDown_fn)}
|
|
41
42
|
@forge-ai-dropdown-menu-open=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuOpen_fn)}
|
|
42
43
|
@forge-ai-dropdown-menu-close=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuClose_fn)}
|
|
@@ -139,6 +140,9 @@ __decorateClass([
|
|
|
139
140
|
__decorateClass([
|
|
140
141
|
property({ type: Boolean, attribute: "show-delete" })
|
|
141
142
|
], AiThreadActionsMenuComponent.prototype, "showDelete", 2);
|
|
143
|
+
__decorateClass([
|
|
144
|
+
property()
|
|
145
|
+
], AiThreadActionsMenuComponent.prototype, "density", 2);
|
|
142
146
|
AiThreadActionsMenuComponent = __decorateClass([
|
|
143
147
|
customElement(AiThreadActionsMenuComponentTagName)
|
|
144
148
|
], AiThreadActionsMenuComponent);
|
|
@@ -13,6 +13,7 @@ declare global {
|
|
|
13
13
|
'forge-ai-threads-search-delete': CustomEvent<ForgeAiThreadsSearchDeleteEventData>;
|
|
14
14
|
'forge-ai-threads-search-delete-confirm': CustomEvent<ForgeAiThreadsSearchDeleteConfirmEventData>;
|
|
15
15
|
'forge-ai-threads-search-back': CustomEvent<void>;
|
|
16
|
+
'forge-ai-threads-search-retry': CustomEvent<void>;
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
export interface ForgeAiThreadsSearchQueryEventData {
|
|
@@ -57,6 +58,7 @@ export declare const AiThreadsSearchComponentTagName: keyof HTMLElementTagNameMa
|
|
|
57
58
|
* @event {CustomEvent<ForgeAiThreadsSearchDeleteEventData>} forge-ai-threads-search-delete - Fired when thread delete confirmed. Cancelable - if prevented, call onSuccess() to commit deletion or onError() to revert.
|
|
58
59
|
* @event {CustomEvent<ForgeAiThreadsSearchDeleteConfirmEventData>} forge-ai-threads-search-delete-confirm - Fired before showing the built-in delete confirmation. Cancelable - if prevented, this component shows no confirmation UI; the host must show its own and call confirmThreadDelete() once accepted.
|
|
59
60
|
* @event {CustomEvent<void>} forge-ai-threads-search-back - Fired when the back button (shown via showBackButton) is clicked.
|
|
61
|
+
* @event {CustomEvent<void>} forge-ai-threads-search-retry - Fired when the retry button in the error state is clicked. The host should re-request the threads and clear errorMessage once the load succeeds.
|
|
60
62
|
*
|
|
61
63
|
* @description A standalone search component for conversations/threads. Can be slotted into forge-ai-threads
|
|
62
64
|
* or used independently. Supports both local and external/async search patterns via event callbacks.
|
|
@@ -88,8 +90,18 @@ export declare class AiThreadsSearchComponent extends LitElement {
|
|
|
88
90
|
* infinite scroll entirely. Useful when all data is loaded upfront.
|
|
89
91
|
*/
|
|
90
92
|
totalChats: number;
|
|
93
|
+
/**
|
|
94
|
+
* Placeholder text for the search input. The input's aria-label is "Search" - avoid reusing
|
|
95
|
+
* that word here so screen readers don't announce the same word twice.
|
|
96
|
+
*/
|
|
91
97
|
placeholder: string;
|
|
92
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Message describing a failed thread load. When no threads are loaded, an error banner with a
|
|
100
|
+
* retry button replaces the empty state. When threads are already on screen the list stays visible
|
|
101
|
+
* and the message shows as a compact single line with a retry - at the bottom of the list if a page
|
|
102
|
+
* was in flight, otherwise above it. The host owns this value and should clear it once a load succeeds.
|
|
103
|
+
*/
|
|
104
|
+
errorMessage?: string;
|
|
93
105
|
showThreadRename: boolean;
|
|
94
106
|
showThreadDelete: boolean;
|
|
95
107
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { unsafeCSS, LitElement, html } from "lit";
|
|
1
|
+
import { unsafeCSS, LitElement, html, nothing } from "lit";
|
|
2
2
|
import { property, query, state, customElement } from "lit/decorators.js";
|
|
3
3
|
import { when } from "lit/directives/when.js";
|
|
4
4
|
import { formatRelativeTime } from "../utils.mjs";
|
|
@@ -6,6 +6,7 @@ import { DeleteThreadController } from "../utils/delete-thread-controller.mjs";
|
|
|
6
6
|
import { InfiniteScrollController } from "../utils/infinite-scroll-controller.mjs";
|
|
7
7
|
import "../ai-thread-actions-menu/ai-thread-actions-menu.mjs";
|
|
8
8
|
import "../ai-edit-thread/ai-edit-thread.mjs";
|
|
9
|
+
import "../ai-error-message/ai-error-message.mjs";
|
|
9
10
|
import "../ai-spinner/ai-spinner.mjs";
|
|
10
11
|
import "../ai-modal/ai-modal.mjs";
|
|
11
12
|
import styles from "./ai-threads-search.scss.mjs";
|
|
@@ -26,7 +27,7 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
|
|
|
26
27
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
27
28
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
28
29
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
29
|
-
var _deleteThreadController, _infiniteScrollController, _AiThreadsSearchComponent_instances, shouldEnablePagination_get, handleSearchInput_fn, performSearch_fn, loadMore_fn, handleThreadSelect_fn, handleNewChatClick_fn, handleBackClick_fn, handleMenuRename_fn, handleMenuOpen_fn, handleMenuClose_fn, handleMenuDeleteClick_fn, confirmDelete_fn, handleEditSave_fn, handleEditCancel_fn, handleClearSearch_fn, displayedThreads_get, header_get, searchField_get, renderThreadItem_fn, resultsList_get;
|
|
30
|
+
var _deleteThreadController, _infiniteScrollController, _AiThreadsSearchComponent_instances, shouldEnablePagination_get, handleSearchInput_fn, performSearch_fn, loadMore_fn, handleThreadSelect_fn, handleNewChatClick_fn, handleBackClick_fn, handleRetryClick_fn, handleMenuRename_fn, handleMenuOpen_fn, handleMenuClose_fn, handleMenuDeleteClick_fn, confirmDelete_fn, handleEditSave_fn, handleEditCancel_fn, handleClearSearch_fn, displayedThreads_get, header_get, searchField_get, renderThreadItem_fn, errorState_get, compactError_get, errorPlacement_get, emptyState_get, listFooter_get, resultsList_get;
|
|
30
31
|
const AiThreadsSearchComponentTagName = "forge-ai-threads-search";
|
|
31
32
|
let AiThreadsSearchComponent = class extends LitElement {
|
|
32
33
|
constructor() {
|
|
@@ -38,8 +39,7 @@ let AiThreadsSearchComponent = class extends LitElement {
|
|
|
38
39
|
this.showBackButton = false;
|
|
39
40
|
this.showSearch = true;
|
|
40
41
|
this.totalChats = 0;
|
|
41
|
-
this.placeholder = "
|
|
42
|
-
this.emptyMessage = "No chats found";
|
|
42
|
+
this.placeholder = "Find a chat";
|
|
43
43
|
this.showThreadRename = false;
|
|
44
44
|
this.showThreadDelete = false;
|
|
45
45
|
this.selectedThreadId = null;
|
|
@@ -88,7 +88,8 @@ let AiThreadsSearchComponent = class extends LitElement {
|
|
|
88
88
|
render() {
|
|
89
89
|
return html`
|
|
90
90
|
<div class="threads-search-container">
|
|
91
|
-
${__privateGet(this, _AiThreadsSearchComponent_instances, header_get)} ${when(this.showSearch, () => __privateGet(this, _AiThreadsSearchComponent_instances, searchField_get))}
|
|
91
|
+
${__privateGet(this, _AiThreadsSearchComponent_instances, header_get)} ${when(this.showSearch, () => __privateGet(this, _AiThreadsSearchComponent_instances, searchField_get))}
|
|
92
|
+
${when(__privateGet(this, _AiThreadsSearchComponent_instances, errorPlacement_get) === "above-list", () => __privateGet(this, _AiThreadsSearchComponent_instances, compactError_get))} ${__privateGet(this, _AiThreadsSearchComponent_instances, resultsList_get)}
|
|
92
93
|
</div>
|
|
93
94
|
${__privateGet(this, _deleteThreadController).template}
|
|
94
95
|
`;
|
|
@@ -181,6 +182,13 @@ handleBackClick_fn = function() {
|
|
|
181
182
|
});
|
|
182
183
|
this.dispatchEvent(event);
|
|
183
184
|
};
|
|
185
|
+
handleRetryClick_fn = function() {
|
|
186
|
+
const event = new CustomEvent("forge-ai-threads-search-retry", {
|
|
187
|
+
bubbles: true,
|
|
188
|
+
composed: true
|
|
189
|
+
});
|
|
190
|
+
this.dispatchEvent(event);
|
|
191
|
+
};
|
|
184
192
|
handleMenuRename_fn = function(e) {
|
|
185
193
|
this._editingThreadId = e.detail.id;
|
|
186
194
|
this._openMenuThreadId = null;
|
|
@@ -326,10 +334,12 @@ searchField_get = function() {
|
|
|
326
334
|
d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14" />
|
|
327
335
|
</svg>
|
|
328
336
|
<input
|
|
337
|
+
id="threads-search-input"
|
|
329
338
|
type="text"
|
|
330
339
|
autocomplete="off"
|
|
331
|
-
|
|
340
|
+
aria-label="Search"
|
|
332
341
|
placeholder=${this.placeholder}
|
|
342
|
+
.value=${this._searchQuery}
|
|
333
343
|
@input=${__privateMethod(this, _AiThreadsSearchComponent_instances, handleSearchInput_fn)} />
|
|
334
344
|
${when(this._isSearching, () => html`<forge-ai-spinner size="extra-small"></forge-ai-spinner>`)}
|
|
335
345
|
${when(
|
|
@@ -365,7 +375,10 @@ renderThreadItem_fn = function(thread) {
|
|
|
365
375
|
</forge-ai-edit-thread>
|
|
366
376
|
`,
|
|
367
377
|
() => html`
|
|
368
|
-
<button
|
|
378
|
+
<button
|
|
379
|
+
type="button"
|
|
380
|
+
aria-current=${isSelected ? "true" : nothing}
|
|
381
|
+
@click=${() => __privateMethod(this, _AiThreadsSearchComponent_instances, handleThreadSelect_fn).call(this, thread)}>
|
|
369
382
|
${thread.title}
|
|
370
383
|
</button>
|
|
371
384
|
<span class="thread-time">${formatRelativeTime(thread.createdAt)}</span>
|
|
@@ -390,31 +403,75 @@ renderThreadItem_fn = function(thread) {
|
|
|
390
403
|
</li>
|
|
391
404
|
`;
|
|
392
405
|
};
|
|
406
|
+
errorState_get = function() {
|
|
407
|
+
return html`
|
|
408
|
+
<div class="error-state">
|
|
409
|
+
<forge-ai-error-message density="small">
|
|
410
|
+
<span slot="title">Error</span>
|
|
411
|
+
<p class="error-state__message">${this.errorMessage}</p>
|
|
412
|
+
<button
|
|
413
|
+
class="forge-button forge-button--outlined forge-button--dense error-state__retry"
|
|
414
|
+
type="button"
|
|
415
|
+
@click=${__privateMethod(this, _AiThreadsSearchComponent_instances, handleRetryClick_fn)}>
|
|
416
|
+
Retry
|
|
417
|
+
</button>
|
|
418
|
+
</forge-ai-error-message>
|
|
419
|
+
</div>
|
|
420
|
+
`;
|
|
421
|
+
};
|
|
422
|
+
compactError_get = function() {
|
|
423
|
+
return html`
|
|
424
|
+
<forge-ai-error-message class="compact-error" density="small">
|
|
425
|
+
<div class="compact-error__body">
|
|
426
|
+
<span>${this.errorMessage}</span>
|
|
427
|
+
<button
|
|
428
|
+
class="forge-button forge-button--outlined forge-button--dense compact-error__retry"
|
|
429
|
+
type="button"
|
|
430
|
+
@click=${__privateMethod(this, _AiThreadsSearchComponent_instances, handleRetryClick_fn)}>
|
|
431
|
+
Retry
|
|
432
|
+
</button>
|
|
433
|
+
</div>
|
|
434
|
+
</forge-ai-error-message>
|
|
435
|
+
`;
|
|
436
|
+
};
|
|
437
|
+
errorPlacement_get = function() {
|
|
438
|
+
if (!this.errorMessage || __privateGet(this, _AiThreadsSearchComponent_instances, displayedThreads_get).length === 0) {
|
|
439
|
+
return "none";
|
|
440
|
+
}
|
|
441
|
+
return __privateGet(this, _infiniteScrollController).isLoadingMore ? "list-footer" : "above-list";
|
|
442
|
+
};
|
|
443
|
+
emptyState_get = function() {
|
|
444
|
+
const message = this._searchQuery.trim() ? "No chats found" : "No chats yet";
|
|
445
|
+
return html`
|
|
446
|
+
<div class="empty-state">
|
|
447
|
+
<p>${message}</p>
|
|
448
|
+
</div>
|
|
449
|
+
`;
|
|
450
|
+
};
|
|
451
|
+
listFooter_get = function() {
|
|
452
|
+
if (__privateGet(this, _AiThreadsSearchComponent_instances, errorPlacement_get) === "list-footer") {
|
|
453
|
+
return __privateGet(this, _AiThreadsSearchComponent_instances, compactError_get);
|
|
454
|
+
}
|
|
455
|
+
if (!__privateGet(this, _infiniteScrollController).isLoadingMore) {
|
|
456
|
+
return nothing;
|
|
457
|
+
}
|
|
458
|
+
return html`
|
|
459
|
+
<div class="loading-more-indicator">
|
|
460
|
+
<forge-ai-spinner></forge-ai-spinner>
|
|
461
|
+
</div>
|
|
462
|
+
`;
|
|
463
|
+
};
|
|
393
464
|
resultsList_get = function() {
|
|
394
465
|
const displayThreads = __privateGet(this, _AiThreadsSearchComponent_instances, displayedThreads_get);
|
|
466
|
+
if (displayThreads.length === 0) {
|
|
467
|
+
return html`<div class="results-container">${this.errorMessage ? __privateGet(this, _AiThreadsSearchComponent_instances, errorState_get) : __privateGet(this, _AiThreadsSearchComponent_instances, emptyState_get)}</div>`;
|
|
468
|
+
}
|
|
395
469
|
return html`
|
|
396
470
|
<div class="results-container">
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
<p>${this.emptyMessage}</p>
|
|
402
|
-
</div>
|
|
403
|
-
`,
|
|
404
|
-
() => html`
|
|
405
|
-
<ul class="forge-list forge-list--dense forge-list--navlist" role="list">
|
|
406
|
-
${displayThreads.map((thread) => __privateMethod(this, _AiThreadsSearchComponent_instances, renderThreadItem_fn).call(this, thread))}
|
|
407
|
-
</ul>
|
|
408
|
-
${when(
|
|
409
|
-
__privateGet(this, _infiniteScrollController).isLoadingMore,
|
|
410
|
-
() => html`
|
|
411
|
-
<div class="loading-more-indicator">
|
|
412
|
-
<forge-ai-spinner></forge-ai-spinner>
|
|
413
|
-
</div>
|
|
414
|
-
`
|
|
415
|
-
)}
|
|
416
|
-
`
|
|
417
|
-
)}
|
|
471
|
+
<ul class="forge-list forge-list--dense forge-list--navlist" role="list">
|
|
472
|
+
${displayThreads.map((thread) => __privateMethod(this, _AiThreadsSearchComponent_instances, renderThreadItem_fn).call(this, thread))}
|
|
473
|
+
</ul>
|
|
474
|
+
${__privateGet(this, _AiThreadsSearchComponent_instances, listFooter_get)}
|
|
418
475
|
</div>
|
|
419
476
|
`;
|
|
420
477
|
};
|
|
@@ -441,8 +498,8 @@ __decorateClass([
|
|
|
441
498
|
property({ type: String })
|
|
442
499
|
], AiThreadsSearchComponent.prototype, "placeholder", 2);
|
|
443
500
|
__decorateClass([
|
|
444
|
-
property({ type: String, attribute: "
|
|
445
|
-
], AiThreadsSearchComponent.prototype, "
|
|
501
|
+
property({ type: String, attribute: "error-message" })
|
|
502
|
+
], AiThreadsSearchComponent.prototype, "errorMessage", 2);
|
|
446
503
|
__decorateClass([
|
|
447
504
|
property({ type: Boolean, attribute: "show-thread-rename" })
|
|
448
505
|
], AiThreadsSearchComponent.prototype, "showThreadRename", 2);
|