1
1
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:
2020-12-22 22:31:31 +01:00
parent 0014f48079
commit cb1fce6f99
3 changed files with 2396 additions and 10 deletions

View File

@ -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>

View File

@ -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">

File diff suppressed because it is too large Load Diff