@tylertech/forge-ai 0.13.1 → 0.13.2
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 +3409 -1497
- package/dist/ai-agent-info/ai-agent-info.d.ts +1 -1
- package/dist/ai-agent-info/ai-agent-info.mjs +17 -62
- package/dist/ai-agent-info/ai-agent-info.scss.mjs +1 -1
- package/dist/ai-assistant-response/ai-assistant-response.scss.mjs +1 -1
- package/dist/ai-chat-header/ai-chat-header.d.ts +6 -0
- package/dist/ai-chat-header/ai-chat-header.mjs +51 -7
- package/dist/ai-chat-header/ai-chat-header.scss.mjs +1 -1
- package/dist/ai-chatbot/ai-chatbot-base.d.ts +37 -3
- package/dist/ai-chatbot/ai-chatbot-base.mjs +83 -24
- package/dist/ai-chatbot/ai-chatbot.d.ts +40 -1
- package/dist/ai-chatbot/ai-chatbot.mjs +242 -44
- package/dist/ai-chatbot/ai-chatbot.scss.mjs +1 -1
- package/dist/ai-chatbot/index.d.ts +1 -1
- package/dist/ai-chatbot/types.d.ts +39 -0
- package/dist/ai-chatbot/utils.d.ts +5 -0
- package/dist/ai-chatbot/utils.mjs +28 -0
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.d.ts +26 -0
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +155 -10
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.scss.mjs +1 -1
- package/dist/ai-confirmation-prompt/ai-confirmation-prompt.d.ts +6 -0
- package/dist/ai-confirmation-prompt/ai-confirmation-prompt.mjs +64 -19
- package/dist/ai-confirmation-prompt/ai-confirmation-prompt.scss.mjs +1 -1
- package/dist/ai-context-chip/ai-context-chip.d.ts +45 -0
- package/dist/ai-context-chip/ai-context-chip.mjs +169 -0
- package/dist/ai-context-chip/ai-context-chip.scss.mjs +4 -0
- package/dist/ai-context-chip/index.d.ts +2 -0
- package/dist/ai-context-chip/index.mjs +5 -0
- package/dist/ai-context-items/ai-context-items.d.ts +20 -0
- package/dist/ai-context-items/ai-context-items.mjs +78 -0
- package/dist/ai-context-items/ai-context-items.scss.mjs +4 -0
- package/dist/ai-context-items/index.d.ts +1 -0
- package/dist/ai-context-items/index.mjs +5 -0
- package/dist/ai-conversations-panel/ai-conversations-panel.d.ts +86 -0
- package/dist/ai-conversations-panel/ai-conversations-panel.mjs +558 -0
- package/dist/ai-conversations-panel/ai-conversations-panel.scss.mjs +4 -0
- package/dist/ai-conversations-panel/index.d.ts +2 -0
- package/dist/ai-conversations-panel/index.mjs +5 -0
- package/dist/ai-copy-button/ai-copy-button.d.ts +32 -0
- package/dist/ai-copy-button/ai-copy-button.mjs +116 -0
- package/dist/ai-copy-button/ai-copy-button.scss.mjs +4 -0
- package/dist/ai-copy-button/index.d.ts +1 -0
- package/dist/ai-copy-button/index.mjs +5 -0
- package/dist/ai-dialog/ai-dialog.scss.mjs +1 -1
- package/dist/ai-dropdown-menu/ai-dropdown-menu-item.scss.mjs +1 -1
- package/dist/ai-dropdown-menu/ai-dropdown-menu.d.ts +6 -1
- package/dist/ai-dropdown-menu/ai-dropdown-menu.mjs +14 -2
- package/dist/ai-dropdown-menu/ai-dropdown-menu.scss.mjs +1 -1
- package/dist/ai-edit-thread/ai-edit-thread.d.ts +34 -0
- package/dist/ai-edit-thread/ai-edit-thread.mjs +130 -0
- package/dist/ai-edit-thread/ai-edit-thread.scss.mjs +4 -0
- package/dist/ai-edit-thread/index.d.ts +1 -0
- package/dist/ai-edit-thread/index.mjs +5 -0
- package/dist/ai-message-thread/ai-message-thread.scss.mjs +1 -1
- package/dist/ai-modal/ai-modal.d.ts +11 -2
- package/dist/ai-modal/ai-modal.mjs +31 -6
- package/dist/ai-prompt/ai-prompt.d.ts +7 -1
- package/dist/ai-prompt/ai-prompt.mjs +29 -2
- package/dist/ai-sidebar/ai-sidebar.d.ts +11 -0
- package/dist/ai-sidebar/ai-sidebar.mjs +94 -4
- package/dist/ai-sidebar/ai-sidebar.scss.mjs +1 -1
- package/dist/ai-sidebar-chat/ai-sidebar-chat.d.ts +1 -0
- package/dist/ai-sidebar-chat/ai-sidebar-chat.mjs +5 -0
- package/dist/ai-spinner/ai-spinner.d.ts +1 -1
- package/dist/ai-spinner/ai-spinner.scss.mjs +1 -1
- package/dist/ai-thread-actions-menu/ai-thread-actions-menu.d.ts +44 -0
- package/dist/ai-thread-actions-menu/ai-thread-actions-menu.mjs +136 -0
- package/dist/ai-thread-actions-menu/ai-thread-actions-menu.scss.mjs +4 -0
- package/dist/ai-thread-actions-menu/index.d.ts +1 -0
- package/dist/ai-thread-actions-menu/index.mjs +5 -0
- package/dist/ai-threads/ai-threads.d.ts +45 -16
- package/dist/ai-threads/ai-threads.mjs +256 -98
- package/dist/ai-threads/ai-threads.scss.mjs +1 -1
- package/dist/ai-threads-search/ai-threads-search.d.ts +81 -0
- package/dist/ai-threads-search/ai-threads-search.mjs +414 -0
- package/dist/ai-threads-search/ai-threads-search.scss.mjs +4 -0
- package/dist/ai-threads-search/index.d.ts +1 -0
- package/dist/ai-threads-search/index.mjs +5 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.mjs +3 -1
- package/dist/core/resize-controller.d.ts +25 -0
- package/dist/core/resize-controller.mjs +144 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +21 -0
- package/dist/utils/delete-thread-controller.d.ts +14 -0
- package/dist/utils/delete-thread-controller.mjs +80 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.mjs +8 -0
- package/dist/utils/infinite-scroll-controller.d.ts +33 -0
- package/dist/utils/infinite-scroll-controller.mjs +95 -0
- package/package.json +14 -14
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { unsafeCSS, LitElement, html } from "lit";
|
|
2
|
+
import { property, customElement } from "lit/decorators.js";
|
|
3
|
+
import { when } from "lit/directives/when.js";
|
|
4
|
+
import "../ai-dropdown-menu/ai-dropdown-menu.mjs";
|
|
5
|
+
import "../ai-dropdown-menu/ai-dropdown-menu-item.mjs";
|
|
6
|
+
import styles from "./ai-thread-actions-menu.scss.mjs";
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __typeError = (msg) => {
|
|
10
|
+
throw TypeError(msg);
|
|
11
|
+
};
|
|
12
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
13
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
14
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
15
|
+
if (decorator = decorators[i])
|
|
16
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
17
|
+
if (kind && result) __defProp(target, key, result);
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
21
|
+
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);
|
|
22
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
23
|
+
var _AiThreadActionsMenuComponent_instances, handleMenuOpen_fn, handleMenuClose_fn, handleMenuKeyDown_fn, handleMenuSelect_fn, handleRenameClick_fn, handleDeleteClick_fn;
|
|
24
|
+
const AiThreadActionsMenuComponentTagName = "forge-ai-thread-actions-menu";
|
|
25
|
+
let AiThreadActionsMenuComponent = class extends LitElement {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
__privateAdd(this, _AiThreadActionsMenuComponent_instances);
|
|
29
|
+
this.showRename = false;
|
|
30
|
+
this.showDelete = false;
|
|
31
|
+
}
|
|
32
|
+
render() {
|
|
33
|
+
return html`
|
|
34
|
+
<forge-ai-dropdown-menu
|
|
35
|
+
variant="icon-button-squared"
|
|
36
|
+
density="small"
|
|
37
|
+
selection-mode="none"
|
|
38
|
+
popover-placement="bottom-start"
|
|
39
|
+
@keydown=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuKeyDown_fn)}
|
|
40
|
+
@forge-ai-dropdown-menu-open=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuOpen_fn)}
|
|
41
|
+
@forge-ai-dropdown-menu-close=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuClose_fn)}
|
|
42
|
+
@click=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleMenuSelect_fn)}>
|
|
43
|
+
<slot name="trigger-icon" slot="trigger-content">
|
|
44
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="forge-icon">
|
|
45
|
+
<path
|
|
46
|
+
d="M12 16a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2 2 2 0 0 1 2-2m0-6a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2 2 2 0 0 1 2-2m0-6a2 2 0 0 1 2 2 2 2 0 0 1-2 2 2 2 0 0 1-2-2 2 2 0 0 1 2-2" />
|
|
47
|
+
</svg>
|
|
48
|
+
</slot>
|
|
49
|
+
|
|
50
|
+
${when(
|
|
51
|
+
this.showRename,
|
|
52
|
+
() => html`
|
|
53
|
+
<forge-ai-dropdown-menu-item value="rename" @click=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleRenameClick_fn)}>
|
|
54
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" slot="start" class="forge-icon">
|
|
55
|
+
<path
|
|
56
|
+
d="m15 16-4 4h10v-4zm-2.94-8.81L3 16.25V20h3.75l9.06-9.06zm6.65.85c.39-.39.39-1.04 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75z" />
|
|
57
|
+
</svg>
|
|
58
|
+
<span>Rename</span>
|
|
59
|
+
</forge-ai-dropdown-menu-item>
|
|
60
|
+
`
|
|
61
|
+
)}
|
|
62
|
+
${when(
|
|
63
|
+
this.showDelete,
|
|
64
|
+
() => html`
|
|
65
|
+
<forge-ai-dropdown-menu-item value="delete" @click=${__privateMethod(this, _AiThreadActionsMenuComponent_instances, handleDeleteClick_fn)}>
|
|
66
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" slot="start" class="forge-icon">
|
|
67
|
+
<path d="M19 4h-3.5l-1-1h-5l-1 1H5v2h14M6 19a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7H6z" />
|
|
68
|
+
</svg>
|
|
69
|
+
<span>Delete</span>
|
|
70
|
+
</forge-ai-dropdown-menu-item>
|
|
71
|
+
`
|
|
72
|
+
)}
|
|
73
|
+
</forge-ai-dropdown-menu>
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
_AiThreadActionsMenuComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
78
|
+
handleMenuOpen_fn = function() {
|
|
79
|
+
const event = new CustomEvent("forge-ai-thread-actions-menu-open", {
|
|
80
|
+
detail: { id: this.thread.id },
|
|
81
|
+
bubbles: true,
|
|
82
|
+
composed: true
|
|
83
|
+
});
|
|
84
|
+
this.dispatchEvent(event);
|
|
85
|
+
};
|
|
86
|
+
handleMenuClose_fn = function() {
|
|
87
|
+
const event = new CustomEvent("forge-ai-thread-actions-menu-close", {
|
|
88
|
+
bubbles: true,
|
|
89
|
+
composed: true
|
|
90
|
+
});
|
|
91
|
+
this.dispatchEvent(event);
|
|
92
|
+
};
|
|
93
|
+
handleMenuKeyDown_fn = function(evt) {
|
|
94
|
+
if (evt.key === "Escape") {
|
|
95
|
+
evt.stopPropagation();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
handleMenuSelect_fn = function(evt) {
|
|
99
|
+
evt.stopPropagation();
|
|
100
|
+
};
|
|
101
|
+
handleRenameClick_fn = function() {
|
|
102
|
+
const event = new CustomEvent("forge-ai-thread-actions-menu-rename", {
|
|
103
|
+
detail: { id: this.thread.id },
|
|
104
|
+
bubbles: true,
|
|
105
|
+
composed: true
|
|
106
|
+
});
|
|
107
|
+
this.dispatchEvent(event);
|
|
108
|
+
};
|
|
109
|
+
handleDeleteClick_fn = function() {
|
|
110
|
+
const event = new CustomEvent(
|
|
111
|
+
"forge-ai-thread-actions-menu-delete-click",
|
|
112
|
+
{
|
|
113
|
+
detail: { id: this.thread.id },
|
|
114
|
+
bubbles: true,
|
|
115
|
+
composed: true
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
this.dispatchEvent(event);
|
|
119
|
+
};
|
|
120
|
+
AiThreadActionsMenuComponent.styles = unsafeCSS(styles);
|
|
121
|
+
__decorateClass([
|
|
122
|
+
property({ type: Object })
|
|
123
|
+
], AiThreadActionsMenuComponent.prototype, "thread", 2);
|
|
124
|
+
__decorateClass([
|
|
125
|
+
property({ type: Boolean, attribute: "show-rename" })
|
|
126
|
+
], AiThreadActionsMenuComponent.prototype, "showRename", 2);
|
|
127
|
+
__decorateClass([
|
|
128
|
+
property({ type: Boolean, attribute: "show-delete" })
|
|
129
|
+
], AiThreadActionsMenuComponent.prototype, "showDelete", 2);
|
|
130
|
+
AiThreadActionsMenuComponent = __decorateClass([
|
|
131
|
+
customElement(AiThreadActionsMenuComponentTagName)
|
|
132
|
+
], AiThreadActionsMenuComponent);
|
|
133
|
+
export {
|
|
134
|
+
AiThreadActionsMenuComponent,
|
|
135
|
+
AiThreadActionsMenuComponentTagName
|
|
136
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const styles = "/**\n * @license\n * Copyright Tyler Technologies, Inc.\n * License: Apache-2.0\n */\n.forge-icon {\n --_icon-color:var(--forge-icon-color, currentColor);\n --_icon-size:var(--forge-icon-size, 1em);\n --_icon-width:var(--forge-icon-width, var(--_icon-size));\n --_icon-height:var(--forge-icon-height, var(--_icon-size));\n --_icon-font-size:var(--forge-icon-font-size, calc(var(--forge-typography-font-size, 1rem) * 1.5));\n}\n\nimg.forge-icon, svg.forge-icon {\n display: inline-block;\n box-sizing: content-box;\n contain: content;\n font-size: var(--_icon-font-size);\n display: inline-block;\n}\n\nimg.forge-icon {\n width: var(--_icon-width);\n height: var(--_icon-height);\n}\n\nsvg {\n width: var(--_icon-width);\n height: var(--_icon-height);\n display: block;\n fill: var(--_icon-color);\n stroke: var(--_icon-color);\n stroke-width: 0;\n}\n\n:host {\n display: flex;\n}\n\nforge-ai-dropdown-menu {\n display: flex;\n}\n\n.forge-icon {\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n}";
|
|
2
|
+
export {
|
|
3
|
+
styles as default
|
|
4
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ai-thread-actions-menu';
|
|
@@ -6,48 +6,77 @@ declare global {
|
|
|
6
6
|
interface HTMLElementEventMap {
|
|
7
7
|
'forge-ai-threads-select': CustomEvent<ForgeAiThreadsSelectEventData>;
|
|
8
8
|
'forge-ai-threads-new-chat': CustomEvent;
|
|
9
|
-
'forge-ai-threads-
|
|
9
|
+
'forge-ai-threads-search-chats': CustomEvent;
|
|
10
|
+
'forge-ai-threads-load-more': CustomEvent<ForgeAiThreadsLoadMoreEventData>;
|
|
11
|
+
'forge-ai-threads-rename': CustomEvent<ForgeAiThreadsRenameEventData>;
|
|
12
|
+
'forge-ai-threads-delete': CustomEvent<ForgeAiThreadsDeleteEventData>;
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
15
|
export interface Thread {
|
|
13
16
|
id: string;
|
|
14
17
|
title: string;
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
createdAt: string;
|
|
19
|
+
updatedAt?: string;
|
|
20
|
+
messageCount?: number;
|
|
17
21
|
}
|
|
18
22
|
export interface ForgeAiThreadsSelectEventData {
|
|
19
23
|
id: string;
|
|
20
24
|
title: string;
|
|
21
25
|
}
|
|
26
|
+
export interface ForgeAiThreadsLoadMoreEventData {
|
|
27
|
+
appendResults: (results: Thread[]) => void;
|
|
28
|
+
}
|
|
29
|
+
export interface ForgeAiThreadsRenameEventData {
|
|
30
|
+
id: string;
|
|
31
|
+
oldTitle: string;
|
|
32
|
+
newTitle: string;
|
|
33
|
+
onSuccess: () => void;
|
|
34
|
+
onError: (error?: string) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface ForgeAiThreadsDeleteEventData {
|
|
37
|
+
id: string;
|
|
38
|
+
thread: Thread;
|
|
39
|
+
onSuccess: () => void;
|
|
40
|
+
onError: (error?: string) => void;
|
|
41
|
+
}
|
|
22
42
|
export declare const AiThreadsComponentTagName: keyof HTMLElementTagNameMap;
|
|
23
43
|
/**
|
|
24
44
|
* @tag forge-ai-threads
|
|
25
45
|
*
|
|
26
|
-
* @slot - Default slot for chatbot component
|
|
46
|
+
* @slot - Default slot for chatbot launcher component
|
|
27
47
|
*
|
|
28
48
|
* @event {CustomEvent<ForgeAiThreadsSelectEventData>} forge-ai-threads-select - Fired when a thread is selected.
|
|
29
49
|
* @event {CustomEvent} forge-ai-threads-new-chat - Fired when the new chat button is clicked.
|
|
30
|
-
* @event {CustomEvent} forge-ai-threads-
|
|
50
|
+
* @event {CustomEvent} forge-ai-threads-search-chats - Fired when the search chats button is clicked.
|
|
51
|
+
* @event {CustomEvent<ForgeAiThreadsLoadMoreEventData>} forge-ai-threads-load-more - Fired when scrolling near bottom. Call appendResults([]) to signal end.
|
|
52
|
+
* @event {CustomEvent<ForgeAiThreadsRenameEventData>} forge-ai-threads-rename - Fired when thread renamed. Cancelable - if prevented, call onSuccess() to commit or onError() to revert.
|
|
53
|
+
* @event {CustomEvent<ForgeAiThreadsDeleteEventData>} forge-ai-threads-delete - Fired when thread delete confirmed. Cancelable - if prevented, call onSuccess() to commit deletion or onError() to revert.
|
|
31
54
|
*
|
|
32
|
-
* @description A form factor component that positions a slotted chatbot alongside a thread navigation drawer.
|
|
33
|
-
* Manages thread list and selection while delegating chat functionality to the slotted
|
|
34
|
-
* All
|
|
55
|
+
* @description A form factor component that positions a slotted chatbot launcher alongside a thread navigation drawer.
|
|
56
|
+
* Manages thread list and selection while delegating chat functionality to the slotted launcher.
|
|
57
|
+
* All launcher events bubble through unchanged.
|
|
35
58
|
*/
|
|
36
59
|
export declare class AiThreadsComponent extends LitElement {
|
|
37
60
|
#private;
|
|
38
61
|
static styles: CSSResult;
|
|
39
62
|
/** Array of threads to display in the navigation list */
|
|
40
63
|
threads: Thread[];
|
|
41
|
-
/**
|
|
42
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Total number of threads available. When set to a positive number and fewer threads
|
|
66
|
+
* are loaded than the total, infinite scroll is enabled. Leave at 0 (default) to disable
|
|
67
|
+
* infinite scroll entirely. Useful when all data is loaded upfront.
|
|
68
|
+
*/
|
|
69
|
+
totalChats: number;
|
|
70
|
+
showThreadRename: boolean;
|
|
71
|
+
showThreadDelete: boolean;
|
|
72
|
+
private _threadListContainer;
|
|
43
73
|
/** Currently selected thread ID */
|
|
44
74
|
private _selectedThreadId;
|
|
45
|
-
private
|
|
46
|
-
private
|
|
75
|
+
private _editingThreadId;
|
|
76
|
+
private _hiddenThreadIds;
|
|
77
|
+
private _openMenuThreadId;
|
|
78
|
+
firstUpdated(): void;
|
|
79
|
+
updated(changedProperties: Map<string, unknown>): void;
|
|
47
80
|
private _handleThreadSelect;
|
|
48
|
-
private _handleNewChatClick;
|
|
49
|
-
private _handleChatbotExpand;
|
|
50
|
-
private _handleChatbotMinimize;
|
|
51
|
-
private _handleClearHistoryClick;
|
|
52
81
|
render(): TemplateResult;
|
|
53
82
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import { unsafeCSS, LitElement, html } from "lit";
|
|
2
|
-
import { property,
|
|
1
|
+
import { unsafeCSS, LitElement, html, nothing } from "lit";
|
|
2
|
+
import { property, query, state, customElement } from "lit/decorators.js";
|
|
3
|
+
import { when } from "lit/directives/when.js";
|
|
4
|
+
import { DeleteThreadController } from "../utils/delete-thread-controller.mjs";
|
|
5
|
+
import { InfiniteScrollController } from "../utils/infinite-scroll-controller.mjs";
|
|
6
|
+
import "../ai-icon/ai-icon.mjs";
|
|
7
|
+
import "../ai-spinner/ai-spinner.mjs";
|
|
8
|
+
import "../ai-thread-actions-menu/ai-thread-actions-menu.mjs";
|
|
9
|
+
import "../ai-edit-thread/ai-edit-thread.mjs";
|
|
10
|
+
import "../ai-modal/ai-modal.mjs";
|
|
3
11
|
import styles from "./ai-threads.scss.mjs";
|
|
4
12
|
var __defProp = Object.defineProperty;
|
|
5
13
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -17,39 +25,91 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
17
25
|
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
18
26
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
19
27
|
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);
|
|
20
|
-
var
|
|
28
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
29
|
+
var _deleteThreadController, _infiniteScrollController, _AiThreadsComponent_instances, shouldEnablePagination_get, handleNewChatClick_fn, handleSearchChatsClick_fn, handleLoadMore_fn, handleMenuRename_fn, handleMenuOpen_fn, handleMenuClose_fn, handleMenuDeleteClick_fn, handleEditSave_fn, handleEditCancel_fn, threadList_get, _chatActionsList, _chatsLabel, loadingMoreIndicator_get, threadListContainer_get, drawer_get, _slotContent;
|
|
21
30
|
const AiThreadsComponentTagName = "forge-ai-threads";
|
|
22
31
|
let AiThreadsComponent = class extends LitElement {
|
|
23
32
|
constructor() {
|
|
24
33
|
super(...arguments);
|
|
25
34
|
__privateAdd(this, _AiThreadsComponent_instances);
|
|
26
35
|
this.threads = [];
|
|
27
|
-
this.
|
|
36
|
+
this.totalChats = 0;
|
|
37
|
+
this.showThreadRename = false;
|
|
38
|
+
this.showThreadDelete = false;
|
|
28
39
|
this._selectedThreadId = null;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
this._editingThreadId = null;
|
|
41
|
+
this._hiddenThreadIds = /* @__PURE__ */ new Set();
|
|
42
|
+
this._openMenuThreadId = null;
|
|
43
|
+
__privateAdd(this, _deleteThreadController, new DeleteThreadController(this, {
|
|
44
|
+
onConfirm: (thread) => {
|
|
45
|
+
const onSuccess = () => {
|
|
46
|
+
this._hiddenThreadIds.add(thread.id);
|
|
47
|
+
this.requestUpdate();
|
|
48
|
+
};
|
|
49
|
+
const onError = (error) => {
|
|
50
|
+
this._hiddenThreadIds.delete(thread.id);
|
|
51
|
+
this.requestUpdate();
|
|
52
|
+
if (error) {
|
|
53
|
+
console.error("Delete failed:", error);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const event = new CustomEvent("forge-ai-threads-delete", {
|
|
57
|
+
detail: { id: thread.id, thread, onSuccess, onError },
|
|
58
|
+
bubbles: true,
|
|
59
|
+
composed: true,
|
|
60
|
+
cancelable: true
|
|
61
|
+
});
|
|
62
|
+
const dispatched = this.dispatchEvent(event);
|
|
63
|
+
if (dispatched) {
|
|
64
|
+
this._hiddenThreadIds.add(thread.id);
|
|
65
|
+
this.requestUpdate();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
__privateAdd(this, _infiniteScrollController, new InfiniteScrollController(this, {
|
|
70
|
+
onLoadMore: () => __privateMethod(this, _AiThreadsComponent_instances, handleLoadMore_fn).call(this)
|
|
71
|
+
}));
|
|
72
|
+
__privateAdd(this, _chatActionsList, html`
|
|
73
|
+
<ul class="forge-list forge-list--dense forge-list--navlist chat-actions-list" role="list">
|
|
74
|
+
<li class="forge-list-item" role="listitem">
|
|
75
|
+
<button @click=${__privateMethod(this, _AiThreadsComponent_instances, handleNewChatClick_fn)}>
|
|
76
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="forge-icon">
|
|
77
|
+
<path
|
|
78
|
+
d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H5.2L4 17.2V4h16zm-4-7v2h-3v3h-2v-3H8V9h3V6h2v3z" />
|
|
79
|
+
</svg>
|
|
80
|
+
<span>New chat</span>
|
|
81
|
+
</button>
|
|
82
|
+
</li>
|
|
83
|
+
<li class="forge-list-item" role="listitem">
|
|
84
|
+
<button @click=${__privateMethod(this, _AiThreadsComponent_instances, handleSearchChatsClick_fn)}>
|
|
85
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="forge-icon">
|
|
86
|
+
<path
|
|
87
|
+
d="M9 6v2H2V6zm0 5v2H2v-2zm9 5v2H2v-2zm1.31-4.5c.44-.68.69-1.5.69-2.39 0-2.5-2-4.5-4.5-4.5s-4.5 2-4.5 4.5 2 4.5 4.5 4.5c.87 0 1.69-.25 2.38-.68L21 16l1.39-1.39zm-3.81.11c-1.38 0-2.5-1.11-2.5-2.5s1.12-2.5 2.5-2.5a2.5 2.5 0 0 1 0 5" />
|
|
88
|
+
</svg>
|
|
89
|
+
<span>All chats</span>
|
|
90
|
+
</button>
|
|
91
|
+
</li>
|
|
92
|
+
</ul>
|
|
49
93
|
`);
|
|
94
|
+
__privateAdd(this, _chatsLabel, html`<div class="chats-label">Recent chats</div>`);
|
|
95
|
+
__privateAdd(this, _slotContent, html`<slot></slot>`);
|
|
96
|
+
}
|
|
97
|
+
firstUpdated() {
|
|
98
|
+
if (__privateGet(this, _AiThreadsComponent_instances, shouldEnablePagination_get) && this._threadListContainer) {
|
|
99
|
+
__privateGet(this, _infiniteScrollController).attach(this._threadListContainer);
|
|
100
|
+
}
|
|
50
101
|
}
|
|
51
|
-
|
|
52
|
-
|
|
102
|
+
updated(changedProperties) {
|
|
103
|
+
if (changedProperties.has("threads") || changedProperties.has("totalChats")) {
|
|
104
|
+
__privateGet(this, _infiniteScrollController).reset();
|
|
105
|
+
if (__privateGet(this, _AiThreadsComponent_instances, shouldEnablePagination_get)) {
|
|
106
|
+
if (this._threadListContainer) {
|
|
107
|
+
__privateGet(this, _infiniteScrollController).attach(this._threadListContainer);
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
__privateGet(this, _infiniteScrollController).detach();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
53
113
|
}
|
|
54
114
|
_handleThreadSelect(thread) {
|
|
55
115
|
this._selectedThreadId = thread.id;
|
|
@@ -61,102 +121,185 @@ let AiThreadsComponent = class extends LitElement {
|
|
|
61
121
|
});
|
|
62
122
|
this.dispatchEvent(event);
|
|
63
123
|
}
|
|
64
|
-
_handleNewChatClick() {
|
|
65
|
-
const event = new CustomEvent("forge-ai-threads-new-chat", {
|
|
66
|
-
bubbles: true,
|
|
67
|
-
composed: true,
|
|
68
|
-
cancelable: true
|
|
69
|
-
});
|
|
70
|
-
this.dispatchEvent(event);
|
|
71
|
-
}
|
|
72
|
-
_handleChatbotExpand() {
|
|
73
|
-
if (__privateGet(this, _AiThreadsComponent_instances, chatbot_get)) {
|
|
74
|
-
__privateGet(this, _AiThreadsComponent_instances, chatbot_get).expanded = !__privateGet(this, _AiThreadsComponent_instances, chatbot_get).expanded;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
_handleChatbotMinimize() {
|
|
78
|
-
if (__privateGet(this, _AiThreadsComponent_instances, chatbot_get)) {
|
|
79
|
-
__privateGet(this, _AiThreadsComponent_instances, chatbot_get).expanded = false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
_handleClearHistoryClick() {
|
|
83
|
-
const event = new CustomEvent("forge-ai-threads-clear-history", {
|
|
84
|
-
bubbles: true,
|
|
85
|
-
composed: true,
|
|
86
|
-
cancelable: true
|
|
87
|
-
});
|
|
88
|
-
this.dispatchEvent(event);
|
|
89
|
-
}
|
|
90
124
|
render() {
|
|
91
125
|
return html`
|
|
92
126
|
<div class="threads-container">
|
|
93
|
-
<div class="
|
|
94
|
-
<div class="
|
|
127
|
+
<div class="drawer">${__privateGet(this, _AiThreadsComponent_instances, drawer_get)}</div>
|
|
128
|
+
<div class="body">${__privateGet(this, _slotContent)}</div>
|
|
95
129
|
</div>
|
|
130
|
+
${__privateGet(this, _deleteThreadController).template}
|
|
96
131
|
`;
|
|
97
132
|
}
|
|
98
133
|
};
|
|
134
|
+
_deleteThreadController = /* @__PURE__ */ new WeakMap();
|
|
135
|
+
_infiniteScrollController = /* @__PURE__ */ new WeakMap();
|
|
99
136
|
_AiThreadsComponent_instances = /* @__PURE__ */ new WeakSet();
|
|
100
|
-
|
|
101
|
-
|
|
137
|
+
shouldEnablePagination_get = function() {
|
|
138
|
+
if (this.totalChats <= 0) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
const displayedCount = this.threads.filter((t) => !this._hiddenThreadIds.has(t.id)).length;
|
|
142
|
+
return displayedCount < this.totalChats;
|
|
102
143
|
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
144
|
+
handleNewChatClick_fn = function() {
|
|
145
|
+
const event = new CustomEvent("forge-ai-threads-new-chat", {
|
|
146
|
+
bubbles: true,
|
|
147
|
+
composed: true,
|
|
148
|
+
cancelable: true
|
|
149
|
+
});
|
|
150
|
+
this.dispatchEvent(event);
|
|
151
|
+
};
|
|
152
|
+
handleSearchChatsClick_fn = function() {
|
|
153
|
+
const event = new CustomEvent("forge-ai-threads-search-chats", {
|
|
154
|
+
bubbles: true,
|
|
155
|
+
composed: true,
|
|
156
|
+
cancelable: true
|
|
157
|
+
});
|
|
158
|
+
this.dispatchEvent(event);
|
|
159
|
+
};
|
|
160
|
+
handleLoadMore_fn = function() {
|
|
161
|
+
const appendResults = (results) => {
|
|
162
|
+
if (results.length === 0) {
|
|
163
|
+
__privateGet(this, _infiniteScrollController).setHasMore(false);
|
|
164
|
+
} else {
|
|
165
|
+
this.threads = [...this.threads, ...results];
|
|
166
|
+
}
|
|
167
|
+
__privateGet(this, _infiniteScrollController).setLoadingState(false);
|
|
168
|
+
};
|
|
169
|
+
const event = new CustomEvent("forge-ai-threads-load-more", {
|
|
170
|
+
detail: { appendResults },
|
|
171
|
+
bubbles: true,
|
|
172
|
+
composed: true
|
|
173
|
+
});
|
|
174
|
+
this.dispatchEvent(event);
|
|
175
|
+
};
|
|
176
|
+
handleMenuRename_fn = function(e) {
|
|
177
|
+
this._editingThreadId = e.detail.id;
|
|
178
|
+
this._openMenuThreadId = null;
|
|
179
|
+
};
|
|
180
|
+
handleMenuOpen_fn = function(e) {
|
|
181
|
+
this._openMenuThreadId = e.detail.id;
|
|
182
|
+
};
|
|
183
|
+
handleMenuClose_fn = function() {
|
|
184
|
+
this._openMenuThreadId = null;
|
|
185
|
+
};
|
|
186
|
+
handleMenuDeleteClick_fn = function(e) {
|
|
187
|
+
const { id } = e.detail;
|
|
188
|
+
const displayedThreads = this.threads.filter((t) => !this._hiddenThreadIds.has(t.id));
|
|
189
|
+
const thread = displayedThreads.find((t) => t.id === id);
|
|
190
|
+
if (!thread) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
__privateGet(this, _deleteThreadController).show(thread);
|
|
194
|
+
};
|
|
195
|
+
handleEditSave_fn = function(e) {
|
|
196
|
+
const { id, oldTitle, newTitle } = e.detail;
|
|
197
|
+
const displayedThreads = this.threads.filter((t) => !this._hiddenThreadIds.has(t.id));
|
|
198
|
+
const targetThread = displayedThreads.find((t) => t.id === id);
|
|
199
|
+
if (!targetThread) {
|
|
200
|
+
return;
|
|
106
201
|
}
|
|
107
|
-
|
|
202
|
+
const onSuccess = () => {
|
|
203
|
+
targetThread.title = newTitle;
|
|
204
|
+
this.requestUpdate();
|
|
205
|
+
};
|
|
206
|
+
const onError = (error) => {
|
|
207
|
+
targetThread.title = oldTitle;
|
|
208
|
+
this.requestUpdate();
|
|
209
|
+
if (error) {
|
|
210
|
+
console.error("Rename failed:", error);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const event = new CustomEvent("forge-ai-threads-rename", {
|
|
214
|
+
detail: { id, oldTitle, newTitle, onSuccess, onError },
|
|
215
|
+
bubbles: true,
|
|
216
|
+
composed: true,
|
|
217
|
+
cancelable: true
|
|
218
|
+
});
|
|
219
|
+
const dispatched = this.dispatchEvent(event);
|
|
220
|
+
if (dispatched) {
|
|
221
|
+
targetThread.title = newTitle;
|
|
222
|
+
this.requestUpdate();
|
|
223
|
+
}
|
|
224
|
+
this._editingThreadId = null;
|
|
225
|
+
};
|
|
226
|
+
handleEditCancel_fn = function() {
|
|
227
|
+
this._editingThreadId = null;
|
|
108
228
|
};
|
|
109
|
-
_searchField = /* @__PURE__ */ new WeakMap();
|
|
110
229
|
threadList_get = function() {
|
|
230
|
+
const displayedThreads = this.threads.filter((t) => !this._hiddenThreadIds.has(t.id));
|
|
111
231
|
return html`
|
|
112
|
-
<ul class="forge-list forge-list--navlist">
|
|
113
|
-
${
|
|
232
|
+
<ul class="forge-list forge-list--dense forge-list--navlist" role="list">
|
|
233
|
+
${displayedThreads.map((thread) => {
|
|
114
234
|
const isSelected = this._selectedThreadId === thread.id;
|
|
235
|
+
const isEditing = this._editingThreadId === thread.id;
|
|
236
|
+
const hasOpenMenu = this._openMenuThreadId === thread.id;
|
|
115
237
|
return html`
|
|
116
|
-
<li
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
238
|
+
<li
|
|
239
|
+
class="forge-list-item ${isSelected ? "forge-list-item--selected" : ""} ${hasOpenMenu ? "forge-list-item--menu-open" : ""}"
|
|
240
|
+
role="listitem">
|
|
241
|
+
${when(
|
|
242
|
+
isEditing,
|
|
243
|
+
() => html`
|
|
244
|
+
<forge-ai-edit-thread
|
|
245
|
+
.thread=${thread}
|
|
246
|
+
.value=${thread.title}
|
|
247
|
+
@forge-ai-edit-thread-save=${__privateMethod(this, _AiThreadsComponent_instances, handleEditSave_fn)}
|
|
248
|
+
@forge-ai-edit-thread-cancel=${__privateMethod(this, _AiThreadsComponent_instances, handleEditCancel_fn)}>
|
|
249
|
+
</forge-ai-edit-thread>
|
|
250
|
+
`,
|
|
251
|
+
() => html`
|
|
252
|
+
<button @click=${() => this._handleThreadSelect(thread)} aria-selected=${isSelected}>
|
|
253
|
+
<span>${thread.title}</span>
|
|
254
|
+
</button>
|
|
255
|
+
${when(
|
|
256
|
+
this.showThreadRename || this.showThreadDelete,
|
|
257
|
+
() => html`
|
|
258
|
+
<div class="thread-item-actions">
|
|
259
|
+
<forge-ai-thread-actions-menu
|
|
260
|
+
.thread=${thread}
|
|
261
|
+
?show-rename=${this.showThreadRename}
|
|
262
|
+
?show-delete=${this.showThreadDelete}
|
|
263
|
+
@forge-ai-thread-actions-menu-rename=${__privateMethod(this, _AiThreadsComponent_instances, handleMenuRename_fn)}
|
|
264
|
+
@forge-ai-thread-actions-menu-delete-click=${__privateMethod(this, _AiThreadsComponent_instances, handleMenuDeleteClick_fn)}
|
|
265
|
+
@forge-ai-thread-actions-menu-open=${__privateMethod(this, _AiThreadsComponent_instances, handleMenuOpen_fn)}
|
|
266
|
+
@forge-ai-thread-actions-menu-close=${__privateMethod(this, _AiThreadsComponent_instances, handleMenuClose_fn)}>
|
|
267
|
+
</forge-ai-thread-actions-menu>
|
|
268
|
+
</div>
|
|
269
|
+
`
|
|
270
|
+
)}
|
|
271
|
+
`
|
|
272
|
+
)}
|
|
124
273
|
</li>
|
|
125
274
|
`;
|
|
126
275
|
})}
|
|
127
276
|
</ul>
|
|
128
277
|
`;
|
|
129
278
|
};
|
|
130
|
-
|
|
279
|
+
_chatActionsList = /* @__PURE__ */ new WeakMap();
|
|
280
|
+
_chatsLabel = /* @__PURE__ */ new WeakMap();
|
|
281
|
+
loadingMoreIndicator_get = function() {
|
|
282
|
+
if (!__privateGet(this, _infiniteScrollController).isLoadingMore) {
|
|
283
|
+
return nothing;
|
|
284
|
+
}
|
|
131
285
|
return html`
|
|
132
|
-
<
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
</svg>
|
|
136
|
-
Clear history
|
|
137
|
-
</button>
|
|
286
|
+
<div class="loading-more-indicator">
|
|
287
|
+
<forge-ai-spinner size="small"></forge-ai-spinner>
|
|
288
|
+
</div>
|
|
138
289
|
`;
|
|
139
290
|
};
|
|
140
291
|
threadListContainer_get = function() {
|
|
141
|
-
return html` <div class="thread-list-container">${__privateGet(this, _AiThreadsComponent_instances, threadList_get)} ${__privateGet(this, _AiThreadsComponent_instances,
|
|
142
|
-
};
|
|
143
|
-
newChatButton_get = function() {
|
|
144
|
-
return html`
|
|
145
|
-
<button class="forge-button forge-button--tonal" @click=${this._handleNewChatClick}>
|
|
146
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="forge-icon">
|
|
147
|
-
<path fill="none" d="M0 0h24v24H0z" />
|
|
148
|
-
<path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z" />
|
|
149
|
-
</svg>
|
|
150
|
-
New chat
|
|
151
|
-
</button>
|
|
152
|
-
`;
|
|
292
|
+
return html` <div class="thread-list-container">${__privateGet(this, _AiThreadsComponent_instances, threadList_get)} ${__privateGet(this, _AiThreadsComponent_instances, loadingMoreIndicator_get)}</div> `;
|
|
153
293
|
};
|
|
154
294
|
drawer_get = function() {
|
|
295
|
+
const displayedThreads = this.threads.filter((t) => !this._hiddenThreadIds.has(t.id));
|
|
296
|
+
const hasThreads = displayedThreads.length > 0;
|
|
155
297
|
return html`
|
|
156
|
-
<aside class="forge-drawer">
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
298
|
+
<aside class="forge-drawer" role="complementary" aria-label="Thread navigation">
|
|
299
|
+
<slot name="header"></slot>
|
|
300
|
+
${__privateGet(this, _chatActionsList)}
|
|
301
|
+
<slot name="actions"></slot>
|
|
302
|
+
${when(hasThreads, () => html`${__privateGet(this, _chatsLabel)} ${__privateGet(this, _AiThreadsComponent_instances, threadListContainer_get)}`)}
|
|
160
303
|
</aside>
|
|
161
304
|
`;
|
|
162
305
|
};
|
|
@@ -166,14 +309,29 @@ __decorateClass([
|
|
|
166
309
|
property({ type: Array })
|
|
167
310
|
], AiThreadsComponent.prototype, "threads", 2);
|
|
168
311
|
__decorateClass([
|
|
169
|
-
|
|
170
|
-
], AiThreadsComponent.prototype, "
|
|
312
|
+
property({ type: Number, attribute: "total-chats" })
|
|
313
|
+
], AiThreadsComponent.prototype, "totalChats", 2);
|
|
314
|
+
__decorateClass([
|
|
315
|
+
property({ type: Boolean, attribute: "show-thread-rename" })
|
|
316
|
+
], AiThreadsComponent.prototype, "showThreadRename", 2);
|
|
317
|
+
__decorateClass([
|
|
318
|
+
property({ type: Boolean, attribute: "show-thread-delete" })
|
|
319
|
+
], AiThreadsComponent.prototype, "showThreadDelete", 2);
|
|
320
|
+
__decorateClass([
|
|
321
|
+
query(".thread-list-container")
|
|
322
|
+
], AiThreadsComponent.prototype, "_threadListContainer", 2);
|
|
171
323
|
__decorateClass([
|
|
172
324
|
state()
|
|
173
325
|
], AiThreadsComponent.prototype, "_selectedThreadId", 2);
|
|
174
326
|
__decorateClass([
|
|
175
|
-
|
|
176
|
-
], AiThreadsComponent.prototype, "
|
|
327
|
+
state()
|
|
328
|
+
], AiThreadsComponent.prototype, "_editingThreadId", 2);
|
|
329
|
+
__decorateClass([
|
|
330
|
+
state()
|
|
331
|
+
], AiThreadsComponent.prototype, "_hiddenThreadIds", 2);
|
|
332
|
+
__decorateClass([
|
|
333
|
+
state()
|
|
334
|
+
], AiThreadsComponent.prototype, "_openMenuThreadId", 2);
|
|
177
335
|
AiThreadsComponent = __decorateClass([
|
|
178
336
|
customElement(AiThreadsComponentTagName)
|
|
179
337
|
], AiThreadsComponent);
|