mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-08 11:08:55 +08:00
change code structure
This commit is contained in:
564
src/views/Main/MyQueries/index.vue
Normal file
564
src/views/Main/MyQueries/index.vue
Normal file
@@ -0,0 +1,564 @@
|
||||
<template>
|
||||
<div>
|
||||
<div id="start-guide" v-if="showedQueries.length === 0">
|
||||
You don't have saved queries so far.
|
||||
<span class="link" @click="$root.$emit('createNewQuery')">Create</span>
|
||||
the one from scratch or
|
||||
<span @click="importQueries" class="link">import</span> from a file.
|
||||
</div>
|
||||
<div id="my-queries-content" ref="my-queries-content" v-show="showedQueries.length > 0">
|
||||
<div id="my-queries-toolbar">
|
||||
<div id="toolbar-buttons">
|
||||
<button id="toolbar-btns-import" class="toolbar" @click="importQueries">
|
||||
Import
|
||||
</button>
|
||||
<button
|
||||
id="toolbar-btns-export"
|
||||
class="toolbar"
|
||||
v-show="selectedQueriesCount > 0"
|
||||
@click="exportSelectedQueries()"
|
||||
>
|
||||
Export
|
||||
</button>
|
||||
<button
|
||||
id="toolbar-btns-delete"
|
||||
class="toolbar"
|
||||
v-show="selectedNotPredefinedCount > 0"
|
||||
@click="showDeleteDialog(selectedQueriesIds)"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
<div id="toolbar-search">
|
||||
<text-field placeholder="Search query by name" width="300px" v-model="filter"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-bg">
|
||||
<div class="header-container">
|
||||
<div>
|
||||
<div class="fixed-header" ref="name-th">
|
||||
<check-box ref="mainCheckBox" theme="light" @click="toggleSelectAll"/>
|
||||
<div class="name-th">Name</div>
|
||||
</div>
|
||||
<div class="fixed-header">
|
||||
Created at
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container" :style="{ 'max-height': `${maxTableHeight}px` }">
|
||||
<table ref="table">
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(query, index) in showedQueries"
|
||||
:key="query.id"
|
||||
@click="openQuery(index)"
|
||||
>
|
||||
<td ref="name-td">
|
||||
<div class="cell-data">
|
||||
<check-box
|
||||
ref="rowCheckBox"
|
||||
:init="selectAll || selectedQueriesIds.has(query.id)"
|
||||
@click="toggleRow($event, query.id)"
|
||||
/>
|
||||
<div class="name">{{ query.name }}</div>
|
||||
<div
|
||||
v-if="query.isPredefined"
|
||||
class="badge"
|
||||
@mouseover="showTooltip"
|
||||
@mouseout="hideTooltip"
|
||||
>
|
||||
Predefined
|
||||
<span class="icon-tooltip" :style="tooltipStyle">
|
||||
Predefined queries come from the server.
|
||||
These queries can’t be deleted or renamed.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="second-column">
|
||||
<div class="date-container">{{ query.createdAt | date }}</div>
|
||||
<div class="icons-container">
|
||||
<rename-icon v-if="!query.isPredefined" @click="showRenameDialog(query.id)" />
|
||||
<copy-icon @click="duplicateQuery(index)"/>
|
||||
<export-icon
|
||||
@click="exportToFile([query], `${query.name}.json`)"
|
||||
tooltip="Export query to file"
|
||||
/>
|
||||
<delete-icon
|
||||
v-if="!query.isPredefined"
|
||||
@click="showDeleteDialog((new Set()).add(query.id))"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Rename Query dialog -->
|
||||
<modal name="rename" classes="dialog" height="auto">
|
||||
<div class="dialog-header">
|
||||
Rename query
|
||||
<close-icon @click="$modal.hide('rename')"/>
|
||||
</div>
|
||||
<div class="dialog-body">
|
||||
<text-field
|
||||
label="New query name"
|
||||
:error-msg="errorMsg"
|
||||
v-model="newName"
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
<div class="dialog-buttons-container">
|
||||
<button class="secondary" @click="$modal.hide('rename')">Cancel</button>
|
||||
<button class="primary" @click="renameQuery">Rename</button>
|
||||
</div>
|
||||
</modal>
|
||||
|
||||
<!--Delete Query dialog -->
|
||||
<modal name="delete" classes="dialog" height="auto">
|
||||
<div class="dialog-header">
|
||||
Delete {{ deleteGroup ? 'queries' : 'query' }}
|
||||
<close-icon @click="$modal.hide('delete')"/>
|
||||
</div>
|
||||
<div class="dialog-body">
|
||||
{{ deleteDialogMsg }}
|
||||
<div v-show="selectedQueriesCount > selectedNotPredefinedCount" id="note">
|
||||
<img :src="require('@/assets/images/info.svg')">
|
||||
Note: Predefined queries you've selected won't be deleted
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-buttons-container">
|
||||
<button class="secondary" @click="$modal.hide('delete')">Cancel</button>
|
||||
<button class="primary" @click="deleteQuery">Delete</button>
|
||||
</div>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RenameIcon from './svg/rename'
|
||||
import CopyIcon from './svg/copy'
|
||||
import ExportIcon from '@/components/svg/export'
|
||||
import DeleteIcon from './svg/delete'
|
||||
import CloseIcon from '@/components/svg/close'
|
||||
import TextField from '@/components/TextField'
|
||||
import CheckBox from '@/components/CheckBox'
|
||||
import tooltipMixin from '@/tooltipMixin'
|
||||
import storedQueries from '@/lib/storedQueries'
|
||||
import fu from '@/lib/utils/fileIo'
|
||||
|
||||
export default {
|
||||
name: 'MyQueries',
|
||||
components: {
|
||||
RenameIcon,
|
||||
CopyIcon,
|
||||
ExportIcon,
|
||||
DeleteIcon,
|
||||
CloseIcon,
|
||||
TextField,
|
||||
CheckBox
|
||||
},
|
||||
mixins: [tooltipMixin],
|
||||
data () {
|
||||
return {
|
||||
queries: [],
|
||||
filter: null,
|
||||
newName: null,
|
||||
processedQueryId: null,
|
||||
errorMsg: null,
|
||||
selectedQueriesIds: new Set(),
|
||||
selectedQueriesCount: 0,
|
||||
selectedNotPredefinedCount: 0,
|
||||
selectAll: false,
|
||||
deleteGroup: false,
|
||||
resizeObserver: null,
|
||||
maxTableHeight: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
predefinedQueries () {
|
||||
return this.$store.state.predefinedQueries.map(query => {
|
||||
query.isPredefined = true
|
||||
return query
|
||||
})
|
||||
},
|
||||
predefinedQueriesIds () {
|
||||
return new Set(this.predefinedQueries.map(query => query.id))
|
||||
},
|
||||
showedQueries () {
|
||||
let showedQueries = this.allQueries
|
||||
if (this.filter) {
|
||||
showedQueries = showedQueries.filter(
|
||||
query => query.name.toUpperCase().indexOf(this.filter.toUpperCase()) >= 0
|
||||
)
|
||||
}
|
||||
return showedQueries
|
||||
},
|
||||
allQueries () {
|
||||
return this.predefinedQueries.concat(this.queries)
|
||||
},
|
||||
processedQueryIndex () {
|
||||
return this.queries.findIndex(query => query.id === this.processedQueryId)
|
||||
},
|
||||
deleteDialogMsg () {
|
||||
if (!this.deleteGroup && (
|
||||
this.processedQueryIndex === null ||
|
||||
this.processedQueryIndex < 0 ||
|
||||
this.processedQueryIndex > this.queries.length
|
||||
)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
const deleteItem = this.deleteGroup
|
||||
? `${this.selectedNotPredefinedCount} ${this.selectedNotPredefinedCount > 1
|
||||
? 'queries'
|
||||
: 'query'}`
|
||||
: `"${this.queries[this.processedQueryIndex].name}"`
|
||||
|
||||
return `Are you sure you want to delete ${deleteItem}?`
|
||||
}
|
||||
},
|
||||
created () {
|
||||
storedQueries.readPredefinedQueries()
|
||||
.then(queries => {
|
||||
this.$store.commit('updatePredefinedQueries', queries)
|
||||
})
|
||||
.catch(console.error)
|
||||
.finally(() => {
|
||||
this.queries = storedQueries.getStoredQueries()
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
this.resizeObserver = new ResizeObserver(this.calcMaxTableHeight)
|
||||
this.resizeObserver.observe(this.$refs['my-queries-content'])
|
||||
|
||||
this.tableResizeObserver = new ResizeObserver(this.calcNameWidth)
|
||||
this.tableResizeObserver.observe(this.$refs.table)
|
||||
this.calcNameWidth()
|
||||
this.calcMaxTableHeight()
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.resizeObserver.unobserve(this.$refs['my-queries-content'])
|
||||
this.tableResizeObserver.unobserve(this.$refs.table)
|
||||
},
|
||||
filters: {
|
||||
date (value) {
|
||||
if (!value) {
|
||||
return ''
|
||||
}
|
||||
const dateOptions = { year: 'numeric', month: 'long', day: 'numeric' }
|
||||
const timeOptions = {
|
||||
hour12: false,
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}
|
||||
return new Date(value).toLocaleDateString('en-GB', dateOptions) + ' ' +
|
||||
new Date(value).toLocaleTimeString('en-GB', timeOptions)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
calcNameWidth () {
|
||||
const nameWidth = this.$refs['name-td']
|
||||
? this.$refs['name-td'][0].getBoundingClientRect().width
|
||||
: 0
|
||||
this.$refs['name-th'].style = `width: ${nameWidth}px`
|
||||
},
|
||||
calcMaxTableHeight () {
|
||||
const freeSpace = this.$refs['my-queries-content'].offsetHeight - 200
|
||||
this.maxTableHeight = freeSpace - (freeSpace % 40) + 1
|
||||
},
|
||||
openQuery (index) {
|
||||
const tab = this.showedQueries[index]
|
||||
this.$store.dispatch('addTab', tab).then(id => {
|
||||
this.$store.commit('setCurrentTabId', id)
|
||||
this.$router.push('/editor')
|
||||
})
|
||||
},
|
||||
showRenameDialog (id) {
|
||||
this.errorMsg = null
|
||||
this.processedQueryId = id
|
||||
this.newName = this.queries[this.processedQueryIndex].name
|
||||
this.$modal.show('rename')
|
||||
},
|
||||
renameQuery () {
|
||||
if (!this.newName) {
|
||||
this.errorMsg = 'Query name can\'t be empty'
|
||||
return
|
||||
}
|
||||
const processedQuery = this.queries[this.processedQueryIndex]
|
||||
processedQuery.name = this.newName
|
||||
this.$set(this.queries, this.processedQueryIndex, processedQuery)
|
||||
|
||||
// update queries in local storage
|
||||
storedQueries.updateStorage(this.queries)
|
||||
|
||||
// update tab, if renamed query is opened
|
||||
const tabIndex = this.findTabIndex(processedQuery.id)
|
||||
if (tabIndex >= 0) {
|
||||
this.$store.commit('updateTab', {
|
||||
index: tabIndex,
|
||||
name: this.newName,
|
||||
id: processedQuery.id
|
||||
})
|
||||
}
|
||||
// hide dialog
|
||||
this.$modal.hide('rename')
|
||||
},
|
||||
duplicateQuery (index) {
|
||||
const newQuery = storedQueries.duplicateQuery(this.showedQueries[index])
|
||||
if (this.selectAll) {
|
||||
this.selectedQueriesIds.add(newQuery.id)
|
||||
this.selectedQueriesCount = this.selectedQueriesIds.size
|
||||
}
|
||||
this.queries.push(newQuery)
|
||||
storedQueries.updateStorage(this.queries)
|
||||
},
|
||||
showDeleteDialog (idsSet) {
|
||||
this.deleteGroup = idsSet.size > 1
|
||||
if (!this.deleteGroup) {
|
||||
this.processedQueryId = idsSet.values().next().value
|
||||
}
|
||||
this.$modal.show('delete')
|
||||
},
|
||||
deleteQuery () {
|
||||
this.$modal.hide('delete')
|
||||
if (!this.deleteGroup) {
|
||||
this.queries.splice(this.processedQueryIndex, 1)
|
||||
|
||||
// Close deleted query tab if it was opened
|
||||
const tabIndex = this.findTabIndex(this.processedQueryId)
|
||||
if (tabIndex >= 0) {
|
||||
this.$store.commit('deleteTab', tabIndex)
|
||||
}
|
||||
|
||||
// Clear checkboxes
|
||||
if (this.selectedQueriesIds.has(this.processedQueryId)) {
|
||||
this.selectedQueriesIds.delete(this.processedQueryId)
|
||||
}
|
||||
} else {
|
||||
this.queries = this.selectAll
|
||||
? []
|
||||
: this.queries.filter(query => !this.selectedQueriesIds.has(query.id))
|
||||
|
||||
// Close deleted queries if it was opened
|
||||
const tabs = this.$store.state.tabs
|
||||
for (let i = tabs.length - 1; i >= 0; i--) {
|
||||
if (this.selectedQueriesIds.has(tabs[i].id)) {
|
||||
this.$store.commit('deleteTab', i)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear checkboxes
|
||||
this.selectedQueriesIds.clear()
|
||||
}
|
||||
this.selectedQueriesCount = this.selectedQueriesIds.size
|
||||
storedQueries.updateStorage(this.queries)
|
||||
},
|
||||
findTabIndex (id) {
|
||||
return this.$store.state.tabs.findIndex(tab => tab.id === id)
|
||||
},
|
||||
exportToFile (queryList, fileName) {
|
||||
const jsonStr = storedQueries.serialiseQueries(queryList)
|
||||
fu.exportToFile(jsonStr, fileName)
|
||||
},
|
||||
exportSelectedQueries () {
|
||||
const queryList = this.selectAll
|
||||
? this.allQueries
|
||||
: this.allQueries.filter(query => this.selectedQueriesIds.has(query.id))
|
||||
|
||||
this.exportToFile(queryList, 'My sqliteviz queries.json')
|
||||
},
|
||||
importQueries () {
|
||||
storedQueries.importQueries()
|
||||
.then(importedQueries => {
|
||||
if (this.selectAll) {
|
||||
importedQueries.forEach(query => {
|
||||
this.selectedQueriesIds.add(query.id)
|
||||
})
|
||||
this.selectedQueriesCount = this.selectedQueriesIds.size
|
||||
}
|
||||
|
||||
this.queries = this.queries.concat(importedQueries)
|
||||
storedQueries.updateStorage(this.queries)
|
||||
})
|
||||
},
|
||||
toggleSelectAll (checked) {
|
||||
this.selectAll = checked
|
||||
this.$refs.rowCheckBox.forEach(item => { item.checked = checked })
|
||||
|
||||
this.selectedQueriesIds = checked
|
||||
? new Set(this.allQueries.map(query => query.id))
|
||||
: new Set()
|
||||
|
||||
this.selectedQueriesCount = this.selectedQueriesIds.size
|
||||
this.selectedNotPredefinedCount = checked ? this.queries.length : 0
|
||||
},
|
||||
toggleRow (checked, id) {
|
||||
const isPredefined = this.predefinedQueriesIds.has(id)
|
||||
if (checked) {
|
||||
this.selectedQueriesIds.add(id)
|
||||
if (!isPredefined) {
|
||||
this.selectedNotPredefinedCount += 1
|
||||
}
|
||||
} else {
|
||||
if (this.selectedQueriesIds.size === this.allQueries.length) {
|
||||
this.$refs.mainCheckBox.checked = false
|
||||
this.selectAll = false
|
||||
}
|
||||
this.selectedQueriesIds.delete(id)
|
||||
if (!isPredefined) {
|
||||
this.selectedNotPredefinedCount -= 1
|
||||
}
|
||||
}
|
||||
this.selectedQueriesCount = this.selectedQueriesIds.size
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#start-guide {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: var(--color-text-base);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#my-queries-content {
|
||||
padding: 52px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#my-queries-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 18px;
|
||||
margin: 0 auto 8px;
|
||||
max-width: 1500px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.rounded-bg {
|
||||
margin: 0 auto;
|
||||
max-width: 1500px;
|
||||
width: 100%;
|
||||
}
|
||||
.fixed-header {
|
||||
padding: 11px 24px;
|
||||
}
|
||||
.fixed-header:first-child {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 12px;
|
||||
}
|
||||
.fixed-header:first-child .name-th {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
tbody tr td {
|
||||
min-width: 0;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
tbody tr td:first-child {
|
||||
width: 70%;
|
||||
max-width: 0;
|
||||
padding: 0 12px;
|
||||
}
|
||||
tbody tr td:last-child {
|
||||
width: 30%;
|
||||
max-width: 0;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
tbody .cell-data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
tbody .cell-data div.name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
tbody tr:hover td {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
tbody tr:hover td {
|
||||
color: var(--color-text-active);
|
||||
}
|
||||
|
||||
.second-column {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.icons-container {
|
||||
display: none;
|
||||
margin-right: -12px;
|
||||
}
|
||||
.date-container {
|
||||
flex-shrink: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
tbody tr:hover .icons-container {
|
||||
display: flex;
|
||||
}
|
||||
.dialog input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button.toolbar {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: none;
|
||||
background-color: var(--color-gray-light-4);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-small);
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
line-height: normal;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
tbody tr:hover .badge {
|
||||
display: block;
|
||||
}
|
||||
#note {
|
||||
margin-top: 24px;
|
||||
}
|
||||
#note img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.icon-tooltip {
|
||||
display: block;
|
||||
width: 149px;
|
||||
white-space: normal;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
padding: 6px;
|
||||
}
|
||||
</style>
|
||||
42
src/views/Main/MyQueries/svg/copy.vue
Normal file
42
src/views/Main/MyQueries/svg/copy.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<span>
|
||||
<svg
|
||||
class="icon"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@click.stop="$emit('click')"
|
||||
@mouseover="showTooltip"
|
||||
@mouseout="hideTooltip"
|
||||
>
|
||||
<path
|
||||
d="M14.25 15.75H6V5.25H14.25V15.75ZM14.25 3.75H6C5.60218 3.75 5.22064 3.90804 4.93934 4.18934C4.65804 4.47064 4.5 4.85218 4.5 5.25V15.75C4.5 16.1478 4.65804 16.5294 4.93934 16.8107C5.22064 17.092 5.60218 17.25 6 17.25H14.25C14.6478 17.25 15.0294 17.092 15.3107 16.8107C15.592 16.5294 15.75 16.1478 15.75 15.75V5.25C15.75 4.85218 15.592 4.47064 15.3107 4.18934C15.0294 3.90804 14.6478 3.75 14.25 3.75ZM12 0.75H3C2.60218 0.75 2.22064 0.908035 1.93934 1.18934C1.65804 1.47064 1.5 1.85218 1.5 2.25V12.75H3V2.25H12V0.75Z"
|
||||
fill="#A2B1C6"
|
||||
/>
|
||||
</svg>
|
||||
<span class="icon-tooltip" :style="tooltipStyle">
|
||||
Duplicate query
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tooltipMixin from '@/tooltipMixin'
|
||||
|
||||
export default {
|
||||
name: 'CopyIcon',
|
||||
mixins: [tooltipMixin]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
display: block;
|
||||
margin: 0 12px;
|
||||
}
|
||||
.icon:hover path {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
</style>
|
||||
43
src/views/Main/MyQueries/svg/delete.vue
Normal file
43
src/views/Main/MyQueries/svg/delete.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<span>
|
||||
<svg
|
||||
class="icon"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@click.stop="$emit('click')"
|
||||
@mouseover="showTooltip"
|
||||
@mouseout="hideTooltip"
|
||||
>
|
||||
<path
|
||||
d="M6.75 2.25V3H3V4.5H3.75V14.25C3.75 14.6478 3.90804 15.0294 4.18934 15.3107C4.47064 15.592 4.85218 15.75 5.25 15.75H12.75C13.1478 15.75 13.5294 15.592 13.8107 15.3107C14.092 15.0294 14.25 14.6478 14.25 14.25V4.5H15V3H11.25V2.25H6.75ZM5.25 4.5H12.75V14.25H5.25V4.5ZM6.75 6V12.75H8.25V6H6.75ZM9.75 6V12.75H11.25V6H9.75Z"
|
||||
fill="#A2B1C6"
|
||||
/>
|
||||
</svg>
|
||||
<span class="icon-tooltip" :style="tooltipStyle">
|
||||
Delete query
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tooltipMixin from '@/tooltipMixin'
|
||||
|
||||
export default {
|
||||
name: 'DeleteIcon',
|
||||
mixins: [tooltipMixin]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
display: block;
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
.icon:hover path {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
</style>
|
||||
43
src/views/Main/MyQueries/svg/rename.vue
Normal file
43
src/views/Main/MyQueries/svg/rename.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<span>
|
||||
<svg
|
||||
class="icon"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@click.stop="$emit('click')"
|
||||
@mouseover="showTooltip"
|
||||
@mouseout="hideTooltip"
|
||||
>
|
||||
<path
|
||||
d="M10.545 6.75L11.25 7.455L4.44 14.25H3.75V13.56L10.545 6.75ZM13.245 2.25C13.0575 2.25 12.8625 2.325 12.72 2.4675L11.3475 3.84L14.16 6.6525L15.5325 5.28C15.825 4.9875 15.825 4.5 15.5325 4.2225L13.7775 2.4675C13.6275 2.3175 13.44 2.25 13.245 2.25ZM10.545 4.6425L2.25 12.9375V15.75H5.0625L13.3575 7.455L10.545 4.6425Z"
|
||||
fill="#A2B1C6"
|
||||
/>
|
||||
</svg>
|
||||
<span class="icon-tooltip" :style="tooltipStyle">
|
||||
Rename query
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import tooltipMixin from '@/tooltipMixin'
|
||||
|
||||
export default {
|
||||
name: 'RenameIcon',
|
||||
mixins: [tooltipMixin]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.icon {
|
||||
display: block;
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
.icon:hover path {
|
||||
fill: var(--color-accent);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user