Skip to content

Commit 5d2332b

Browse files
Refactor home templates
1 parent c4fd9d9 commit 5d2332b

File tree

6 files changed

+396
-323
lines changed

6 files changed

+396
-323
lines changed

static/js/home.js

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
// Global variable for attached resources
2+
let attachedResources = [];
3+
4+
function showServerModal(serverName) {
5+
const modalText = document.getElementById('serverModalText');
6+
modalText.textContent = `Server: ${serverName}`;
7+
const modal = new bootstrap.Modal(document.getElementById('serverModal'));
8+
modal.show();
9+
}
10+
11+
function handleKeyPress(event, formID) {
12+
if (event.key === 'Enter') {
13+
if (!event.shiftKey) {
14+
event.preventDefault();
15+
htmx.trigger(formID, 'submit');
16+
}
17+
}
18+
// Auto-expand height
19+
adjustHeight(event.target);
20+
}
21+
22+
function adjustHeight(element) {
23+
element.style.height = 'auto';
24+
element.style.height = (element.scrollHeight) + 'px';
25+
}
26+
27+
function showPromptModal(promptIndex) {
28+
const promptData = promptsList[promptIndex];
29+
if (!promptData) {
30+
console.error('Prompt not found at index:', promptIndex);
31+
return;
32+
}
33+
34+
// Set the modal title and description
35+
document.getElementById('promptModalLabel').textContent = `Prompt: ${promptData.name}`;
36+
const descElem = document.getElementById('promptDescription');
37+
descElem.textContent = promptData.description || '';
38+
39+
// Get the form element where we'll add the inputs
40+
const argContainer = document.getElementById('promptArguments');
41+
argContainer.innerHTML = '';
42+
43+
// Create input fields for each argument
44+
if (promptData.arguments && promptData.arguments.length > 0) {
45+
promptData.arguments.forEach(arg => {
46+
const formGroup = document.createElement('div');
47+
formGroup.className = 'mb-3';
48+
49+
const label = document.createElement('label');
50+
label.htmlFor = `arg-${arg.name}`;
51+
label.className = 'form-label';
52+
label.textContent = arg.name;
53+
if (arg.required) {
54+
label.textContent += ' *';
55+
}
56+
57+
const input = document.createElement('input');
58+
input.type = 'text';
59+
input.className = 'form-control';
60+
input.id = `arg-${arg.name}`;
61+
input.name = arg.name;
62+
input.required = arg.required;
63+
64+
formGroup.appendChild(label);
65+
formGroup.appendChild(input);
66+
67+
if (arg.description) {
68+
const helpText = document.createElement('div');
69+
helpText.className = 'form-text';
70+
helpText.textContent = arg.description;
71+
formGroup.appendChild(helpText);
72+
}
73+
74+
argContainer.appendChild(formGroup);
75+
});
76+
} else {
77+
// If there are no arguments, show a message
78+
const noArgsMsg = document.createElement('p');
79+
noArgsMsg.textContent = 'This prompt has no arguments.';
80+
argContainer.appendChild(noArgsMsg);
81+
}
82+
83+
// Set up the "Use Prompt" button handler
84+
document.getElementById('usePromptBtn').onclick = function() {
85+
// Collect prompt data and arguments
86+
const args = {};
87+
const promptName = promptData.name;
88+
89+
if (promptData.arguments) {
90+
promptData.arguments.forEach(arg => {
91+
const input = document.getElementById(`arg-${arg.name}`);
92+
if (input) {
93+
args[arg.name] = input.value;
94+
}
95+
});
96+
}
97+
98+
// Determine which form to use
99+
const isWelcomePage = document.getElementById('chat-form-welcome') !== null;
100+
const formId = isWelcomePage ? 'chat-form-welcome' : 'chat-form-chatbox';
101+
const form = document.getElementById(formId);
102+
103+
// Get the textarea and temporarily remove required attribute
104+
const textarea = form.querySelector('textarea[name="message"]');
105+
textarea.removeAttribute('required');
106+
107+
// Clear the message field and set prompt data
108+
textarea.value = '';
109+
form.querySelector('input[name="prompt_name"]').value = promptName;
110+
form.querySelector('input[name="prompt_args"]').value = JSON.stringify(args);
111+
112+
// Set up a one-time event listener for after the request completes
113+
form.addEventListener('htmx:afterRequest', function afterRequest() {
114+
// Restore the required attribute and clear prompt fields
115+
textarea.setAttribute('required', '');
116+
form.querySelector('input[name="prompt_name"]').value = '';
117+
form.querySelector('input[name="prompt_args"]').value = '';
118+
119+
// Remove this event listener to prevent it from firing on future requests
120+
form.removeEventListener('htmx:afterRequest', afterRequest);
121+
}, { once: true });
122+
123+
// Submit the form
124+
htmx.trigger(form, 'submit');
125+
126+
// Close the modal
127+
bootstrap.Modal.getInstance(document.getElementById('promptModal')).hide();
128+
};
129+
130+
// Show the modal
131+
new bootstrap.Modal(document.getElementById('promptModal')).show();
132+
}
133+
134+
function attachResource(resource) {
135+
// Add resource to the tracking array if not already present
136+
if (!attachedResources.some(r => r.uri === resource.uri)) {
137+
attachedResources.push(resource);
138+
updateAttachedResourcesDisplay();
139+
}
140+
}
141+
142+
function removeResource(uri) {
143+
// Remove the resource from the tracking array
144+
attachedResources = attachedResources.filter(r => r.uri !== uri);
145+
updateAttachedResourcesDisplay();
146+
}
147+
148+
function clearAttachedResources() {
149+
attachedResources = [];
150+
updateAttachedResourcesDisplay();
151+
}
152+
153+
function updateAttachedResourcesDisplay() {
154+
// Get the container element
155+
const container = document.getElementById('attached-resources-container');
156+
const list = document.getElementById('attached-resources-list');
157+
158+
if (!container || !list) return;
159+
160+
// Show/hide the container based on whether there are resources
161+
container.style.display = attachedResources.length > 0 ? 'block' : 'none';
162+
163+
// Clear the list
164+
list.innerHTML = '';
165+
166+
// Add badges for each resource
167+
attachedResources.forEach(resource => {
168+
const badge = document.createElement('div');
169+
170+
// Create display text with name and URI
171+
let displayText = resource.name || 'Resource';
172+
if (resource.uri) {
173+
displayText += ` (${resource.uri})`;
174+
}
175+
176+
badge.className = 'badge bg-secondary text-white d-flex align-items-center p-2 me-1 mb-1';
177+
badge.innerHTML = `
178+
<span class="me-2 text-truncate" style="max-width: 250px;" title="${displayText}">${displayText}</span>
179+
<button type="button" class="btn-close btn-close-white btn-close-sm flex-shrink-0"
180+
aria-label="Remove" onclick="removeResource('${resource.uri}')"></button>
181+
`;
182+
list.appendChild(badge);
183+
});
184+
185+
// Update the hidden form input
186+
const isWelcomePage = document.getElementById('chat-form-welcome') !== null;
187+
const formId = isWelcomePage ? 'chat-form-welcome' : 'chat-form-chatbox';
188+
const form = document.getElementById(formId);
189+
190+
if (form) {
191+
const input = form.querySelector('input[name="attached_resources"]');
192+
if (input) {
193+
input.value = JSON.stringify(attachedResources.map(r => r.uri));
194+
}
195+
}
196+
}
197+
198+
function showResourceModal(resourceIndex) {
199+
const resourceData = resourcesList[resourceIndex];
200+
if (!resourceData) {
201+
console.error('Resource not found at index:', resourceIndex);
202+
return;
203+
}
204+
205+
// Set the modal content
206+
document.getElementById('resourceName').textContent = resourceData.name || 'Unnamed Resource';
207+
document.getElementById('resourceDescription').textContent = resourceData.description || 'No description available';
208+
document.getElementById('resourceUri').textContent = resourceData.uri || '';
209+
document.getElementById('resourceMimeType').textContent = resourceData.mimeType || 'Unknown';
210+
211+
// Set up the "Use Resource" button handler
212+
document.getElementById('useResourceBtn').onclick = function() {
213+
attachResource(resourceData);
214+
bootstrap.Modal.getInstance(document.getElementById('resourceModal')).hide();
215+
};
216+
217+
// Show the modal
218+
new bootstrap.Modal(document.getElementById('resourceModal')).show();
219+
}
220+
221+
document.addEventListener('DOMContentLoaded', function() {
222+
// Fix any trailing commas in arrays
223+
for (let i = 0; i < promptsList.length; i++) {
224+
if (promptsList[i].arguments && promptsList[i].arguments.length > 0) {
225+
// Remove any undefined items that may have been created by trailing commas
226+
promptsList[i].arguments = promptsList[i].arguments.filter(item => item !== undefined);
227+
}
228+
}
229+
230+
// Clean up the resources list
231+
if (typeof resourcesList !== 'undefined') {
232+
resourcesList = resourcesList.filter(item => item !== undefined);
233+
}
234+
});

0 commit comments

Comments
 (0)