Skip to content

Commit 132c94d

Browse files
committed
feat: dashboard tabs move in & move out
1 parent 6529442 commit 132c94d

File tree

3 files changed

+152
-6
lines changed

3 files changed

+152
-6
lines changed

frontend/components.d.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,42 @@ export {}
88
/* prettier-ignore */
99
declare module 'vue' {
1010
export interface GlobalComponents {
11+
ElAvatar: typeof import('element-plus/es')['ElAvatar']
12+
ElButton: typeof import('element-plus/es')['ElButton']
13+
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
14+
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
15+
ElCol: typeof import('element-plus/es')['ElCol']
16+
ElDialog: typeof import('element-plus/es')['ElDialog']
17+
ElDivider: typeof import('element-plus/es')['ElDivider']
18+
ElDropdown: typeof import('element-plus/es')['ElDropdown']
19+
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
20+
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
21+
ElForm: typeof import('element-plus/es')['ElForm']
22+
ElFormItem: typeof import('element-plus/es')['ElFormItem']
23+
ElIcon: typeof import('element-plus/es')['ElIcon']
24+
ElInput: typeof import('element-plus/es')['ElInput']
25+
ElMenu: typeof import('element-plus/es')['ElMenu']
26+
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
27+
ElOption: typeof import('element-plus/es')['ElOption']
28+
ElRadio: typeof import('element-plus/es')['ElRadio']
29+
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
30+
ElRow: typeof import('element-plus/es')['ElRow']
31+
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
32+
ElSelect: typeof import('element-plus/es')['ElSelect']
33+
ElStep: typeof import('element-plus/es')['ElStep']
34+
ElSteps: typeof import('element-plus/es')['ElSteps']
35+
ElTable: typeof import('element-plus/es')['ElTable']
36+
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
37+
ElTabPane: typeof import('element-plus/es')['ElTabPane']
38+
ElTabs: typeof import('element-plus/es')['ElTabs']
39+
ElTooltip: typeof import('element-plus/es')['ElTooltip']
40+
ElUpload: typeof import('element-plus/es')['ElUpload']
1141
Icon: typeof import('./src/components/icon-custom/src/Icon.vue')['default']
1242
Layout: typeof import('./src/components/layout/index.vue')['default']
1343
RouterLink: typeof import('vue-router')['RouterLink']
1444
RouterView: typeof import('vue-router')['RouterView']
1545
}
46+
export interface ComponentCustomProperties {
47+
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
48+
}
1649
}

