Skip to content

Commit

Permalink
search focus and keyboard-submission for assistant
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisclark committed Apr 22, 2024
1 parent 93ba05f commit 5dfb7aa
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 37 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
* SQL Assistant: Built in query help via OpenAI (or LLM of choice), with relevant schema
automatically injected into the prompt. Enable by setting EXPLORER_AI_API_KEY.
* Anonymous usage telemetry. Disable by setting EXPLORER_ENABLE_ANONYMOUS_STATS to False.
* Refactor pip requirements to make 'extras' more robust and easier to manage.
* `#592`_: Support user models with no email fields
* `#594`_: Eliminate <script> tags to prevent potential Content Security Policy issues.

Expand Down
88 changes: 51 additions & 37 deletions explorer/src/js/assistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ function getErrorMessage() {
return errorElement ? errorElement.textContent.trim() : null;
}

function assistantSearchFocus() {
document.getElementById("search_assistant_tables").focus();
}

export function setUpAssistant(expand = false) {

const error = getErrorMessage();
Expand Down Expand Up @@ -76,6 +80,7 @@ export function setUpAssistant(expand = false) {
additionalTableContainer.classList.remove('d-none');
assistantInputWrapper.classList.remove('col-12');
assistantInputWrapper.classList.add('col-9');
assistantSearchFocus();
} else {
additionalTableContainer.classList.add('d-none');
assistantInputWrapper.classList.remove('col-9');
Expand All @@ -87,45 +92,54 @@ export function setUpAssistant(expand = false) {
});
showHideExtraTables(checkbox.checked);

document.getElementById('ask_assistant_btn').addEventListener('click', function() {

const selectedTables = Array.from(
document.querySelectorAll('.table-checkbox:checked')
).map(cb => cb.value);
document.getElementById('id_assistant_input').addEventListener('keydown', function(event) {
if ((event.ctrlKey || event.metaKey) && (event.key === 'Enter')) {
event.preventDefault();
submitAssistantAsk();
}
});

const data = {
sql: window.editor?.state.doc.toString() ?? null,
connection: document.getElementById("id_connection")?.value ?? null,
assistant_request: document.getElementById("id_assistant_input")?.value ?? null,
selected_tables: selectedTables,
db_error: getErrorMessage()
};
document.getElementById('ask_assistant_btn').addEventListener('click', submitAssistantAsk);
}

document.getElementById("response_block").classList.remove('d-none');
document.getElementById("assistant_spinner").classList.remove('d-none');

fetch('../assistant/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCsrfToken()
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
const output = DOMPurify.sanitize(marked.parse(data.message));
document.getElementById("assistant_response").innerHTML = output;
setUpCopyButtons();
})
.catch(error => {
console.error('Error:', error);
});
function submitAssistantAsk() {

const selectedTables = Array.from(
document.querySelectorAll('.table-checkbox:checked')
).map(cb => cb.value);

const data = {
sql: window.editor?.state.doc.toString() ?? null,
connection: document.getElementById("id_connection")?.value ?? null,
assistant_request: document.getElementById("id_assistant_input")?.value ?? null,
selected_tables: selectedTables,
db_error: getErrorMessage()
};

document.getElementById("response_block").classList.remove('d-none');
document.getElementById("assistant_spinner").classList.remove('d-none');

fetch('../assistant/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCsrfToken()
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
const output = DOMPurify.sanitize(marked.parse(data.message));
document.getElementById("assistant_response").innerHTML = output;
setUpCopyButtons();
})
.catch(error => {
console.error('Error:', error);
});
}

Expand Down

0 comments on commit 5dfb7aa

Please sign in to comment.