diff --git a/src/components/Logs.vue b/src/components/Logs.vue index 3b504e4..d7e2e51 100644 --- a/src/components/Logs.vue +++ b/src/components/Logs.vue @@ -64,6 +64,7 @@ export default { border: 1px solid var(--color-border-light); box-sizing: border-box; overflow-y: scroll; + color: var(--color-text-base); } .msg { padding: 16px 7px; diff --git a/src/components/SqlTable/index.vue b/src/components/SqlTable/index.vue index 4c637e7..ebe7edc 100644 --- a/src/components/SqlTable/index.vue +++ b/src/components/SqlTable/index.vue @@ -41,6 +41,7 @@ @@ -53,7 +54,7 @@ import Pager from './Pager' export default { name: 'SqlTable', components: { Pager }, - props: ['dataSet', 'height', 'preview'], + props: ['dataSet', 'time', 'height', 'preview'], data () { return { header: null, diff --git a/src/views/Main/Editor/Tabs/Tab/index.vue b/src/views/Main/Editor/Tabs/Tab/index.vue index f748571..c97efa9 100644 --- a/src/views/Main/Editor/Tabs/Tab/index.vue +++ b/src/views/Main/Editor/Tabs/Tab/index.vue @@ -21,7 +21,8 @@ > Run your query and get results here -
+
+ Fetching results...
No rows retrieved according to your query
-
- {{ error }} -
- + +
import SqlTable from '@/components/SqlTable' import Splitpanes from '@/components/Splitpanes' +import LoadingIndicator from '@/components/LoadingIndicator' import SqlEditor from './SqlEditor' import ViewSwitcher from './ViewSwitcher' import Chart from './Chart' +import Logs from '@/components/Logs' +import time from '@/lib/utils/time' export default { name: 'Tab', @@ -63,7 +65,9 @@ export default { SqlTable, Splitpanes, ViewSwitcher, - Chart + Chart, + LoadingIndicator, + Logs }, data () { return { @@ -73,7 +77,8 @@ export default { tableViewHeight: 0, isGettingResults: false, error: null, - resizeObserver: null + resizeObserver: null, + time: 0 } }, computed: { @@ -110,11 +115,16 @@ export default { this.error = null const state = this.$store.state try { + const start = new Date() this.result = await state.db.execute(this.query + ';') + this.time = time.getPeriod(start, new Date()) const schema = await state.db.getSchema(state.dbName) this.$store.commit('saveSchema', schema) } catch (err) { - this.error = err + this.error = { + type: 'error', + message: err + } } this.isGettingResults = false }, @@ -183,11 +193,32 @@ export default { font-size: 13px; } -.table-preview.error { - color: var(--color-text-error); +.result-in-progress { + 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 { - text-transform: capitalize; +@keyframes show-loader { + 0% { + opacity: 0; + } + 99% { + opacity: 0; + } + 100% { + opacity: 1; + } } diff --git a/tests/views/MainView/Editor/Tabs/Tab/Tab.spec.js b/tests/views/MainView/Editor/Tabs/Tab/Tab.spec.js index eb45db2..1d09db6 100644 --- a/tests/views/MainView/Editor/Tabs/Tab/Tab.spec.js +++ b/tests/views/MainView/Editor/Tabs/Tab/Tab.spec.js @@ -202,9 +202,9 @@ describe('Tab.vue', () => { await wrapper.vm.execute() 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-preview.error').isVisible()).to.equal(true) - expect(wrapper.find('.table-preview.error').text()).to.include('There is no table foo') + expect(wrapper.find('.table-view .result-in-progress').exists()).to.equal(false) + expect(wrapper.findComponent({name: 'logs'}).isVisible()).to.equal(true) + expect(wrapper.findComponent({name: 'logs'}).text()).to.include('There is no table foo') }) it('Passes result to sql-table component', async () => { @@ -242,8 +242,8 @@ describe('Tab.vue', () => { await wrapper.vm.execute() 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-preview.error').isVisible()).to.equal(false) + expect(wrapper.find('.table-view .result-in-progress').exists()).to.equal(false) + expect(wrapper.findComponent({name: 'logs'}).exists()).to.equal(false) expect(wrapper.findComponent({ name: 'SqlTable' }).vm.dataSet).to.eql(result) })