mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 18:18:53 +08:00
codemirror wrapped as a vue component
This commit is contained in:
82
src/components/SqlEditor.vue
Normal file
82
src/components/SqlEditor.vue
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<div class="codemirror-container">
|
||||||
|
<codemirror v-model="query" :options="cmOptions" @changes="onCmChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CM from 'codemirror'
|
||||||
|
import { codemirror } from 'vue-codemirror'
|
||||||
|
import 'codemirror/lib/codemirror.css'
|
||||||
|
import 'codemirror/mode/sql/sql.js'
|
||||||
|
import 'codemirror/theme/neo.css'
|
||||||
|
import 'codemirror/addon/hint/show-hint.js'
|
||||||
|
import 'codemirror/addon/hint/show-hint.css'
|
||||||
|
import 'codemirror/addon/hint/sql-hint.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SqlEditor',
|
||||||
|
props: ['value'],
|
||||||
|
components: {
|
||||||
|
codemirror
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
query: this.value,
|
||||||
|
cmOptions: {
|
||||||
|
// codemirror options
|
||||||
|
tabSize: 4,
|
||||||
|
mode: 'text/x-mysql',
|
||||||
|
theme: 'neo',
|
||||||
|
lineNumbers: true,
|
||||||
|
line: true
|
||||||
|
},
|
||||||
|
result: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
query () {
|
||||||
|
this.$emit('input', this.query)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onCmChange (editor) {
|
||||||
|
// Don't show autocomplete after a space or semicolon
|
||||||
|
const ch = editor.getTokenAt(editor.getCursor()).string.slice(-1)
|
||||||
|
if (!ch || ch === ' ' || ch === ';') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const hintOptions = {
|
||||||
|
// tables: this.state.tables,
|
||||||
|
completeSingle: false,
|
||||||
|
completeOnSingleClick: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// editor.hint.sql is defined when importing codemirror/addon/hint/sql-hint
|
||||||
|
// (this is mentioned in codemirror addon documentation)
|
||||||
|
// Reference the hint function imported here when including other hint addons
|
||||||
|
// or supply your own
|
||||||
|
CM.showHint(editor, CM.hint.sql, hintOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.codemirror-container {
|
||||||
|
flex-grow: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
>>> .vue-codemirror {
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
>>> .CodeMirror {
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--border-radius-big);
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -8,13 +8,11 @@
|
|||||||
>
|
>
|
||||||
<template #left-pane>
|
<template #left-pane>
|
||||||
<div class="query-editor">
|
<div class="query-editor">
|
||||||
<div class="codemirror-container">
|
<sql-editor v-model="query" />
|
||||||
<codemirror v-model="query" :options="cmOptions" @changes="onCmChange" ref="codemirror" />
|
|
||||||
</div>
|
|
||||||
<div class="run-btn-container">
|
<div class="run-btn-container">
|
||||||
<button
|
<button
|
||||||
class="primary run-btn"
|
class="primary run-btn"
|
||||||
@click="execute(query)"
|
@click="execute"
|
||||||
:disabled="!$store.state.schema"
|
:disabled="!$store.state.schema"
|
||||||
>
|
>
|
||||||
Run
|
Run
|
||||||
@@ -30,7 +28,7 @@
|
|||||||
<pre ref="output" id="output">Results will be displayed here</pre> -->
|
<pre ref="output" id="output">Results will be displayed here</pre> -->
|
||||||
<sql-table v-if="result" :data="result" :height="tableViewHeight" />
|
<sql-table v-if="result" :data="result" :height="tableViewHeight" />
|
||||||
</div>
|
</div>
|
||||||
<Chart
|
<chart
|
||||||
:visible="view === 'chart'"
|
:visible="view === 'chart'"
|
||||||
:sql-result="result"
|
:sql-result="result"
|
||||||
:init-chart="initChart"
|
:init-chart="initChart"
|
||||||
@@ -45,24 +43,16 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SqlTable from '@/components/SqlTable'
|
import SqlTable from '@/components/SqlTable'
|
||||||
|
import SqlEditor from '@/components/SqlEditor'
|
||||||
import Splitpanes from '@/components/splitpanes'
|
import Splitpanes from '@/components/splitpanes'
|
||||||
import ViewSwitcher from '@/components/ViewSwitcher'
|
import ViewSwitcher from '@/components/ViewSwitcher'
|
||||||
import Chart from '@/components/Chart'
|
import Chart from '@/components/Chart'
|
||||||
|
|
||||||
import CM from 'codemirror'
|
|
||||||
import { codemirror } from 'vue-codemirror'
|
|
||||||
import 'codemirror/lib/codemirror.css'
|
|
||||||
import 'codemirror/mode/sql/sql.js'
|
|
||||||
import 'codemirror/theme/neo.css'
|
|
||||||
import 'codemirror/addon/hint/show-hint.js'
|
|
||||||
import 'codemirror/addon/hint/show-hint.css'
|
|
||||||
import 'codemirror/addon/hint/sql-hint.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TabContent',
|
name: 'TabContent',
|
||||||
props: ['id', 'initName', 'initQuery', 'initChart', 'tabIndex'],
|
props: ['id', 'initName', 'initQuery', 'initChart', 'tabIndex'],
|
||||||
components: {
|
components: {
|
||||||
codemirror,
|
SqlEditor,
|
||||||
SqlTable,
|
SqlTable,
|
||||||
Splitpanes,
|
Splitpanes,
|
||||||
ViewSwitcher,
|
ViewSwitcher,
|
||||||
@@ -71,14 +61,6 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
query: this.initQuery,
|
query: this.initQuery,
|
||||||
cmOptions: {
|
|
||||||
// codemirror options
|
|
||||||
tabSize: 4,
|
|
||||||
mode: 'text/x-mysql',
|
|
||||||
theme: 'neo',
|
|
||||||
lineNumbers: true,
|
|
||||||
line: true
|
|
||||||
},
|
|
||||||
result: null,
|
result: null,
|
||||||
view: 'table',
|
view: 'table',
|
||||||
tableViewHeight: 0,
|
tableViewHeight: 0,
|
||||||
@@ -88,25 +70,6 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
isActive () {
|
isActive () {
|
||||||
return this.id === this.$store.state.currentTabId
|
return this.id === this.$store.state.currentTabId
|
||||||
},
|
|
||||||
dataSources () {
|
|
||||||
if (!this.result) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
const dataSorces = {}
|
|
||||||
const matrix = this.result.values
|
|
||||||
const [row] = matrix
|
|
||||||
const transposedMatrix = row.map((value, column) => matrix.map(row => row[column]))
|
|
||||||
this.result.columns.forEach((column, index) => {
|
|
||||||
dataSorces[column] = transposedMatrix[index]
|
|
||||||
})
|
|
||||||
return dataSorces
|
|
||||||
},
|
|
||||||
dataSourceOptions () {
|
|
||||||
return Object.keys(this.dataSources).map(name => ({
|
|
||||||
value: name,
|
|
||||||
label: name
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
@@ -130,29 +93,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onCmChange (editor) {
|
|
||||||
// Don't show autocomplete after a space or semicolon
|
|
||||||
const ch = editor.getTokenAt(editor.getCursor()).string.slice(-1)
|
|
||||||
if (!ch || ch === ' ' || ch === ';') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const hintOptions = {
|
|
||||||
// tables: this.state.tables,
|
|
||||||
completeSingle: false,
|
|
||||||
completeOnSingleClick: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// editor.hint.sql is defined when importing codemirror/addon/hint/sql-hint
|
|
||||||
// (this is mentioned in codemirror addon documentation)
|
|
||||||
// Reference the hint function imported here when including other hint addons
|
|
||||||
// or supply your own
|
|
||||||
CM.showHint(editor, CM.hint.sql, hintOptions)
|
|
||||||
},
|
|
||||||
// Run a command in the database
|
// Run a command in the database
|
||||||
execute (commands) {
|
execute () {
|
||||||
// this.$refs.output.textContent = 'Fetching results...' */
|
// this.$refs.output.textContent = 'Fetching results...' */
|
||||||
this.$db.execute(commands + ';')
|
this.$db.execute(this.query + ';')
|
||||||
.then(result => { this.result = result })
|
.then(result => { this.result = result })
|
||||||
.catch(err => alert(err))
|
.catch(err => alert(err))
|
||||||
},
|
},
|
||||||
@@ -214,25 +158,10 @@ export default {
|
|||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codemirror-container {
|
|
||||||
flex-grow: 1;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.run-btn-container {
|
.run-btn-container {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
>>> .vue-codemirror {
|
|
||||||
height: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
>>> .CodeMirror {
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
border-radius: var(--border-radius-big);
|
|
||||||
height: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
.table-view {
|
.table-view {
|
||||||
margin: 0 52px;
|
margin: 0 52px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user