agentgui 1.0.820 → 1.0.822
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/static/index.html +4 -0
- package/static/js/conv-list-renderer.js +197 -0
- package/static/js/conv-sidebar-actions.js +184 -0
- package/static/js/conv-sidebar-clone.js +91 -0
- package/static/js/conversations.js +116 -736
- package/static/js/ui-components.js +88 -187
- package/static/js/websocket-manager.js +107 -642
- package/static/js/ws-core.js +162 -0
|
@@ -1,187 +1,88 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
modal.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
container.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
b.classList.add('tab-active');
|
|
90
|
-
} else {
|
|
91
|
-
b.classList.remove('tab-active');
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
tabContent.querySelectorAll('.tab-pane').forEach((pane, i) => {
|
|
96
|
-
pane.style.display = i === index ? 'block' : 'none';
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
if (onChange) onChange(index);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
tabButtons.appendChild(btn);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
container.appendChild(tabButtons);
|
|
106
|
-
|
|
107
|
-
const tabContent = document.createElement('div');
|
|
108
|
-
tabContent.className = 'tab-content mt-4';
|
|
109
|
-
|
|
110
|
-
tabs.forEach((tab, index) => {
|
|
111
|
-
const pane = document.createElement('div');
|
|
112
|
-
pane.className = 'tab-pane';
|
|
113
|
-
pane.style.display = index === activeTab ? 'block' : 'none';
|
|
114
|
-
pane.innerHTML = typeof tab.content === 'string' ? tab.content : '';
|
|
115
|
-
tabContent.appendChild(pane);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
container.appendChild(tabContent);
|
|
119
|
-
return container;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
static createAlert(config = {}) {
|
|
123
|
-
const {
|
|
124
|
-
message = '',
|
|
125
|
-
type = 'info',
|
|
126
|
-
duration = 5000,
|
|
127
|
-
dismissible = true
|
|
128
|
-
} = config;
|
|
129
|
-
|
|
130
|
-
const alert = document.createElement('div');
|
|
131
|
-
const typeClasses = {
|
|
132
|
-
'info': 'alert-info',
|
|
133
|
-
'success': 'alert-success',
|
|
134
|
-
'warning': 'alert-warning',
|
|
135
|
-
'error': 'alert-error'
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
alert.className = `alert ${typeClasses[type] || typeClasses['info']}`;
|
|
139
|
-
alert.innerHTML = `
|
|
140
|
-
<div class="flex justify-between items-center">
|
|
141
|
-
<span>${UIComponents.escapeHtml(message)}</span>
|
|
142
|
-
${dismissible ? '<button class="text-current hover:opacity-75">×</button>' : ''}
|
|
143
|
-
</div>
|
|
144
|
-
`;
|
|
145
|
-
|
|
146
|
-
if (dismissible) {
|
|
147
|
-
const closeBtn = alert.querySelector('button');
|
|
148
|
-
closeBtn.addEventListener('click', () => alert.remove());
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (duration > 0) {
|
|
152
|
-
setTimeout(() => alert.remove(), duration);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return alert;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
static createSpinner(config = {}) {
|
|
159
|
-
const {
|
|
160
|
-
size = 'medium',
|
|
161
|
-
text = 'Loading...'
|
|
162
|
-
} = config;
|
|
163
|
-
|
|
164
|
-
const sizeClasses = {
|
|
165
|
-
'small': 'spinner-xs',
|
|
166
|
-
'medium': 'spinner-sm',
|
|
167
|
-
'large': 'spinner-md'
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const container = document.createElement('div');
|
|
171
|
-
container.className = 'flex items-center gap-3 justify-center p-4';
|
|
172
|
-
container.innerHTML = `
|
|
173
|
-
<div class="spinner-simple spinner-primary ${sizeClasses[size] || sizeClasses['medium']}"></div>
|
|
174
|
-
<span class="text-base-content">${UIComponents.escapeHtml(text)}</span>
|
|
175
|
-
`;
|
|
176
|
-
return container;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
static escapeHtml(text) {
|
|
180
|
-
return window._escHtml(text);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (typeof module !== 'undefined' && module.exports) {
|
|
186
|
-
module.exports = UIComponents;
|
|
187
|
-
}
|
|
1
|
+
class UIComponents {
|
|
2
|
+
static createModal(config = {}) {
|
|
3
|
+
const { title = 'Dialog', content = '', buttons = [], onClose = null, size = 'medium' } = config;
|
|
4
|
+
const modal = document.createElement('div');
|
|
5
|
+
modal.className = 'modal-overlay';
|
|
6
|
+
modal.dataset.modal = 'true';
|
|
7
|
+
const sizeClasses = { 'small': 'max-w-sm', 'medium': 'max-w-md', 'large': 'max-w-2xl' };
|
|
8
|
+
modal.innerHTML = `<div class="modal-content card ${sizeClasses[size] || sizeClasses['medium']}"><div class="card-header flex justify-between items-center"><h2 class="text-xl font-bold">${UIComponents.escapeHtml(title)}</h2><button class="btn btn-ghost btn-sm modal-close">×</button></div><div class="card-body modal-body">${typeof content === 'string' ? UIComponents.escapeHtml(content) : ''}</div><div class="card-footer flex gap-2 justify-end">${buttons.map(btn => `<button class="btn btn-${btn.variant || 'secondary'}" data-action="${btn.action || 'close'}">${UIComponents.escapeHtml(btn.label)}</button>`).join('')}</div></div>`;
|
|
9
|
+
const closeBtn = modal.querySelector('.modal-close');
|
|
10
|
+
closeBtn.addEventListener('click', () => { modal.remove(); if (onClose) onClose(); });
|
|
11
|
+
modal.querySelectorAll('[data-action]').forEach(btn => {
|
|
12
|
+
btn.addEventListener('click', (e) => { const action = e.target.dataset.action; if (action === 'close') { modal.remove(); if (onClose) onClose(); } });
|
|
13
|
+
});
|
|
14
|
+
modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); if (onClose) onClose(); } });
|
|
15
|
+
return modal;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static createTabs(config = {}) {
|
|
19
|
+
const { tabs = [], activeTab = 0, onChange = null } = config;
|
|
20
|
+
const container = document.createElement('div');
|
|
21
|
+
container.className = 'tabs';
|
|
22
|
+
const tabButtons = document.createElement('div');
|
|
23
|
+
tabButtons.className = 'tab-buttons flex border-b';
|
|
24
|
+
const tabContent = document.createElement('div');
|
|
25
|
+
tabContent.className = 'tab-content mt-4';
|
|
26
|
+
tabs.forEach((tab, index) => {
|
|
27
|
+
const btn = document.createElement('button');
|
|
28
|
+
btn.className = `tab tab-underline tab-button ${index === activeTab ? 'tab-active' : ''}`;
|
|
29
|
+
btn.textContent = tab.label;
|
|
30
|
+
btn.dataset.tabIndex = index;
|
|
31
|
+
btn.addEventListener('click', () => {
|
|
32
|
+
tabButtons.querySelectorAll('.tab-button').forEach((b, i) => b.classList.toggle('tab-active', i === index));
|
|
33
|
+
tabContent.querySelectorAll('.tab-pane').forEach((pane, i) => { pane.style.display = i === index ? 'block' : 'none'; });
|
|
34
|
+
if (onChange) onChange(index);
|
|
35
|
+
});
|
|
36
|
+
tabButtons.appendChild(btn);
|
|
37
|
+
const pane = document.createElement('div');
|
|
38
|
+
pane.className = 'tab-pane';
|
|
39
|
+
pane.style.display = index === activeTab ? 'block' : 'none';
|
|
40
|
+
pane.innerHTML = typeof tab.content === 'string' ? tab.content : '';
|
|
41
|
+
tabContent.appendChild(pane);
|
|
42
|
+
});
|
|
43
|
+
container.appendChild(tabButtons);
|
|
44
|
+
container.appendChild(tabContent);
|
|
45
|
+
return container;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static createAlert(config = {}) {
|
|
49
|
+
const { message = '', type = 'info', duration = 5000, dismissible = true } = config;
|
|
50
|
+
const alert = document.createElement('div');
|
|
51
|
+
const typeClasses = { 'info': 'alert-info', 'success': 'alert-success', 'warning': 'alert-warning', 'error': 'alert-error' };
|
|
52
|
+
alert.className = `alert ${typeClasses[type] || typeClasses['info']}`;
|
|
53
|
+
alert.innerHTML = `<div class="flex justify-between items-center"><span>${UIComponents.escapeHtml(message)}</span>${dismissible ? '<button class="text-current hover:opacity-75">×</button>' : ''}</div>`;
|
|
54
|
+
if (dismissible) alert.querySelector('button').addEventListener('click', () => alert.remove());
|
|
55
|
+
if (duration > 0) setTimeout(() => alert.remove(), duration);
|
|
56
|
+
return alert;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static createSpinner(config = {}) {
|
|
60
|
+
const { size = 'medium', text = 'Loading...' } = config;
|
|
61
|
+
const sizeClasses = { 'small': 'spinner-xs', 'medium': 'spinner-sm', 'large': 'spinner-md' };
|
|
62
|
+
const container = document.createElement('div');
|
|
63
|
+
container.className = 'flex items-center gap-3 justify-center p-4';
|
|
64
|
+
container.innerHTML = `<div class="spinner-simple spinner-primary ${sizeClasses[size] || sizeClasses['medium']}"></div><span class="text-base-content">${UIComponents.escapeHtml(text)}</span>`;
|
|
65
|
+
return container;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static createProgressBar(config = {}) {
|
|
69
|
+
const { percentage = 0, label = '', showLabel = true } = config;
|
|
70
|
+
const container = document.createElement('div');
|
|
71
|
+
container.className = 'progress-container';
|
|
72
|
+
let html = '';
|
|
73
|
+
if (label && showLabel) html += `<div class="flex justify-between mb-2 text-sm"><span>${UIComponents.escapeHtml(label)}</span><span>${Math.round(percentage)}%</span></div>`;
|
|
74
|
+
html += `<progress class="progress progress-primary progress-xs w-full" value="${Math.min(100, Math.max(0, percentage))}" max="100"></progress>`;
|
|
75
|
+
container.innerHTML = html;
|
|
76
|
+
return container;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static createCollapsible(config = {}) {
|
|
80
|
+
const { title = 'Details', content = '', isOpen = false } = config;
|
|
81
|
+
const container = document.createElement('div');
|
|
82
|
+
container.className = 'collapsible';
|
|
83
|
+
container.innerHTML = `<details ${isOpen ? 'open' : ''}><summary class="cursor-pointer font-semibold hover:bg-base-200 px-2 py-1 rounded transition-colors">${UIComponents.escapeHtml(title)}</summary><div class="content mt-2 ml-4">${typeof content === 'string' ? content : ''}</div></details>`;
|
|
84
|
+
return container;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (typeof module !== 'undefined' && module.exports) module.exports = UIComponents;
|