mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
feat: query editor auto-completer for tables and columns
This commit is contained in:
@ -7,22 +7,78 @@
|
|||||||
<script>
|
<script>
|
||||||
import * as ace from 'ace-builds';
|
import * as ace from 'ace-builds';
|
||||||
import 'ace-builds/webpack-resolver';
|
import 'ace-builds/webpack-resolver';
|
||||||
import 'ace-builds/src-noconflict/ext-language_tools';
|
import '../libs/ext-language_tools';
|
||||||
|
import Tables from '@/ipc-api/Tables';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'QueryEditor',
|
name: 'QueryEditor',
|
||||||
props: {
|
props: {
|
||||||
value: String,
|
value: String,
|
||||||
autoFocus: { type: Boolean, default: false }
|
schema: String,
|
||||||
|
autoFocus: { type: Boolean, default: false },
|
||||||
|
workspace: Object
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
editor: null
|
editor: null,
|
||||||
|
fields: [],
|
||||||
|
baseCompleter: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
tables () {
|
||||||
|
return this.workspace.structure.filter(schema => schema.name === this.schema)
|
||||||
|
.reduce((acc, curr) => {
|
||||||
|
acc.push(...curr.tables);
|
||||||
|
return acc;
|
||||||
|
}, []).map(table => {
|
||||||
|
return {
|
||||||
|
name: table.name,
|
||||||
|
comment: table.comment,
|
||||||
|
type: table.type,
|
||||||
|
fields: ['TODO']
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mode () {
|
||||||
|
switch (this.workspace.client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
return 'mysql';
|
||||||
|
case 'mssql':
|
||||||
|
return 'sqlserver';
|
||||||
|
case 'pg':
|
||||||
|
return 'pgsql';
|
||||||
|
default:
|
||||||
|
return 'sql';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lastWord () {
|
||||||
|
const words = this.value.split(' ');
|
||||||
|
return words[words.length - 1];
|
||||||
|
},
|
||||||
|
isLastWordATable () {
|
||||||
|
return /\w+\.\w*/gm.test(this.lastWord);
|
||||||
|
},
|
||||||
|
fieldsCompleter () {
|
||||||
|
return {
|
||||||
|
getCompletions: (editor, session, pos, prefix, callback) => {
|
||||||
|
const completions = [];
|
||||||
|
this.fields.forEach(field => {
|
||||||
|
completions.push({
|
||||||
|
value: field,
|
||||||
|
meta: 'column',
|
||||||
|
score: 1000
|
||||||
|
});
|
||||||
|
});
|
||||||
|
callback(null, completions);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.editor = ace.edit(this.$refs.editor, {
|
this.editor = ace.edit(this.$refs.editor, {
|
||||||
mode: 'ace/mode/sql',
|
mode: `ace/mode/${this.mode}`,
|
||||||
theme: 'ace/theme/twilight',
|
theme: 'ace/theme/twilight',
|
||||||
value: this.value,
|
value: this.value,
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
@ -35,6 +91,53 @@ export default {
|
|||||||
enableLiveAutocompletion: true
|
enableLiveAutocompletion: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.editor.completers.push({
|
||||||
|
getCompletions: (editor, session, pos, prefix, callback) => {
|
||||||
|
const completions = [];
|
||||||
|
this.tables.forEach(table => {
|
||||||
|
completions.push({
|
||||||
|
value: table.name,
|
||||||
|
meta: table.type,
|
||||||
|
caption: table.comment
|
||||||
|
});
|
||||||
|
});
|
||||||
|
callback(null, completions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.baseCompleter = this.editor.completers;
|
||||||
|
|
||||||
|
this.editor.commands.on('afterExec', e => {
|
||||||
|
if (['insertstring', 'backspace', 'del'].includes(e.command.name)) {
|
||||||
|
if (this.isLastWordATable || e.args === '.') {
|
||||||
|
if (e.args !== ' ') {
|
||||||
|
const table = this.tables.find(t => t.name === this.lastWord.split('.').pop());
|
||||||
|
|
||||||
|
if (table) {
|
||||||
|
const params = {
|
||||||
|
uid: this.workspace.uid,
|
||||||
|
schema: this.schema,
|
||||||
|
table: table.name
|
||||||
|
};
|
||||||
|
|
||||||
|
Tables.getTableColumns(params).then(res => {
|
||||||
|
if (res.response.length)
|
||||||
|
this.fields = res.response.map(field => field.name);
|
||||||
|
this.editor.completers = [this.fieldsCompleter];
|
||||||
|
this.editor.execCommand('startAutocomplete');
|
||||||
|
}).catch(console.log);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.editor.completers = this.baseCompleter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.editor.completers = this.baseCompleter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.editor.completers = this.baseCompleter;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.editor.session.on('change', () => {
|
this.editor.session.on('change', () => {
|
||||||
const content = this.editor.getValue();
|
const content = this.editor.getValue();
|
||||||
this.$emit('update:value', content);
|
this.$emit('update:value', content);
|
||||||
@ -50,12 +153,30 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.editor-wrapper {
|
.editor-wrapper {
|
||||||
border-bottom: 1px solid #444;
|
border-bottom: 1px solid #444;
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_.mdi {
|
||||||
|
display: inline-block;
|
||||||
|
width: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {
|
||||||
|
background-color: #c9561a99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_line-hover {
|
||||||
|
background-color: #c9571a33;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight {
|
||||||
|
color: #e0d00c;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
v-if="isSelected"
|
v-if="isSelected"
|
||||||
:auto-focus="true"
|
:auto-focus="true"
|
||||||
:value.sync="query"
|
:value.sync="query"
|
||||||
|
:workspace="workspace"
|
||||||
|
:schema="schema"
|
||||||
/>
|
/>
|
||||||
<div class="workspace-query-runner-footer">
|
<div class="workspace-query-runner-footer">
|
||||||
<div class="workspace-query-buttons">
|
<div class="workspace-query-buttons">
|
||||||
|
2263
src/renderer/libs/ext-language_tools.js
Normal file
2263
src/renderer/libs/ext-language_tools.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user