frontend/src/stores/dashboard/dashboard.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {store} from "@/stores";
44
export const dashboardStore = defineStore('dashboard', {
55
state: () => {
66
return {
7+
tabCollisionActiveId: null,
8+
tabMoveInActiveId: null,
79
curComponent: null,
810
canvasStyle: {},
911
componentData: [],
@@ -33,7 +35,13 @@ export const dashboardStore = defineStore('dashboard', {
3335
},
3436
setCanvasStyle(value: any) {
3537
this.canvasStyle = value
36-
}
38+
},
39+
setTabCollisionActiveId(tabId: any) {
40+
this.tabCollisionActiveId = tabId
41+
},
42+
setTabMoveInActiveId(tabId: any) {
43+
this.tabMoveInActiveId = tabId
44+
},
3745

3846
}
3947
})

frontend/src/views/dashboard/canvas/CanvasCore.vue

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import {dashboardStoreWithOut} from '@/stores/dashboard/dashboard'
55
import {type CanvasCoord, type CanvasItem} from '@/utils/canvas.ts'
66
import CanvasShape from './CanvasShape.vue'
77
import {findComponent} from "@/views/dashboard/components/component-list.ts";
8+
import {storeToRefs} from 'pinia'
89
910
const dashboardStore = dashboardStoreWithOut()
10-
11+
const {
12+
tabCollisionActiveId,
13+
tabMoveInActiveId
14+
} = storeToRefs(dashboardStore)
1115
1216
// Props
1317
const props = defineProps({
@@ -105,9 +109,12 @@ let lastTask: (() => void) | undefined = undefined
105109
let isOverlay = false
106110
let itemMaxX = 0
107111
let itemMaxY = 0
108-
109112
const moveTime = 80
110113
114+
const tabMoveInYOffset = 70
115+
// Effective area of collision depth
116+
const collisionGap = 10
117+
111118
function debounce(func: () => void, time: number) {
112119
if (!isOverlay) {
113120
isOverlay = true
@@ -832,11 +839,10 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
832839
833840
let nowCloneItemX = infoBox.value.originX + moveXSize
834841
let nowCloneItemY = infoBox.value.originY + moveYSize
835-
836842
// Adjust the accuracy of moving coordinate changes
837843
const newX = Math.max(
838844
Math.floor(
839-
(nowCloneItemX + infoBox.value.cloneItem.offsetWidth / 24 - baseMarginLeft.value) /
845+
(nowCloneItemX + infoBox.value.cloneItem.offsetWidth / 96 - baseMarginLeft.value) /
840846
cellWidth.value +
841847
1
842848
),
@@ -845,7 +851,7 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
845851
// Adjust the accuracy of moving coordinate changes
846852
const newY = Math.max(
847853
Math.floor(
848-
(nowCloneItemY + infoBox.value.cloneItem.offsetHeight / 24 - baseMarginTop.value) /
854+
(nowCloneItemY + infoBox.value.cloneItem.offsetHeight / 96 - baseMarginTop.value) /
849855
cellHeight.value +
850856
1
851857
),
@@ -862,6 +868,7 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
862868
863869
infoBox.value.cloneItem.style.left = `${nowCloneItemX}px`
864870
infoBox.value.cloneItem.style.top = `${nowCloneItemY}px`
871+
tabMoveInCheckSQ()
865872
}
866873
}
867874
@@ -950,6 +957,104 @@ function moving() {
950957
// do moving
951958
}
952959
960+
// Obtain matrix position
961+
function getItemMatrixPosition(item: CanvasItem) {
962+
return {
963+
tw: cellWidth.value * item.sizeX - baseMarginLeft.value,
964+
th: cellHeight.value * item.sizeY - baseMarginTop.value,
965+
tl: cellWidth.value * (item.x - 1) + baseMarginLeft.value,
966+
tr: cellWidth.value * (item.sizeX + item.x - 1) + baseMarginLeft.value,
967+
tt: cellHeight.value * (item.y - 1) + baseMarginTop.value,
968+
tb: cellHeight.value * (item.sizeY + item.y - 1) + baseMarginLeft.value
969+
}
970+
}
971+
972+
// Get style location
973+
function getItemStylePosition(item: CanvasItem) {
974+
const {tw, th, tl, tr, tt, tb} = getItemMatrixPosition(item)
975+
return {
976+
tw: tw * (cellWidth.value + baseMarginLeft.value) - baseMarginLeft.value,
977+
th: th * (cellHeight.value + baseMarginTop.value) - baseMarginTop.value,
978+
tl: cellWidth.value * tl + baseMarginLeft.value,
979+
tr: cellWidth.value * tr + baseMarginLeft.value,
980+
tt: cellHeight.value * tt + baseMarginTop.value,
981+
tb: cellHeight.value * tb + baseMarginLeft.value
982+
}
983+
}
984+
985+
function tabMoveInCheck(cloneRefItem) {
986+
//1. If the current cloneItem type is not a tab,
987+
// check if there are any tab components with overlapping boundaries (about to overlap) in the top left and right directions of the current Item
988+
//2.If there is, the original item of the current cloneItem is not moving (the entire dashboard will not be rearranged)
989+
//3. Activate this tab item. At this time, the tab item displays the activation status
990+
//4. Release this cloneItem from the main canvas and remove the canvas with the added item
991+
const moveItem = infoBox.value.moveItem
992+
if (moveItem && moveItem !== 'SQTab') {
993+
canvasComponentData.value.forEach(item => {
994+
// Determine the position of SQTab components around moveItem
995+
if (item.id !== moveItem.id && item.component === 'SQTab') {
996+
}
997+
})
998+
}
999+
}
1000+
1001+
function tabMoveInCheckSQ() {
1002+
const {cloneItem,moveItem} = infoBox.value.cloneItem
1003+
if (cloneItem && moveItem && moveItem !== 'SQTab') {
1004+
const width = cloneItem.offsetWidth
1005+
const height = cloneItem.offsetHeight
1006+
const left = cloneItem.offsetLeft
1007+
const top = cloneItem.offsetTop
1008+
canvasComponentData.value.forEach(item => {
1009+
if (item.id !== moveItem.id && item.component === 'SQTab') {
1010+
const {tw, th, tl, tt} = getItemStylePosition(item)
1011+
// Collision effective area inspection
1012+
const collisionT = tt + tabMoveInYOffset
1013+
const collisionL = tl + collisionGap - width
1014+
const collisionW = tw + 2 * width - collisionGap
1015+
const collisionH = th + height - tabMoveInYOffset
1016+
// Near the upper left corner area
1017+
const tfAndTf = collisionT <= top && collisionL <= left
1018+
// Near the lower left corner area
1019+
const bfAndBf = collisionT + collisionH >= top + height && collisionL <= left
1020+
// Near the upper right corner area
1021+
const trAndTr = collisionT <= top && collisionL + collisionW >= left + width
1022+
// Near the lower right corner area
1023+
const brAndBr =
1024+
collisionT + collisionH >= top + height && collisionL + collisionW >= left + width
1025+
if (tfAndTf && bfAndBf && trAndTr && brAndBr) {
1026+
dashboardStore.setTabCollisionActiveId(item.id)
1027+
} else if (tabCollisionActiveId.value === item.id) {
1028+
dashboardStore.setTabCollisionActiveId(null)
1029+
}
1030+
1031+
1032+
//Move into effective area for inspection
1033+
//Collision effective area inspection
1034+
const activeT = tt + tabMoveInYOffset
1035+
const activeL = tl + collisionGap * 10 - width
1036+
const activeW = tw + 2 * width - collisionGap * 20
1037+
const activeH = th + height - 2 * tabMoveInYOffset
1038+
1039+
// Near the upper left corner area
1040+
const activeTfAndTf = activeT <= top && activeL <= left
1041+
// Near the lower left corner area
1042+
const activeBfAndBf = activeT + activeH >= top + height && activeL <= left
1043+
// Near the upper right corner area
1044+
const activeTrAndTr = activeT <= top && activeL + activeW >= left + width
1045+
// Near the lower right corner area
1046+
const activeBrAndBr = activeT + activeH >= top + height && activeL + activeW >= left + width
1047+
if (activeTfAndTf && activeBfAndBf && activeTrAndTr && activeBrAndBr) {
1048+
dashboardStore.setTabMoveInActiveId(item.id)
1049+
} else if (tabMoveInActiveId.value === item.id) {
1050+
dashboardStore.setTabMoveInActiveId(null)
1051+
}
1052+
}
1053+
})
1054+
}
1055+
1056+
}
1057+
9531058
9541059
defineExpose({
9551060
getRenderState,

0 commit comments

Comments
 (0)