1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2025-12-06 18:18:53 +08:00

add tab switcher

This commit is contained in:
lana-k
2020-10-03 22:33:53 +02:00
parent 2371cd5acc
commit f898493d29
4 changed files with 149 additions and 50 deletions

View File

@@ -13,11 +13,16 @@
</div> </div>
</div> </div>
</div> </div>
<div id="table-container" ref="table-container" @scroll="onScrollTable" :style="{height: `${height}px`}"> <div
<table id="table"> id="table-container"
ref="table-container"
@scroll="onScrollTable"
:style="{height: `${height}px`}"
>
<table ref="table">
<thead> <thead>
<tr> <tr>
<th v-for="(th,index) in data.columns" :key="index"> <th v-for="(th,index) in data.columns" :key="index" ref="th">
<div class="cell-data" :style="cellStyle">{{ th }}</div> <div class="cell-data" :style="cellStyle">{{ th }}</div>
</th> </th>
</tr> </tr>
@@ -76,7 +81,7 @@ export default {
calculateHeadersWidth () { calculateHeadersWidth () {
this.tableWidth = this.$refs['table-container'].offsetWidth this.tableWidth = this.$refs['table-container'].offsetWidth
this.$nextTick(() => { this.$nextTick(() => {
this.header = Array.from(document.querySelectorAll('th')).map(th => { this.header = this.$refs.th.map(th => {
return { name: th.innerText, width: th.offsetWidth } return { name: th.innerText, width: th.offsetWidth }
}) })
}) })
@@ -89,7 +94,7 @@ export default {
} }
}, },
mounted () { mounted () {
new ResizeObserver(this.calculateHeadersWidth).observe(document.getElementById('table')) new ResizeObserver(this.calculateHeadersWidth).observe(this.$refs.table)
this.calculateHeadersWidth() this.calculateHeadersWidth()
}, },
watch: { watch: {
@@ -127,7 +132,6 @@ export default {
} }
#table-container { #table-container {
width: 100%; width: 100%;
/* height: 200px; */
overflow: auto; overflow: auto;
} }
table { table {
@@ -167,7 +171,6 @@ td > div.cell-data {
width: -moz-max-content; width: -moz-max-content;
width: max-content; width: max-content;
white-space: nowrap; white-space: nowrap;
/* max-width: 250px; */
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }

View File

@@ -1,41 +1,43 @@
<template> <template>
<splitpanes <div class="tab-content-container" v-show="isActive">
class="query-results-splitter" <splitpanes
horizontal class="query-results-splitter"
:before="{ size: 50, max: 50 }" horizontal
:after="{ size: 50, max: 100 }" :before="{ size: 50, max: 50 }"
> :after="{ size: 50, max: 100 }"
<div slot="left-pane" class="query-editor"> >
<div class="codemirror-container"> <div slot="left-pane" class="query-editor">
<codemirror v-model="code" :options="cmOptions" @changes="onCmChange" /> <div class="codemirror-container">
<codemirror v-model="code" :options="cmOptions" @changes="onCmChange" />
</div>
<div class="run-btn-container">
<button class="primary run-btn" @click="execEditorContents">Run</button>
</div>
</div> </div>
<div class="run-btn-container"> <div slot="right-pane" id="bottomPane" ref="bottomPane">
<button class="primary run-btn" @click="execEditorContents">Run</button> <view-switcher :view.sync="view" />
<div v-show="view === 'table'" class="table-view">
<!-- <div id="error" class="error"></div>
<pre ref="output" id="output">Results will be displayed here</pre> -->
<sql-table v-if="result" :data="result" :height="tableViewHeight" />
</div>
<PlotlyEditor
v-show="view === 'chart'"
:data="state.data"
:layout="state.layout"
:frames="state.frames"
:config="{ editable: true }"
:dataSources="dataSources"
:dataSourceOptions="dataSourceOptions"
:plotly="plotly"
@onUpdate="update"
:useResizeHandler="true"
:debug="true"
:advancedTraceTypeSelector="true"
/>
</div> </div>
</div> </splitpanes>
<div slot="right-pane" id="bottomPane"> </div>
<view-switcher :view.sync="view" />
<div v-show="view === 'table'" class="table-view">
<!-- <div id="error" class="error"></div>
<pre ref="output" id="output">Results will be displayed here</pre> -->
<sql-table v-if="result" :data="result" :height="tableViewHeight" />
</div>
<PlotlyEditor
v-show="view === 'chart'"
:data="state.data"
:layout="state.layout"
:frames="state.frames"
:config="{ editable: true }"
:dataSources="dataSources"
:dataSourceOptions="dataSourceOptions"
:plotly="plotly"
@onUpdate="update"
:useResizeHandler="true"
:debug="true"
:advancedTraceTypeSelector="true"
/>
</div>
</splitpanes>
</template> </template>
<script> <script>
@@ -57,6 +59,7 @@ import 'codemirror/addon/hint/sql-hint.js'
export default { export default {
name: 'TabContent', name: 'TabContent',
props: ['name', 'isActive'],
components: { components: {
codemirror, codemirror,
SqlTable, SqlTable,
@@ -108,7 +111,7 @@ export default {
} }
}, },
mounted () { mounted () {
new ResizeObserver(this.calculateTableHeight).observe(document.getElementById('bottomPane')) new ResizeObserver(this.calculateTableHeight).observe(this.$refs.bottomPane)
this.calculateTableHeight() this.calculateTableHeight()
}, },
methods: { methods: {
@@ -154,7 +157,7 @@ export default {
this.execute(this.code + ';') this.execute(this.code + ';')
}, },
calculateTableHeight () { calculateTableHeight () {
const bottomPane = document.getElementById('bottomPane') const bottomPane = this.$refs.bottomPane
// 88 - view swittcher height // 88 - view swittcher height
// 42 - table footer width // 42 - table footer width
// 30 - desirable space after the table // 30 - desirable space after the table
@@ -168,13 +171,19 @@ export default {
</script> </script>
<style scoped> <style scoped>
.tab-content-container {
padding-top: 6px;
background-color: var(--color-bg-light);
border-top: 1px solid var(--color-border-light);
margin-top: -1px;
}
#bottomPane { #bottomPane {
height: 100%; height: 100%;
} }
.query-results-splitter { .query-results-splitter {
height: calc(100vh - 74px); height: calc(100vh - 110px);
margin-top: 6px;
background-color: var(--color-bg-light); background-color: var(--color-bg-light);
} }
@@ -183,7 +192,7 @@ export default {
} }
.query-editor { .query-editor {
padding: 0 52px 24px; padding: 52px 52px 24px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;

87
src/components/Tabs.vue Normal file
View File

@@ -0,0 +1,87 @@
<template>
<div>
<div id="tabs__header">
<div
v-for="tab in tabs"
:key="tab.id"
@click="selectTab(tab.id)"
:class='{"tab__selected": (tab.id === selectedIndex)}'
>
{{ tab.name }}
</div>
</div>
<tab-content
v-for="tab in tabs"
:key="tab.id"
:is-active="tab.isActive"
:name="tab.name"
/>
</div>
</template>
<script>
import TabContent from '@/components/TabContent'
export default {
components: {
TabContent
},
data () {
return {
selectedIndex: 0,
tabs: [
{ id: 1, name: 'New query', isActive: true },
{ id: 2, name: 'New query 2', isActive: false }
]
}
},
methods: {
selectTab (id) {
this.selectedIndex = id
this.tabs.forEach(tab => {
tab.isActive = (tab.id === id)
})
}
}
}
</script>
<style>
#tabs__header {
display: flex;
margin: 0;
}
#tabs__header div {
height: 36px;
background-color: var(--color-bg-light);
border-right: 1px solid var(--color-border-light);
border-bottom: 1px solid var(--color-border-light);
line-height: 36px;
font-size: 14px;
color: var(--color-text-base);
padding: 0 12px;
box-sizing: border-box;
position: relative;
}
#tabs__header div:hover {
cursor: pointer;
}
#tabs__header .tab__selected {
color: var(--color-text-active);
font-weight: 600;
border-bottom: none;
}
#tabs__header .tab__selected:hover {
cursor: default;
}
#tabs__header .tab__selected:before {
content: '';
position: absolute;
width: 100%;
height: 5px;
background-color: var(--color-accent);
top: 0;
left: 0;
}
</style>

View File

@@ -9,7 +9,7 @@
<schema /> <schema />
</div> </div>
<div slot="right-pane"> <div slot="right-pane">
<tab-content /> <tabs />
</div> </div>
</splitpanes> </splitpanes>
</div> </div>
@@ -18,14 +18,14 @@
<script> <script>
import Splitpanes from '@/components/splitpanes' import Splitpanes from '@/components/splitpanes'
import Schema from '@/components/Schema' import Schema from '@/components/Schema'
import TabContent from '@/components/TabContent' import Tabs from '@/components/Tabs'
export default { export default {
name: 'Editor', name: 'Editor',
components: { components: {
Schema, Schema,
Splitpanes, Splitpanes,
TabContent Tabs
} }
} }
</script> </script>