Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions media/scripts/dropdown-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class DropdownMenu {
constructor(/** @type {Tab} */ tab) {
this.tab = tab
}

initialize() {
const exportResultsButton = /** @type {HTMLElement} */ (
document.querySelector(`#export-${this.tab.name}`)
)

// Toggle dropdown menu visibility
exportResultsButton.addEventListener('click', (event) => {
event.stopPropagation() // Prevent the event from bubbling up
let dropdownMenu = document.getElementById(
`dropdown-menu-${this.tab.name}`
)

if (
dropdownMenu.style.display === 'none' ||
dropdownMenu.style.display === ''
) {
dropdownMenu.style.display = 'block'
} else {
dropdownMenu.style.display = 'none'
}
})

document
.getElementById(`dropdown-menu-${this.tab.name}`)
.addEventListener('click', (event) => {
event.stopPropagation()
if (event.target.tagName === 'SPAN') {
const selectedOption =
event.target.getAttribute('data-value')

const exportQueryResultsButton = document.getElementById(
`export-${this.tab.name}`
)
exportQueryResultsButton.setAttribute('disabled', '')

const exportQueryResultsButtonText =
document.getElementById(`export-text-${this.tab.name}`)

exportQueryResultsButtonText.innerText = 'Exporting...'

const filterValueInput = /** @type {HTMLElement} */ (
document.querySelector(
`#input-filter-values-${this.tab.name}`
)
)

const sort = this.tab.sort
? this.tab.sort.sortQuery
: undefined
this.tab.vscode.postMessage({
type: 'exportResults',
exportType: selectedOption,
searchString: filterValueInput?.value,
sort: sort,
tabName: this.tab.name,
})

// Perform any additional actions here, e.g., close dropdown
// Hide the menu if it's currently visible
let dropdownMenu = document.getElementById(
`dropdown-menu-${this.tab.name}`
)
if (dropdownMenu.style.display === 'block') {
dropdownMenu.style.display = 'none'
}
}
})

// Close dropdown when clicking outside
window.addEventListener('click', () => {
let dropdownMenu = document.getElementById(
`dropdown-menu-${this.tab.name}`
)

// Hide the menu if it's currently visible
if (dropdownMenu.style.display === 'block') {
dropdownMenu.style.display = 'none'
}
})
}
}
60 changes: 60 additions & 0 deletions media/scripts/editor-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
class EditorControls {
constructor(/** @type {Tab} */ tab) {
this.tab = tab

this.isQueryRunning = false
}

initialize() {
// console.log("editorControls.initialize()")
const runQueryButton = document.getElementById('run-query-btn')
runQueryButton?.addEventListener('click', (e) => {
this.runQuery()
})

const clearQueryTextButton = document.getElementById('clear-query-btn')
clearQueryTextButton?.addEventListener('click', (e) => {
this.tab.editor.aceEditor.setValue('')
})
}

runQuery() {
if (this.isQueryRunning) {
return
}

this.tab.tableWrapper.setAlert()

const runQueryButton = document.getElementById('run-query-btn')
runQueryButton?.setAttribute('disabled', '')

const runQueryButtonText = document.getElementById('run-query-btn-text')
runQueryButtonText.innerText = 'Running'

const selectedOption = this.tab.pagination.getSelectedPageSize()
const queryString = this.tab.editor.getTextFromEditor()
const pageSize =
selectedOption.innerText === 'all'
? undefined
: selectedOption.innerText

this.tab.vscode.postMessage({
type: 'startQuery',
query: {
queryString: queryString,
pageSize: pageSize,
},
})
this.isQueryRunning = true
}

reset() {
const runQueryButton = document.getElementById('run-query-btn')
runQueryButton?.removeAttribute('disabled')

const runQueryButtonText = document.getElementById('run-query-btn-text')
runQueryButtonText.innerText = 'Run'

this.isQueryRunning = false
}
}
93 changes: 93 additions & 0 deletions media/scripts/editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
class Editor {
constructor(
/** @type {Tab} */ tab,
/** @type {EditorControls} */ editorControls,
/** @type {any} */ parameters
) {
this.tab = tab

this.defaultQuery = parameters.defaultQuery
this.shortCutMapping = parameters.shortCutMapping
this.aceTheme = parameters.theme
this.aceEditorCompletions = parameters.aceEditorCompletions

this.editorControls = editorControls

this.aceEditor
}

initialize() {
this.aceEditor = ace.edit('editor')

this.aceEditor.setTheme(this.aceTheme)
this.aceEditor.session.setMode('ace/mode/sql')
this.aceEditor.setValue(this.defaultQuery)

this.aceEditor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
})

const completer = {
getCompletions: (editor, session, pos, prefix, callback) => {
const line = session.getLine(pos.row)
const charBeforeCursor = line[pos.column - 1] || ''

// Get the character immediately after the cursor
const charAfterCursor = line[pos.column] || ''

const aceEditorCompletionsCopy = structuredClone(
this.aceEditorCompletions
)
aceEditorCompletionsCopy.forEach((c) => {
if (charBeforeCursor === '"' && charAfterCursor === '"') {
// If the cursor is between a pair of quotes, offer relevant suggestions
c.value = c.value.replace(/['"]/g, '')
} else if (charBeforeCursor === '"') {
// If the cursor is right after an opening quote

if (c.value.includes('"')) {
c.value = c.value.replace(/^"/, '')
} else {
c.value = c.value + '"'
}
} else if (charAfterCursor === '"') {
// If the cursor is right after an opening quote
if (c.value.includes('"')) {
c.value = c.value.replace(/"$/, '')
} else {
c.value = '"' + c.value
}
}
})

callback(null, aceEditorCompletionsCopy)
},
}

var langTools = ace.require('ace/ext/language_tools')
langTools.addCompleter(completer)

this.aceEditor.commands.addCommand({
name: 'runQuery',
bindKey: this.shortCutMapping,
exec: () => {
this.editorControls.runQuery()
},
})
}

getTextFromEditor() {
var selectedText = this.aceEditor.getSelectedText()
if (selectedText) {
return selectedText
} else {
return this.aceEditor.getValue()
}
}

setTheme(/** @type {string} */ theme) {
this.aceEditor.setTheme(theme)
}
}
Loading
Loading