1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2025-12-06 18:18:53 +08:00
This commit is contained in:
lana-k
2022-06-24 21:29:40 +02:00
parent a20dd7f849
commit 518b22b489
15 changed files with 193 additions and 16 deletions

View File

@@ -58,6 +58,7 @@ import fIo from '@/lib/utils/fileIo'
import ChangeDbIcon from '@/components/svg/changeDb' import ChangeDbIcon from '@/components/svg/changeDb'
import database from '@/lib/database' import database from '@/lib/database'
import CsvImport from '@/components/CsvImport' import CsvImport from '@/components/CsvImport'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'DbUploader', name: 'DbUploader',
@@ -127,6 +128,13 @@ export default {
if (fIo.isDatabase(file)) { if (fIo.isDatabase(file)) {
this.loadDb(file) this.loadDb(file)
} else { } else {
send({
category: 'database',
action: 'import',
value: file.size,
label: 'from=csv new_db=true'
})
this.file = file this.file = file
await this.$nextTick() await this.$nextTick()
const csvImport = this.$refs.addCsv const csvImport = this.$refs.addCsv

View File

@@ -7,6 +7,8 @@ import Worker from './_worker.js'
// https://github.com/nolanlawson/promise-worker // https://github.com/nolanlawson/promise-worker
import PromiseWorker from 'promise-worker' import PromiseWorker from 'promise-worker'
import { send } from '@/lib/utils/events'
function getNewDatabase () { function getNewDatabase () {
const worker = new Worker() const worker = new Worker()
return new Database(worker) return new Database(worker)
@@ -76,6 +78,15 @@ class Database {
this.dbName = file ? fu.getFileName(file) : 'database' this.dbName = file ? fu.getFileName(file) : 'database'
this.refreshSchema() this.refreshSchema()
send({
category: 'database',
action: 'import',
value: file ? file.size : 0,
label: file
? 'from=sqlite new_db=true'
: 'from=none new_db=true'
})
} }
async refreshSchema () { async refreshSchema () {
@@ -114,6 +125,12 @@ class Database {
throw new Error(data.error) throw new Error(data.error)
} }
fu.exportToFile(data, fileName) fu.exportToFile(data, fileName)
send({
category: 'database',
action: 'export',
value: data.byteLength,
label: 'to=sqlite'
})
} }
async validateTableName (name) { async validateTableName (name) {

View File

@@ -1,5 +1,6 @@
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import fu from '@/lib/utils/fileIo' import fu from '@/lib/utils/fileIo'
import { send } from '@/lib/utils/events'
import migration from './_migrations' import migration from './_migrations'
const migrate = migration._migrate const migrate = migration._migrate
@@ -103,7 +104,25 @@ export default {
importInquiries () { importInquiries () {
return fu.importFile() return fu.importFile()
.then(str => { .then(str => {
return this.deserialiseInquiries(str) const inquires = this.deserialiseInquiries(str)
send({
category: 'inquiry',
action: 'import',
value: inquires.length
})
return inquires
})
},
export (inquiryList, fileName) {
const jsonStr = this.serialiseInquiries(inquiryList)
fu.exportToFile(jsonStr, fileName)
send({
category: 'inquiry',
action: 'export',
value: inquiryList.length
}) })
}, },

11
src/lib/utils/events.js Normal file
View File

@@ -0,0 +1,11 @@
export function send (payload) {
console.log(payload)
if (!window.sendEvent) {
return
}
const event = new CustomEvent('sqliteviz-app-event', {
detail: payload
})
window.dispatchEvent(event)
}

View File

@@ -1,3 +1,4 @@
import { send } from '@/lib/utils/events'
let refresh = false let refresh = false
function invokeServiceWorkerUpdateFlow (registration) { function invokeServiceWorkerUpdateFlow (registration) {
@@ -41,4 +42,11 @@ if ('serviceWorker' in navigator) {
} }
}) })
}) })
window.addEventListener('appinstalled', () => {
send({
category: 'pwa',
action: 'install'
})
})
} }

View File

