mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
feat: dashboard tabs move in & move out
This commit is contained in:
Vendored
+33
@@ -8,9 +8,42 @@ export {}
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElStep: typeof import('element-plus/es')['ElStep']
|
||||
ElSteps: typeof import('element-plus/es')['ElSteps']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
Icon: typeof import('./src/components/icon-custom/src/Icon.vue')['default']
|
||||
Layout: typeof import('./src/components/layout/index.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
}
|
||||
export interface ComponentCustomProperties {
|
||||
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import {store} from "@/stores";
|
||||
export const dashboardStore = defineStore('dashboard', {
|
||||
state: () => {
|
||||
return {
|
||||
tabCollisionActiveId: null,
|
||||
tabMoveInActiveId: null,
|
||||
curComponent: null,
|
||||
canvasStyle: {},
|
||||
componentData: [],
|
||||
@@ -33,7 +35,13 @@ export const dashboardStore = defineStore('dashboard', {
|
||||
},
|
||||
setCanvasStyle(value: any) {
|
||||
this.canvasStyle = value
|
||||
}
|
||||
},
|
||||
setTabCollisionActiveId(tabId: any) {
|
||||
this.tabCollisionActiveId = tabId
|
||||
},
|
||||
setTabMoveInActiveId(tabId: any) {
|
||||
this.tabMoveInActiveId = tabId
|
||||
},
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
@@ -5,9 +5,13 @@ import {dashboardStoreWithOut} from '@/stores/dashboard/dashboard'
|
||||
import {type CanvasCoord, type CanvasItem} from '@/utils/canvas.ts'
|
||||
import CanvasShape from './CanvasShape.vue'
|
||||
import {findComponent} from "@/views/dashboard/components/component-list.ts";
|
||||
import {storeToRefs} from 'pinia'
|
||||
|
||||
const dashboardStore = dashboardStoreWithOut()
|
||||
|
||||
const {
|
||||
tabCollisionActiveId,
|
||||
tabMoveInActiveId
|
||||
} = storeToRefs(dashboardStore)
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
@@ -105,9 +109,12 @@ let lastTask: (() => void) | undefined = undefined
|
||||
let isOverlay = false
|
||||
let itemMaxX = 0
|
||||
let itemMaxY = 0
|
||||
|
||||
const moveTime = 80
|
||||
|
||||
const tabMoveInYOffset = 70
|
||||
// Effective area of collision depth
|
||||
const collisionGap = 10
|
||||
|
||||
function debounce(func: () => void, time: number) {
|
||||
if (!isOverlay) {
|
||||
isOverlay = true
|
||||
@@ -832,11 +839,10 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
|
||||
|
||||
let nowCloneItemX = infoBox.value.originX + moveXSize
|
||||
let nowCloneItemY = infoBox.value.originY + moveYSize
|
||||
|
||||
// Adjust the accuracy of moving coordinate changes
|
||||
const newX = Math.max(
|
||||
Math.floor(
|
||||
(nowCloneItemX + infoBox.value.cloneItem.offsetWidth / 24 - baseMarginLeft.value) /
|
||||
(nowCloneItemX + infoBox.value.cloneItem.offsetWidth / 96 - baseMarginLeft.value) /
|
||||
cellWidth.value +
|
||||
1
|
||||
),
|
||||
@@ -845,7 +851,7 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
|
||||
// Adjust the accuracy of moving coordinate changes
|
||||
const newY = Math.max(
|
||||
Math.floor(
|
||||
(nowCloneItemY + infoBox.value.cloneItem.offsetHeight / 24 - baseMarginTop.value) /
|
||||
(nowCloneItemY + infoBox.value.cloneItem.offsetHeight / 96 - baseMarginTop.value) /
|
||||
cellHeight.value +
|
||||
1
|
||||
),
|
||||
@@ -862,6 +868,7 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
|
||||
|
||||
infoBox.value.cloneItem.style.left = `${nowCloneItemX}px`
|
||||
infoBox.value.cloneItem.style.top = `${nowCloneItemY}px`
|
||||
tabMoveInCheckSQ()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,6 +957,104 @@ function moving() {
|
||||
// do moving
|
||||
}
|
||||
|
||||
// Obtain matrix position
|
||||
function getItemMatrixPosition(item: CanvasItem) {
|
||||
return {
|
||||
tw: cellWidth.value * item.sizeX - baseMarginLeft.value,
|
||||
th: cellHeight.value * item.sizeY - baseMarginTop.value,
|
||||
tl: cellWidth.value * (item.x - 1) + baseMarginLeft.value,
|
||||
tr: cellWidth.value * (item.sizeX + item.x - 1) + baseMarginLeft.value,
|
||||
tt: cellHeight.value * (item.y - 1) + baseMarginTop.value,
|
||||
tb: cellHeight.value * (item.sizeY + item.y - 1) + baseMarginLeft.value
|
||||
}
|
||||
}
|
||||
|
||||
// Get style location
|
||||
function getItemStylePosition(item: CanvasItem) {
|
||||
const {tw, th, tl, tr, tt, tb} = getItemMatrixPosition(item)
|
||||
return {
|
||||
tw: tw * (cellWidth.value + baseMarginLeft.value) - baseMarginLeft.value,
|
||||
th: th * (cellHeight.value + baseMarginTop.value) - baseMarginTop.value,
|
||||
tl: cellWidth.value * tl + baseMarginLeft.value,
|
||||
tr: cellWidth.value * tr + baseMarginLeft.value,
|
||||
tt: cellHeight.value * tt + baseMarginTop.value,
|
||||
tb: cellHeight.value * tb + baseMarginLeft.value
|
||||
}
|
||||
}
|
||||
|
||||
function tabMoveInCheck(cloneRefItem) {
|
||||
//1. If the current cloneItem type is not a tab,
|
||||
// check if there are any tab components with overlapping boundaries (about to overlap) in the top left and right directions of the current Item
|
||||
//2.If there is, the original item of the current cloneItem is not moving (the entire dashboard will not be rearranged)
|
||||
//3. Activate this tab item. At this time, the tab item displays the activation status
|
||||
//4. Release this cloneItem from the main canvas and remove the canvas with the added item
|
||||
const moveItem = infoBox.value.moveItem
|
||||
if (moveItem && moveItem !== 'SQTab') {
|
||||
canvasComponentData.value.forEach(item => {
|
||||
// Determine the position of SQTab components around moveItem
|
||||
if (item.id !== moveItem.id && item.component === 'SQTab') {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function tabMoveInCheckSQ() {
|
||||
const {cloneItem,moveItem} = infoBox.value.cloneItem
|
||||
if (cloneItem && moveItem && moveItem !== 'SQTab') {
|
||||
const width = cloneItem.offsetWidth
|
||||
const height = cloneItem.offsetHeight
|
||||
const left = cloneItem.offsetLeft
|
||||
const top = cloneItem.offsetTop
|
||||
canvasComponentData.value.forEach(item => {
|
||||
if (item.id !== moveItem.id && item.component === 'SQTab') {
|
||||
const {tw, th, tl, tt} = getItemStylePosition(item)
|
||||
// Collision effective area inspection
|
||||
const collisionT = tt + tabMoveInYOffset
|
||||
const collisionL = tl + collisionGap - width
|
||||
const collisionW = tw + 2 * width - collisionGap
|
||||
const collisionH = th + height - tabMoveInYOffset
|
||||
// Near the upper left corner area
|
||||
const tfAndTf = collisionT <= top && collisionL <= left
|
||||
// Near the lower left corner area
|
||||
const bfAndBf = collisionT + collisionH >= top + height && collisionL <= left
|
||||
// Near the upper right corner area
|
||||
const trAndTr = collisionT <= top && collisionL + collisionW >= left + width
|
||||
// Near the lower right corner area
|
||||
const brAndBr =
|
||||
collisionT + collisionH >= top + height && collisionL + collisionW >= left + width
|
||||
if (tfAndTf && bfAndBf && trAndTr && brAndBr) {
|
||||
dashboardStore.setTabCollisionActiveId(item.id)
|
||||
} else if (tabCollisionActiveId.value === item.id) {
|
||||
dashboardStore.setTabCollisionActiveId(null)
|
||||
}
|
||||
|
||||
|
||||
//Move into effective area for inspection
|
||||
//Collision effective area inspection
|
||||
const activeT = tt + tabMoveInYOffset
|
||||
const activeL = tl + collisionGap * 10 - width
|
||||
const activeW = tw + 2 * width - collisionGap * 20
|
||||
const activeH = th + height - 2 * tabMoveInYOffset
|
||||
|
||||
// Near the upper left corner area
|
||||
const activeTfAndTf = activeT <= top && activeL <= left
|
||||
// Near the lower left corner area
|
||||
const activeBfAndBf = activeT + activeH >= top + height && activeL <= left
|
||||
// Near the upper right corner area
|
||||
const activeTrAndTr = activeT <= top && activeL + activeW >= left + width
|
||||
// Near the lower right corner area
|
||||
const activeBrAndBr = activeT + activeH >= top + height && activeL + activeW >= left + width
|
||||
if (activeTfAndTf && activeBfAndBf && activeTrAndTr && activeBrAndBr) {
|
||||
dashboardStore.setTabMoveInActiveId(item.id)
|
||||
} else if (tabMoveInActiveId.value === item.id) {
|
||||
dashboardStore.setTabMoveInActiveId(null)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
getRenderState,
|
||||
|
||||
Reference in New Issue
Block a user