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
2025-03-30 15:57:47 +02:00
parent 6f7961e1b4
commit df16383d49
64 changed files with 316 additions and 279 deletions

View File

@@ -8,18 +8,18 @@
>
<div class="value">
<input
:class="{ filled: filled }"
ref="delimiterInput"
v-model="inputValue"
:class="{ filled: filled }"
type="text"
maxlength="1"
v-model="inputValue"
@click.stop
:disabled="disabled"
@click.stop
/>
<div class="name">{{ getSymbolName(modelValue) }}</div>
</div>
<div class="controls" @click.stop>
<clear-icon @click="clear" :disabled="disabled" />
<clear-icon :disabled="disabled" @click="clear" />
<drop-down-chevron
:disabled="disabled"
@click="!disabled && (showOptions = !showOptions)"
@@ -30,8 +30,8 @@
<div
v-for="(option, index) in options"
:key="index"
@click="chooseOption(option)"
class="option"
@click="chooseOption(option)"
>
<pre>{{ option }}</pre>
<div>{{ getSymbolName(option) }}</div>
@@ -47,9 +47,13 @@ import ClearIcon from '@/components/svg/clear'
export default {
name: 'DelimiterSelector',
props: ['modelValue', 'width', 'disabled'],
emits: ['update:modelValue'],
components: { DropDownChevron, ClearIcon },
props: {
modelValue: String,
width: String,
disabled: Boolean
},
emits: ['update:modelValue'],
data() {
return {
showOptions: false,
@@ -84,7 +88,7 @@ export default {
this.inputValue = option
this.showOptions = false
},
onContainerClick(event) {
onContainerClick() {
this.$refs.delimiterInput.focus()
},

View File

@@ -4,20 +4,20 @@
class="dialog"
content-class="import-modal"
scrollable
:clickToClose="false"
:click-to-close="false"
>
<div class="dialog-header">
{{ typeName }} import
<close-icon @click="cancelImport" :disabled="disableDialog" />
<close-icon :disabled="disableDialog" @click="cancelImport" />
</div>
<div class="dialog-body">
<text-field
label="Table name"
id="csv-json-table-name"
v-model="tableName"
label="Table name"
width="484px"
:disabled="disableDialog"
:error-msg="tableNameError"
id="csv-json-table-name"
/>
<div v-if="!isJson && !isNdJson" class="chars">
<delimiter-selector
@@ -28,27 +28,27 @@
@input="preview"
/>
<text-field
id="quote-char"
v-model="quoteChar"
label="Quote char"
hint="The character used to quote fields."
v-model="quoteChar"
width="93px"
:disabled="disableDialog"
class="char-input"
id="quote-char"
@input="preview"
/>
<text-field
id="escape-char"
v-model="escapeChar"
label="Escape char"
hint='
The character used to escape the quote character within a field
(e.g. "column with ""quotes"" in text").
'
max-hint-width="242px"
v-model="escapeChar"
width="93px"
:disabled="disableDialog"
class="char-input"
id="escape-char"
@input="preview"
/>
</div>
@@ -70,28 +70,28 @@
</div>
<div class="dialog-buttons-container">
<button
id="import-cancel"
class="secondary"
:disabled="disableDialog"
@click="cancelImport"
id="import-cancel"
>
Cancel
</button>
<button
v-show="!importCompleted"
id="import-start"
class="primary"
:disabled="disableDialog || disableImport"
@click="loadToDb(file)"
id="import-start"
>
Import
</button>
<button
v-show="importCompleted"
id="import-finish"
class="primary"
:disabled="disableDialog"
@click="finish"
id="import-finish"
>
Finish
</button>

View File

@@ -63,6 +63,10 @@ import events from '@/lib/utils/events'
export default {
name: 'DbUploader',
components: {
ChangeDbIcon,
CsvJsonImport
},
props: {
type: {
type: String,
@@ -79,10 +83,6 @@ export default {
}
},
emits: [],
components: {
ChangeDbIcon,
CsvJsonImport
},
data() {
return {
state: '',

View File

@@ -12,9 +12,9 @@
</div>
<span
v-if="tooltip"
ref="tooltip"
class="icon-tooltip"
:style="tooltipStyle"
ref="tooltip"
>
{{ tooltip }}
</span>
@@ -27,10 +27,16 @@ import LoadingIndicator from '@/components/LoadingIndicator'
export default {
name: 'SideBarButton',
props: ['active', 'disabled', 'tooltip', 'tooltipPosition', 'loading'],
emits: ['click'],
components: { LoadingIndicator },
mixins: [tooltipMixin],
props: {
active: Boolean,
disabled: Boolean,
tooltip: String,
tooltipPosition: String,
loading: Boolean
},
emits: ['click'],
methods: {
onClick() {
this.hideTooltip()

View File

@@ -2,13 +2,13 @@
<modal
:modal-id="name"
class="dialog"
:clickToClose="false"
:contentTransition="{ name: 'loading-dialog' }"
:overlayTransition="{ name: 'loading-dialog' }"
:click-to-close="false"
:content-transition="{ name: 'loading-dialog' }"
:overlay-transition="{ name: 'loading-dialog' }"
>
<div class="dialog-header">
{{ title }}
<close-icon @click="$emit('cancel')" :disabled="loading" />
<close-icon :disabled="loading" @click="$emit('cancel')" />
</div>
<div class="dialog-body">
<div v-if="loading" class="loading-dialog-body">
@@ -49,7 +49,8 @@ import LoadingIndicator from '@/components/LoadingIndicator'
import CloseIcon from '@/components/svg/close'
export default {
name: 'loadingDialog',
name: 'LoadingDialog',
components: { LoadingIndicator, CloseIcon },
props: {
loadingMsg: String,
successMsg: String,
@@ -66,7 +67,6 @@ export default {
}
}
},
components: { LoadingIndicator, CloseIcon },
methods: {
cancel() {
this.$emit('cancel')

View File

@@ -1,5 +1,5 @@
<template>
<div class="logs-container" ref="logsContainer">
<div ref="logsContainer" class="logs-container">
<div v-for="(msg, index) in messages" :key="index" class="msg">
<img v-if="msg.type === 'error'" src="~@/assets/images/error.svg" />
<img
@@ -21,10 +21,10 @@
import LoadingIndicator from '@/components/LoadingIndicator'
export default {
name: 'logs',
props: ['messages'],
emits: [],
name: 'Logs',
components: { LoadingIndicator },
props: { messages: Array },
emits: [],
watch: {
'messages.length': 'scrollToBottom'
},

View File

@@ -8,13 +8,13 @@
]"
>
<div
class="movable-splitter"
ref="movableSplitter"
class="movable-splitter"
:style="movableSplitterStyle"
/>
<div
class="splitpanes-pane"
ref="left"
class="splitpanes-pane"
:size="paneBefore.size"
max-size="30"
:style="styles.before"
@@ -64,7 +64,7 @@
</div>
</div>
<!-- splitter end -->
<div class="splitpanes-pane" ref="right" :style="styles.after">
<div ref="right" class="splitpanes-pane" :style="styles.after">
<slot name="right-pane" />
</div>
</div>
@@ -158,6 +158,9 @@ export default {
}
}
},
mounted() {
this.container = this.$refs.container
},
methods: {
bindEvents() {
@@ -242,9 +245,6 @@ export default {
this.paneAfter.size = this.beforeMinimising.after
}
}
},
mounted() {
this.container = this.$refs.container
}
}
</script>

View File

@@ -1,5 +1,6 @@
<template>
<paginate
v-model="page"
:page-count="pageCount"
:page-range="5"
:margin-pages="1"
@@ -13,7 +14,6 @@
next-link-class="paginator-next"
prev-link-class="paginator-prev"
disabled-class="paginator-disabled"
v-model="page"
/>
</template>
@@ -23,7 +23,10 @@ import Paginate from 'vuejs-paginate-next'
export default {
name: 'Pager',
components: { Paginate },
props: ['pageCount', 'modelValue'],
props: {
pageCount: Number,
modelValue: Number
},
emits: ['update:modelValue'],
data() {
return {

View File

@@ -1,13 +1,13 @@
<template>
<div>
<div class="rounded-bg">
<div class="header-container" ref="header-container">
<div ref="header-container" class="header-container">
<div>
<div
v-for="(th, index) in header"
:key="index"
class="fixed-header"
:style="{ width: `${th.width}px` }"
:key="index"
:title="th.name"
>
{{ th.name }}
@@ -15,8 +15,8 @@
</div>
</div>
<div
class="table-container"
ref="table-container"
class="table-container"
@scroll="onScrollTable"
>
<table
@@ -36,11 +36,11 @@
<tr v-for="rowIndex in currentPageData.count" :key="rowIndex">
<td
v-for="(col, colIndex) in columns"
:key="colIndex"
:data-col="colIndex"
:data-row="pageSize * (currentPage - 1) + rowIndex - 1"
:data-isNull="isNull(getCellValue(col, rowIndex))"
:data-isBlob="isBlob(getCellValue(col, rowIndex))"
:key="colIndex"
:aria-selected="false"
@click="onCellClick"
>
@@ -61,8 +61,8 @@
</div>
<pager
v-show="pageCount > 1"
:page-count="pageCount"
v-model="currentPage"
:page-count="pageCount"
/>
</div>
</div>
@@ -125,6 +125,15 @@ export default {
}
}
},
watch: {
currentPageData() {
this.calculateHeadersWidth()
this.selectCell(null)
},
dataSet() {
this.currentPage = 1
}
},
mounted() {
this.resizeObserver = new ResizeObserver(this.calculateHeadersWidth)
this.resizeObserver.observe(this.$refs.table)
@@ -140,6 +149,9 @@ export default {
}
}
},
beforeUnmount() {
this.resizeObserver.unobserve(this.$refs.table)
},
methods: {
isBlob(value) {
return value && ArrayBuffer.isView(value)
@@ -252,18 +264,6 @@ export default {
this.selectCell(newCell)
}
}
},
beforeUnmount() {
this.resizeObserver.unobserve(this.$refs.table)
},
watch: {
currentPageData() {
this.calculateHeadersWidth()
this.selectCell(null)
},
dataSet() {
this.currentPage = 1
}
}
}
</script>

View File

@@ -6,8 +6,8 @@
>
{{ label }}
<hint-icon
class="hint"
v-if="hint"
class="hint"
:hint="hint"
:max-width="maxHintWidth || '149px'"
/>
@@ -28,18 +28,19 @@
<script>
import HintIcon from '@/components/svg/hint'
export default {
name: 'textField',
props: [
'placeholder',
'label',
'errorMsg',
'modelValue',
'width',
'hint',
'maxHintWidth',
'disabled'
],
components: { HintIcon }
name: 'TextField',
components: { HintIcon },
props: {
placeholder: String,
label: String,
errorMsg: String,
modelValue: String,
width: String,
hint: String,
maxHintWidth: String,
disabled: Boolean
},
emits: ['update:modelValue']
}
</script>

View File

@@ -33,7 +33,7 @@
</clipPath>
</defs>
</svg>
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
<span ref="tooltip" class="icon-tooltip" :style="tooltipStyle">
Add new table from CSV, JSON or NDJSON
</span>
</span>
@@ -45,7 +45,7 @@ import tooltipMixin from '@/tooltipMixin'
export default {
name: 'AddTableIcon',
mixins: [tooltipMixin],
props: ['tooltip'],
props: { tooltip: String },
emits: ['click'],
methods: {
onClick() {

View File

@@ -21,7 +21,7 @@
fill="#A2B1C6"
/>
</svg>
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
<span ref="tooltip" class="icon-tooltip" :style="tooltipStyle">
Load another database, CSV, JSON or NDJSON
</span>
</div>
@@ -31,7 +31,7 @@
import tooltipMixin from '@/tooltipMixin'
export default {
name: 'changeDbIcon',
name: 'ChangeDbIcon',
mixins: [tooltipMixin],
emits: ['click'],
methods: {

View File

@@ -23,7 +23,7 @@
<script>
export default {
name: 'ClearIcon',
props: ['disabled']
props: { disabled: Boolean }
}
</script>

View File

@@ -1,12 +1,12 @@
<template>
<svg
@click.stop="$emit('click')"
:class="['icon', { disabled: disabled }]"
:width="size"
:height="size"
viewBox="0 0 14 14"
fill="none"
xmlns="http://www.w3.org/2000/svg"
@click.stop="$emit('click')"
>
<path
d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14

View File

@@ -17,7 +17,7 @@
<script>
export default {
name: 'DropDownChevron',
props: ['disabled']
props: { disabled: Boolean }
}
</script>

View File

@@ -17,7 +17,7 @@
fill="#A2B1C6"
/>
</svg>
<span class="icon-tooltip" :style="tooltipStyle" ref="tooltip">
<span ref="tooltip" class="icon-tooltip" :style="tooltipStyle">
{{ tooltip }}
</span>
</span>
@@ -29,7 +29,10 @@ import tooltipMixin from '@/tooltipMixin'
export default {
name: 'ExportIcon',
mixins: [tooltipMixin],
props: ['tooltip', 'tooltipPosition'],
props: {
tooltip: String,
tooltipPosition: String
},
emits: ['click'],
methods: {
onClick() {

View File

@@ -34,9 +34,9 @@
/>
</svg>
<span
ref="tooltip"
class="icon-tooltip"
:style="{ ...tooltipStyle, maxWidth: maxWidth }"
ref="tooltip"
>
{{ hint }}
</span>
@@ -48,9 +48,12 @@ import tooltipMixin from '@/tooltipMixin'
export default {
name: 'HintIcon',
props: ['hint', 'maxWidth'],
emits: ['click'],
mixins: [tooltipMixin],
props: {
hint: String,
maxWidth: String
},
emits: ['click'],
methods: {
onClick() {
this.hideTooltip()

View File

@@ -18,7 +18,7 @@
<script>
export default {
name: 'treeChevron',
name: 'TreeChevron',
props: {
expanded: {
type: Boolean,