@@ -159,7 +159,6 @@ import TextField from '@/components/TextField'
import CheckBox from '@/components/CheckBox' import CheckBox from '@/components/CheckBox'
import tooltipMixin from '@/tooltipMixin' import tooltipMixin from '@/tooltipMixin'
import storedInquiries from '@/lib/storedInquiries' import storedInquiries from '@/lib/storedInquiries'
import fu from '@/lib/utils/fileIo'
export default { export default {
name: 'Inquiries', name: 'Inquiries',
@@ -385,8 +384,7 @@ export default {
return this.$store.state.tabs.findIndex(tab => tab.id === id) return this.$store.state.tabs.findIndex(tab => tab.id === id)
}, },
exportToFile (inquiryList, fileName) { exportToFile (inquiryList, fileName) {
const jsonStr = storedInquiries.serialiseInquiries(inquiryList) storedInquiries.export(inquiryList, fileName)
fu.exportToFile(jsonStr, fileName)
}, },
exportSelectedInquiries () { exportSelectedInquiries () {
const inquiryList = this.allInquiries.filter( const inquiryList = this.allInquiries.filter(

View File

@@ -57,6 +57,7 @@ import TextField from '@/components/TextField'
import CloseIcon from '@/components/svg/close' import CloseIcon from '@/components/svg/close'
import storedInquiries from '@/lib/storedInquiries' import storedInquiries from '@/lib/storedInquiries'
import AppDiagnosticInfo from './AppDiagnosticInfo' import AppDiagnosticInfo from './AppDiagnosticInfo'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'MainMenu', name: 'MainMenu',
@@ -110,6 +111,12 @@ export default {
this.$router.push('/workspace') this.$router.push('/workspace')
} }
}) })
send({
category: 'inquiry',
action: 'create',
label: 'auto=false'
})
}, },
cancelSave () { cancelSave () {
this.$modal.hide('save') this.$modal.hide('save')
@@ -163,6 +170,10 @@ export default {
// Signal about saving // Signal about saving
this.$root.$emit('inquirySaved') this.$root.$emit('inquirySaved')
send({
category: 'inquiry',
action: 'save'
})
}, },
_keyListener (e) { _keyListener (e) {
if (this.$route.path === '/workspace') { if (this.$route.path === '/workspace') {

View File

@@ -33,6 +33,7 @@
<script> <script>
import fIo from '@/lib/utils/fileIo' import fIo from '@/lib/utils/fileIo'
import { send } from '@/lib/utils/events'
import TableDescription from './TableDescription' import TableDescription from './TableDescription'
import TextField from '@/components/TextField' import TextField from '@/components/TextField'
import TreeChevron from '@/components/svg/treeChevron' import TreeChevron from '@/components/svg/treeChevron'
@@ -86,6 +87,13 @@ export default {
csvImport.reset() csvImport.reset()
await csvImport.previewCsv() await csvImport.previewCsv()
csvImport.open() csvImport.open()
send({
category: 'database',
action: 'import',
value: this.file.size,
label: 'from=csv new_db=false'
})
} }
} }
} }

View File

