1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2025-12-07 02:28:54 +08:00

SQL query execution state in UI #3

- use LoadingIndicator
- use Logs
This commit is contained in:
lana-k
2021-05-14 16:42:58 +02:00
parent 3bb40b4eb7
commit a3fb38b23c
4 changed files with 51 additions and 18 deletions

View File

@@ -64,6 +64,7 @@ export default {
border: 1px solid var(--color-border-light); border: 1px solid var(--color-border-light);
box-sizing: border-box; box-sizing: border-box;
overflow-y: scroll; overflow-y: scroll;
color: var(--color-text-base);
} }
.msg { .msg {
padding: 16px 7px; padding: 16px 7px;

View File

@@ -41,6 +41,7 @@
<div class="table-footer-count"> <div class="table-footer-count">
{{ dataSet.values.length}} {{dataSet.values.length === 1 ? 'row' : 'rows'}} retrieved {{ dataSet.values.length}} {{dataSet.values.length === 1 ? 'row' : 'rows'}} retrieved
<span v-if="preview">for preview</span> <span v-if="preview">for preview</span>
<span v-if="time">in {{ time }}</span>
</div> </div>
<pager v-show="pageCount > 1" :page-count="pageCount" v-model="currentPage" /> <pager v-show="pageCount > 1" :page-count="pageCount" v-model="currentPage" />
</div> </div>
@@ -53,7 +54,7 @@ import Pager from './Pager'
export default { export default {
name: 'SqlTable', name: 'SqlTable',
components: { Pager }, components: { Pager },
props: ['dataSet', 'height', 'preview'], props: ['dataSet', 'time', 'height', 'preview'],
data () { data () {
return { return {
header: null, header: null,

View File

@@ -21,7 +21,8 @@
> >
Run your query and get results here Run your query and get results here
</div> </div>
<div v-show="isGettingResults" class="table-preview result-in-progress"> <div v-if="isGettingResults" class="table-preview result-in-progress">
<loading-indicator :size="30"/>
Fetching results... Fetching results...
</div> </div>
<div <div
@@ -30,10 +31,8 @@
> >
No rows retrieved according to your query No rows retrieved according to your query
</div> </div>
<div v-show="error" class="table-preview error"> <logs v-if="error" :messages="[error]"/>
{{ error }} <sql-table v-if="result" :data-set="result" :time="time" :height="tableViewHeight" />
</div>
<sql-table v-if="result" :data-set="result" :height="tableViewHeight" />
</div> </div>
<chart <chart
:visible="view === 'chart'" :visible="view === 'chart'"
@@ -51,9 +50,12 @@
<script> <script>
import SqlTable from '@/components/SqlTable' import SqlTable from '@/components/SqlTable'
import Splitpanes from '@/components/Splitpanes' import Splitpanes from '@/components/Splitpanes'
import LoadingIndicator from '@/components/LoadingIndicator'
import SqlEditor from './SqlEditor' import SqlEditor from './SqlEditor'
import ViewSwitcher from './ViewSwitcher' import ViewSwitcher from './ViewSwitcher'
import Chart from './Chart' import Chart from './Chart'
import Logs from '@/components/Logs'
import time from '@/lib/utils/time'
export default { export default {
name: 'Tab', name: 'Tab',
@@ -63,7 +65,9 @@ export default {
SqlTable, SqlTable,
Splitpanes, Splitpanes,
ViewSwitcher, ViewSwitcher,
Chart Chart,
LoadingIndicator,
Logs
}, },
data () { data () {
return { return {
@@ -73,7 +77,8 @@ export default {
tableViewHeight: 0, tableViewHeight: 0,
isGettingResults: false, isGettingResults: false,
error: null, error: null,
resizeObserver: null resizeObserver: null,
time: 0
} }
}, },
computed: { computed: {
@@ -110,11 +115,16 @@ export default {
this.error = null this.error = null
const state = this.$store.state const state = this.$store.state
try { try {
const start = new Date()
this.result = await state.db.execute(this.query + ';') this.result = await state.db.execute(this.query + ';')
this.time = time.getPeriod(start, new Date())
const schema = await state.db.getSchema(state.dbName) const schema = await state.db.getSchema(state.dbName)
this.$store.commit('saveSchema', schema) this.$store.commit('saveSchema', schema)
} catch (err) { } catch (err) {
this.error = err this.error = {
type: 'error',
message: err
}
} }
this.isGettingResults = false this.isGettingResults = false
}, },
@@ -183,11 +193,32 @@ export default {
font-size: 13px; font-size: 13px;
} }
.table-preview.error { .result-in-progress {
color: var(--color-text-error); display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
will-change: opacity;
/*
We need to show loader in 1 sec after starting query execution. We can't do that with
setTimeout because the main thread can be busy by getting a result set from the web worker.
But we can use CSS animation for opacity. Opacity triggers changes only in the Composite Layer
stage in rendering waterfall. Hence it can be processed only with Compositor Thread while
the Main Thread processes a result set.
https://www.viget.com/articles/animation-performance-101-browser-under-the-hood/
*/
animation: show-loader 1s linear 0s 1;
} }
.table-preview.error::first-letter { @keyframes show-loader {
text-transform: capitalize; 0% {
opacity: 0;
}
99% {
opacity: 0;
}
100% {
opacity: 1;
}
} }
</style> </style>

View File

@@ -202,9 +202,9 @@ describe('Tab.vue', () => {
await wrapper.vm.execute() await wrapper.vm.execute()
expect(wrapper.find('.table-view .result-before').isVisible()).to.equal(false) expect(wrapper.find('.table-view .result-before').isVisible()).to.equal(false)
expect(wrapper.find('.table-view .result-in-progress').isVisible()).to.equal(false) expect(wrapper.find('.table-view .result-in-progress').exists()).to.equal(false)
expect(wrapper.find('.table-preview.error').isVisible()).to.equal(true) expect(wrapper.findComponent({name: 'logs'}).isVisible()).to.equal(true)
expect(wrapper.find('.table-preview.error').text()).to.include('There is no table foo') expect(wrapper.findComponent({name: 'logs'}).text()).to.include('There is no table foo')
}) })
it('Passes result to sql-table component', async () => { it('Passes result to sql-table component', async () => {
@@ -242,8 +242,8 @@ describe('Tab.vue', () => {
await wrapper.vm.execute() await wrapper.vm.execute()
expect(wrapper.find('.table-view .result-before').isVisible()).to.equal(false) expect(wrapper.find('.table-view .result-before').isVisible()).to.equal(false)
expect(wrapper.find('.table-view .result-in-progress').isVisible()).to.equal(false) expect(wrapper.find('.table-view .result-in-progress').exists()).to.equal(false)
expect(wrapper.find('.table-preview.error').isVisible()).to.equal(false) expect(wrapper.findComponent({name: 'logs'}).exists()).to.equal(false)
expect(wrapper.findComponent({ name: 'SqlTable' }).vm.dataSet).to.eql(result) expect(wrapper.findComponent({ name: 'SqlTable' }).vm.dataSet).to.eql(result)
}) })