mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 17:26:55 +08:00
feat: dashboard tab move out
This commit is contained in:
@@ -8,6 +8,7 @@ import {findComponent} from "@/views/dashboard/components/component-list.ts";
|
||||
|
||||
const dashboardStore = dashboardStoreWithOut()
|
||||
const canvasLocked = ref(false) // Is the canvas movement locked, Default false
|
||||
const emits = defineEmits(["parentAddItemBox"]);
|
||||
// @ts-ignore
|
||||
let currentInstance
|
||||
// Props
|
||||
@@ -400,11 +401,26 @@ function removeItem(index: number) {
|
||||
canvasComponentData.value.splice(index, 1)
|
||||
}
|
||||
|
||||
function getNextDragId() {
|
||||
if (!canvasComponentData.value || canvasComponentData.value.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
//@ts-ignore
|
||||
const validIds = canvasComponentData.value.map(item => item._dragId).filter(id => id != null && id !== ''); // 过滤 null、undefined 和空字符串
|
||||
|
||||
if (validIds.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
//@ts-ignore
|
||||
const maxDragId = Math.max(...validIds);
|
||||
return maxDragId + 1;
|
||||
}
|
||||
|
||||
function addItem(item: CanvasItem, index: any) {
|
||||
if (index < 0) {
|
||||
index = canvasComponentData.value.length
|
||||
}
|
||||
item._dragId = index
|
||||
item._dragId = getNextDragId()
|
||||
checkItemPosition(item, {x: item.x, y: item.y})
|
||||
emptyTargetCell(item)
|
||||
addItemToPositionBox(item)
|
||||
@@ -899,15 +915,25 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
|
||||
if (canvasLocked.value) {
|
||||
const moveItem = infoBox.value.moveItem
|
||||
// Get the SQTab currently being moved in
|
||||
const curActiveSQTab = canvasComponentData?.value.find(item => item.component === 'SQTab' && item.moveInActive === true);
|
||||
if (curActiveSQTab) {
|
||||
// @ts-ignore
|
||||
const refTabInstance = currentInstance.refs['shape_component_' + curActiveSQTab.id][0]
|
||||
refTabInstance.addTabItem(moveItem)
|
||||
removeItemById(moveItem.id)
|
||||
curActiveSQTab.collisionActive = false
|
||||
curActiveSQTab.moveInActive = false
|
||||
const curActiveMoveInSQTab = canvasComponentData?.value.find(item => item.component === 'SQTab' && item.collisionActive === true);
|
||||
if (curActiveMoveInSQTab) {
|
||||
if (curActiveMoveInSQTab.moveInActive) {
|
||||
// @ts-ignore
|
||||
const refTabInstance = currentInstance.refs['shape_component_' + curActiveMoveInSQTab.id][0]
|
||||
refTabInstance.addTabItem(moveItem)
|
||||
removeItemById(moveItem.id)
|
||||
}
|
||||
curActiveMoveInSQTab.collisionActive = false
|
||||
curActiveMoveInSQTab.moveInActive = false
|
||||
}
|
||||
|
||||
// move out
|
||||
if (props.parentConfigItem && props.parentConfigItem.moveOutActive) {
|
||||
emits('parentAddItemBox', _.cloneDeep(moveItem))
|
||||
removeItemById(moveItem.id)
|
||||
props.parentConfigItem.moveOutActive = false
|
||||
}
|
||||
|
||||
}
|
||||
canvasLocked.value = false
|
||||
}
|
||||
@@ -1045,6 +1071,7 @@ function tabMoveOutCheckSQ() {
|
||||
const top = cloneItem.offsetTop
|
||||
const {tw} = getItemStylePosition(props.parentConfigItem)
|
||||
props.parentConfigItem.moveOutActive = left < -tabMoveOutXOffset || top < -tabMoveOutYOffset || (left + width - tw) > tabMoveOutXOffset;
|
||||
canvasLocked.value = props.parentConfigItem.moveOutActive
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1135,7 +1162,8 @@ defineExpose({
|
||||
<component :ref="'shape_component_'+item.id"
|
||||
class="sql-component slot-component dragHandle"
|
||||
:is="findComponent(item.component)"
|
||||
:config-item="item">
|
||||
:config-item="item"
|
||||
@parentAddItemBox=" (subItem:any) => addItemBox(subItem)">
|
||||
</component>
|
||||
</CanvasShape>
|
||||
</template>
|
||||
|
||||
@@ -42,6 +42,7 @@ const { draggable } = toRefs(props)
|
||||
<template>
|
||||
<div :class="{
|
||||
item: true,
|
||||
itemCursorDefault: configItem.component === 'SQTab',
|
||||
moveAnimation: moveAnimate,
|
||||
movingItem: configItem.isPlayer,
|
||||
canNotDrag: !draggable
|
||||
|
||||
@@ -32,7 +32,7 @@ const shadowStyle = (size: number, index: number) => {
|
||||
height: `${size}px`
|
||||
}
|
||||
} else if (index === 3) {
|
||||
return {
|
||||
return {
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: `${size}px`,
|
||||
@@ -44,10 +44,15 @@ const shadowStyle = (size: number, index: number) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dragHandle" v-for="(size,index) in sizeList" :style="shadowStyle(size,index)"></div>
|
||||
<div class="dragHandle dragArea" v-for="(size,index) in sizeList" :style="shadowStyle(size,index)"></div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
.dragArea {
|
||||
opacity: 0.05;
|
||||
}
|
||||
|
||||
.dragHandle {
|
||||
background: #c1e2e8;
|
||||
position: absolute;
|
||||
|
||||
@@ -12,6 +12,8 @@ const showTabTitleFlag = ref(true)
|
||||
let currentInstance
|
||||
import _ from 'lodash'
|
||||
|
||||
const emits = defineEmits(["parentAddItemBox"]);
|
||||
|
||||
const tabBaseMatrixCount = {
|
||||
x: 36,
|
||||
y: 12
|
||||
@@ -130,7 +132,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div :class="{'tab-moveout':configItem.moveOutActive}">
|
||||
<drag-handle></drag-handle>
|
||||
<custom-tab
|
||||
v-model="editableTabsValue"
|
||||
@@ -142,7 +144,7 @@ defineExpose({
|
||||
:border-active-color="state.headBorderActiveColor"
|
||||
:hide-title="!showTabTitleFlag"
|
||||
>
|
||||
-------{{ configItem.collisionActive }} -- -- {{ configItem.moveInActive }}-- -- {{ configItem.moveOutActive }}
|
||||
<!-- {{ configItem.collisionActive }} & {{ configItem.moveInActive }}${{ configItem.moveOutActive }}-->
|
||||
<template :key="tabItem.name" v-for="tabItem in configItem.propValue">
|
||||
<el-tab-pane
|
||||
class="el-tab-pane-custom"
|
||||
@@ -193,12 +195,14 @@ defineExpose({
|
||||
:class="{ 'switch-hidden': editableTabsValue !== tabItem.name }"
|
||||
>
|
||||
<DashboardEditor
|
||||
class="tab-dashboard-editor-main"
|
||||
:ref="'tabEditorRef_'+index"
|
||||
:canvas-component-data="tabItem.componentData"
|
||||
:move-in-active="configItem.moveInActive"
|
||||
:base-matrix-count="tabBaseMatrixCount"
|
||||
:canvas-id="tabItem.name"
|
||||
:parent-config-item="configItem"
|
||||
@parentAddItemBox=" item => emits('parentAddItemBox',item)"
|
||||
>
|
||||
</DashboardEditor>
|
||||
</div>
|
||||
@@ -218,4 +222,18 @@ defineExpose({
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tab-dashboard-editor-main{
|
||||
height: 100%!important;
|
||||
}
|
||||
|
||||
.tab-moveout {
|
||||
::v-deep(.ed-tabs__content) {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
::v-deep(.dashboard-editor-main) {
|
||||
overflow: visible !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,105 +1,104 @@
|
||||
.dragAndResize
|
||||
{
|
||||
position: relative;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
*
|
||||
{
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.item
|
||||
{
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
cursor: move;
|
||||
border: 1px solid #59c7f9;
|
||||
background-color: #fff;
|
||||
.resizeHandle
|
||||
{
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
border: 1px solid #59c7f9;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
z-index: 5;
|
||||
}
|
||||
.sql-component {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.moveAnimation
|
||||
{
|
||||
transition: top 80ms ease;
|
||||
}
|
||||
.canNotDrag
|
||||
{
|
||||
cursor: default!important;
|
||||
.dragAndResize {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.itemCursorDefault {
|
||||
cursor: default!important;
|
||||
}
|
||||
.item {
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 1px solid #59c7f9;
|
||||
background-color: #fff;
|
||||
cursor: move;
|
||||
.resizeHandle {
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
border: 1px solid #59c7f9;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.cloneNode
|
||||
{
|
||||
z-index: 100;
|
||||
.sql-component {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
transition: none;
|
||||
.moveAnimation {
|
||||
transition: top 80ms ease;
|
||||
}
|
||||
|
||||
opacity: .5;
|
||||
.canNotDrag {
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.cloneNode {
|
||||
z-index: 100;
|
||||
|
||||
transition: none;
|
||||
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.movingItem {
|
||||
position: absolute;
|
||||
|
||||
border: none;
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: '';
|
||||
background-color: #b8d3f9;
|
||||
}
|
||||
|
||||
.movingItem
|
||||
{
|
||||
position: absolute;
|
||||
|
||||
border: none;
|
||||
&:before
|
||||
{
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: '';
|
||||
background-color: #b8d3f9;
|
||||
}
|
||||
.resizeHandle
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
.slot-component {
|
||||
display: none;
|
||||
}
|
||||
.resizeHandle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.positionBox
|
||||
{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 100px;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
|
||||
border: 1px solid;
|
||||
.slot-component {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.coords
|
||||
{
|
||||
position: fixed;
|
||||
right: 100px;
|
||||
bottom: 200px;
|
||||
.positionBox {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 100px;
|
||||
|
||||
overflow: auto;
|
||||
overflow: auto;
|
||||
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
|
||||
border: 1px solid;
|
||||
}
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.coords {
|
||||
position: fixed;
|
||||
right: 100px;
|
||||
bottom: 200px;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@ onMounted(() => {
|
||||
}
|
||||
})
|
||||
})
|
||||
const emits = defineEmits(["parentAddItemBox"]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -99,6 +100,7 @@ onMounted(() => {
|
||||
:canvas-component-data="canvasComponentData"
|
||||
:parent-config-item="parentConfigItem"
|
||||
:canvas-id="canvasId"
|
||||
@parentAddItemBox=" item => emits('parentAddItemBox',item)"
|
||||
></CanvasCore>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import {ref} from 'vue'
|
||||
import Toolbar from "@/views/dashboard/editor/Toolbar.vue";
|
||||
import DashboardEditor from "@/views/dashboard/editor/DashboardEditor.vue";
|
||||
import {findNewComponentFromList} from "@/views/dashboard/components/component-list.ts";
|
||||
import {guid} from "@/utils/canvas.ts";
|
||||
import {type CanvasItem, guid} from "@/utils/canvas.ts";
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
|
||||
|
||||
@@ -56,7 +56,10 @@ const componentData = ref([
|
||||
<template>
|
||||
<div class="editor-main">
|
||||
<Toolbar @add-component="addComponent"></Toolbar>
|
||||
<DashboardEditor ref="dashboardEditorRef" :canvas-component-data="componentData"></DashboardEditor>
|
||||
<DashboardEditor
|
||||
ref="dashboardEditorRef"
|
||||
:canvas-component-data="componentData">
|
||||
</DashboardEditor>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user