@@ -31,10 +31,15 @@ import PlotlyEditor from 'react-chart-editor'
import chartHelper from '@/lib/chartHelper' import chartHelper from '@/lib/chartHelper'
import dereference from 'react-chart-editor/lib/lib/dereference' import dereference from 'react-chart-editor/lib/lib/dereference'
import fIo from '@/lib/utils/fileIo' import fIo from '@/lib/utils/fileIo'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'Chart', name: 'Chart',
props: ['dataSources', 'initOptions', 'importToPngEnabled', 'importToSvgEnabled'], props: [
'dataSources', 'initOptions',
'importToPngEnabled', 'importToSvgEnabled',
'forPivot'
],
components: { components: {
PlotlyEditor PlotlyEditor
}, },
@@ -60,6 +65,19 @@ export default {
plotly.setPlotConfig({ plotly.setPlotConfig({
notifyOnLogging: 1 notifyOnLogging: 1
}) })
this.$watch(
() => JSON.stringify(
this.state.data.map(trace => `${trace.type}-${trace.mode}`)
),
(value) => {
send({
category: 'viz_plotly',
action: 'render',
label: `type=${value} pivot=${this.forPivot ? 'true' : 'false'}`
})
},
{ deep: true }
)
}, },
mounted () { mounted () {
this.resizeObserver = new ResizeObserver(this.handleResize) this.resizeObserver = new ResizeObserver(this.handleResize)

View File

@@ -23,6 +23,7 @@ import pivotHelper from './pivotHelper'
import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart' import Chart from '@/views/Main/Workspace/Tabs/Tab/DataView/Chart'
import chartHelper from '@/lib/chartHelper' import chartHelper from '@/lib/chartHelper'
import Vue from 'vue' import Vue from 'vue'
import { send } from '@/lib/utils/events'
const ChartClass = Vue.extend(Chart) const ChartClass = Vue.extend(Chart)
export default { export default {
@@ -89,6 +90,11 @@ export default {
handler () { handler () {
this.$emit('update:importToPngEnabled', this.pivotOptions.rendererName !== 'TSV Export') this.$emit('update:importToPngEnabled', this.pivotOptions.rendererName !== 'TSV Export')
this.$emit('update:importToSvgEnabled', this.viewStandartChart || this.viewCustomChart) this.$emit('update:importToSvgEnabled', this.viewStandartChart || this.viewCustomChart)
send({
category: 'viz_pivot',
action: 'render',
label: `type=${this.pivotOptions.rendererName}`
})
} }
}, },
pivotOptions () { pivotOptions () {
@@ -179,11 +185,11 @@ export default {
async prepareCopy () { async prepareCopy () {
if (this.viewCustomChart) { if (this.viewCustomChart) {
return await this.pivotOptions.rendererOptions.customChartComponent.prepareCopy() return await this.pivotOptions.rendererOptions.customChartComponent.prepareCopy()
} else if (this.viewStandartChart) {
return await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
} else {
return await pivotHelper.getPivotCanvas(this.$refs.pivotOutput)
} }
if (this.viewStandartChart) {
return await chartHelper.getImageDataUrl(this.$refs.pivotOutput, 'png')
}
return await pivotHelper.getPivotCanvas(this.$refs.pivotOutput)
}, },
async saveAsSvg () { async saveAsSvg () {
@@ -198,14 +204,18 @@ export default {
saveAsHtml () { saveAsHtml () {
if (this.viewCustomChart) { if (this.viewCustomChart) {
this.pivotOptions.rendererOptions.customChartComponent.saveAsHtml() this.pivotOptions.rendererOptions.customChartComponent.saveAsHtml()
} else if (this.viewStandartChart) { return
}
if (this.viewStandartChart) {
const chartState = chartHelper.getChartData(this.$refs.pivotOutput) const chartState = chartHelper.getChartData(this.$refs.pivotOutput)
fIo.exportToFile( fIo.exportToFile(
chartHelper.getHtml(chartState), chartHelper.getHtml(chartState),
'chart.html', 'chart.html',
'text/html' 'text/html'
) )
} else { return
}
fIo.exportToFile( fIo.exportToFile(
pivotHelper.getPivotHtml(this.$refs.pivotOutput), pivotHelper.getPivotHtml(this.$refs.pivotOutput),
'pivot.html', 'pivot.html',
@@ -214,7 +224,6 @@ export default {
} }
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@@ -51,6 +51,8 @@ export function _getDataSources (pivotData) {
function customChartRenderer (data, options) { function customChartRenderer (data, options) {
options.customChartComponent.dataSources = _getDataSources(data) options.customChartComponent.dataSources = _getDataSources(data)
options.customChartComponent.forPivot = true
options.customChartComponent.$mount() options.customChartComponent.$mount()
return $(options.customChartComponent.$el) return $(options.customChartComponent.$el)

View File

@@ -95,6 +95,7 @@ import ClipboardIcon from '@/components/svg/clipboard'
import cIo from '@/lib/utils/clipboardIo' import cIo from '@/lib/utils/clipboardIo'
import loadingDialog from '@/components/LoadingDialog' import loadingDialog from '@/components/LoadingDialog'
import time from '@/lib/utils/time' import time from '@/lib/utils/time'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'DataView', name: 'DataView',
@@ -123,6 +124,11 @@ export default {
dataToCopy: null dataToCopy: null
} }
}, },
computed: {
plotlyInPivot () {
return this.mode === 'pivot' && this.$refs.viewComponent.viewCustomChart
}
},
watch: { watch: {
mode () { mode () {
this.$emit('update') this.$emit('update')
@@ -148,6 +154,7 @@ export default {
*/ */
await time.sleep(0) await time.sleep(0)
this.$refs.viewComponent.saveAsPng() this.$refs.viewComponent.saveAsPng()
this.exportSignal('png')
}, },
getOptionsForSave () { getOptionsForSave () {
return this.$refs.viewComponent.getOptionsForSave() return this.$refs.viewComponent.getOptionsForSave()
@@ -178,6 +185,7 @@ export default {
async copyToClipboard () { async copyToClipboard () {
cIo.copyImage(this.dataToCopy) cIo.copyImage(this.dataToCopy)
this.$modal.hide('prepareCopy') this.$modal.hide('prepareCopy')
this.exportSignal('clipboard')
}, },
cancelCopy () { cancelCopy () {
this.dataToCopy = null this.dataToCopy = null
@@ -186,9 +194,20 @@ export default {
saveAsSvg () { saveAsSvg () {
this.$refs.viewComponent.saveAsSvg() this.$refs.viewComponent.saveAsSvg()
this.exportSignal('svg')
}, },
saveAsHtml () { saveAsHtml () {
this.$refs.viewComponent.saveAsHtml() this.$refs.viewComponent.saveAsHtml()
this.exportSignal('html')
},
exportSignal (to) {
send({
category: this.plotlyInPivot || this.mode === 'chart'
? 'viz_plotly' : 'viz_pivot',
action: 'export',
label: `type=${to}${this.plotlyInPivot
? ' pivot=true' : this.mode === 'chart' ? ' pivot=false' : ''}`
})
} }
} }
} }

View File

@@ -72,6 +72,7 @@ import fIo from '@/lib/utils/fileIo'
import cIo from '@/lib/utils/clipboardIo' import cIo from '@/lib/utils/clipboardIo'
import time from '@/lib/utils/time' import time from '@/lib/utils/time'
import loadingDialog from '@/components/LoadingDialog' import loadingDialog from '@/components/LoadingDialog'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'RunResult', name: 'RunResult',
@@ -117,10 +118,28 @@ export default {
}, },
exportToCsv () { exportToCsv () {
if (this.result && this.result.values) {
send({
category: 'resultset',
action: 'export',
value: this.result.values[this.result.columns[0]].length,
label: 'to=csv'
})
}
fIo.exportToFile(csv.serialize(this.result), 'result_set.csv', 'text/csv') fIo.exportToFile(csv.serialize(this.result), 'result_set.csv', 'text/csv')
}, },
async prepareCopy () { async prepareCopy () {
if (this.result && this.result.values) {
send({
category: 'resultset',
action: 'export',
value: this.result.values[this.result.columns[0]].length,
label: 'to=clipboard'
})
}
if ('ClipboardItem' in window) { if ('ClipboardItem' in window) {
this.preparingCopy = true this.preparingCopy = true
this.$modal.show('prepareCSVCopy') this.$modal.show('prepareCSVCopy')

View File

@@ -56,6 +56,7 @@ import DataView from './DataView'
import RunResult from './RunResult' import RunResult from './RunResult'
import time from '@/lib/utils/time' import time from '@/lib/utils/time'
import Teleport from 'vue2-teleport' import Teleport from 'vue2-teleport'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'Tab', name: 'Tab',
@@ -121,11 +122,33 @@ export default {
const start = new Date() 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()) this.time = time.getPeriod(start, new Date())
if (this.result && this.result.values) {
send({
category: 'resultset',
action: 'create',
value: this.result.values[this.result.columns[0]].length
})
}
send({
category: 'query',
action: 'run',
value: this.time,
label: 'status=success'
})
} catch (err) { } catch (err) {
this.error = { this.error = {
type: 'error', type: 'error',
message: err message: err
} }
send({
category: 'query',
action: 'run',
value: 0,
label: 'status=error'
})
} }
state.db.refreshSchema() state.db.refreshSchema()
this.isGettingResults = false this.isGettingResults = false

View File

@@ -19,6 +19,7 @@
import Splitpanes from '@/components/Splitpanes' import Splitpanes from '@/components/Splitpanes'
import Schema from './Schema' import Schema from './Schema'
import Tabs from './Tabs' import Tabs from './Tabs'
import { send } from '@/lib/utils/events'
export default { export default {
name: 'Workspace', name: 'Workspace',
@@ -49,6 +50,12 @@ export default {
const tabId = await this.$store.dispatch('addTab', { query: stmt }) const tabId = await this.$store.dispatch('addTab', { query: stmt })
this.$store.commit('setCurrentTabId', tabId) this.$store.commit('setCurrentTabId', tabId)
send({
category: 'inquiry',
action: 'create',
label: 'auto=true'
})
} }
} }
} }