Merge pull request #10078 from dataease/pr@dev-v2@fix_batch2

fix(数据大屏): 修复多选command键可能不准确造成组件选择不准确问题
This commit is contained in:
王嘉豪 2024-06-04 16:49:50 +08:00 committed by GitHub
commit 5cf54bf2a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 1 additions and 474 deletions

View File

@ -1,473 +0,0 @@
<script lang="ts" setup>
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { layerStoreWithOut } from '@/store/modules/data-visualization/layer'
import { storeToRefs } from 'pinia'
import { ElIcon, ElRow } from 'element-plus-secondary'
import Icon from '../icon-custom/src/Icon.vue'
import { nextTick, ref } from 'vue'
import draggable from 'vuedraggable'
import { lockStoreWithOut } from '@/store/modules/data-visualization/lock'
import ContextMenuAsideDetails from '@/components/data-visualization/canvas/ContextMenuAsideDetails.vue'
import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue'
import { composeStoreWithOut } from '@/store/modules/data-visualization/compose'
const dropdownMore = ref(null)
const lockStore = lockStoreWithOut()
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const layerStore = layerStoreWithOut()
const composeStore = composeStoreWithOut()
const { areaData, isCtrlOrCmdDown, isShiftDown, laterIndex } = storeToRefs(composeStore)
const { componentData, curComponent, canvasViewInfo } = storeToRefs(dvMainStore)
const getComponent = index => {
return componentData.value[componentData.value.length - 1 - index]
}
const transformIndex = index => {
return componentData.value.length - 1 - index
}
const areaDataPush = component => {
if (component && !component.isLock && component.isShow) {
areaData.value.components.push(component)
}
}
// shift
// 1.laterIndexlaterIndex=0;
// 2.index curClickIndex;
// 3.laterIndex curClickIndex;
// 4.[laterIndex,curClickIndex] [curClickIndex,laterIndex]areaData.value.components();
const shiftDataPush = curClickIndex => {
const areaDataIdArray = areaData.value.components.map(com => com.id)
let indexBegin, indexEnd
const laterIndexTrans = laterIndex.value === null ? componentData.value.length : laterIndex.value
if (laterIndexTrans < curClickIndex) {
indexBegin = laterIndexTrans
indexEnd = curClickIndex
} else {
indexBegin = curClickIndex
indexEnd = laterIndexTrans
}
const shiftAreaComponents = componentData.value
.slice(indexBegin, indexEnd + 1)
.filter(
component => !areaDataIdArray.includes(component.id) && !component.isLock && component.isShow
)
areaData.value.components.push(...shiftAreaComponents)
dvMainStore.setCurComponent({ component: null, index: null })
}
const onClick = (e, index) => {
// laterIndex=0
if (!curComponent.value) {
composeStore.setLaterIndex(null)
}
// ctrl or command (ComposeShow)
if (isCtrlOrCmdDown.value && !areaData.value.components.includes(componentData.value[index])) {
areaDataPush(componentData.value[index])
if (curComponent.value && curComponent.value.id !== componentData.value[index].id) {
areaDataPush(curComponent.value)
}
dvMainStore.setCurComponent({ component: null, index: null })
e.stopPropagation()
composeStore.setLaterIndex(index)
return
}
//shift
if (isShiftDown.value) {
shiftDataPush(index)
return
}
//
areaData.value.components.splice(0, areaData.value.components.length)
setCurComponent(index)
composeStore.setLaterIndex(index)
}
const setCurComponent = index => {
dvMainStore.setCurComponent({ component: componentData.value[index], index })
}
let nameEdit = ref(false)
let editComponentId = ref('')
let inputName = ref('')
let nameInput = ref(null)
let curEditComponent = null
const editComponentName = item => {
curEditComponent = curComponent.value
editComponentId.value = `#component-label-${item.id}`
nameEdit.value = true
inputName.value = item.name
nextTick(() => {
nameInput.value.focus()
})
}
const closeEditComponentName = () => {
nameEdit.value = false
if (!inputName.value || !inputName.value.trim()) {
return
}
if (inputName.value.trim() === curEditComponent.name) {
return
}
curEditComponent.name = inputName.value
inputName.value = ''
curEditComponent = null
}
const lock = () => {
setTimeout(() => {
lockStore.lock()
snapshotStore.recordSnapshotCache('realTime-lock')
})
}
const unlock = () => {
setTimeout(() => {
lockStore.unlock()
snapshotStore.recordSnapshotCache('realTime-unlock')
})
}
const hideComponent = () => {
setTimeout(() => {
layerStore.hideComponent()
snapshotStore.recordSnapshotCache('realTime-hideComponent')
})
}
const showComponent = () => {
setTimeout(() => {
layerStore.showComponent()
snapshotStore.recordSnapshotCache()
})
}
const dragOnEnd = ({ oldIndex, newIndex }) => {
const source = componentData.value[newIndex]
const comLength = componentData.value.length
//
componentData.value.splice(newIndex, 1)
componentData.value.splice(oldIndex, 0, source)
const target = componentData.value[comLength - 1 - oldIndex]
//
componentData.value.splice(comLength - 1 - oldIndex, 1)
componentData.value.splice(comLength - 1 - newIndex, 0, target)
dvMainStore.setCurComponent({ component: target, index: transformIndex(comLength - oldIndex) })
}
const getIconName = item => {
if (item.component === 'UserView') {
const viewInfo = canvasViewInfo.value[item.id]
return `${viewInfo.type}-origin`
} else {
return item.icon
}
}
const menuAsideClose = (param, index) => {
const iconDom = document.getElementById('close-button')
if (iconDom) {
iconDom.click()
}
if (param.opt === 'rename') {
setTimeout(() => {
editComponentName(getComponent(index))
}, 200)
}
}
const handleContextMenu = e => {
e.preventDefault()
//
const x = e.clientX
const y = e.clientY
const customContextMenu = document.createElement('div')
customContextMenu.style.position = 'fixed'
customContextMenu.style.left = x + 'px'
customContextMenu.style.top = y + 'px'
//
document.body.appendChild(customContextMenu)
//
customContextMenu.addEventListener('click', () => {
//
//
document.body.removeChild(customContextMenu)
})
}
</script>
<template>
<!--为了保持图层视觉上的一致性 这里进行数组的倒序排列 相应的展示和移动按照倒序处理-->
<div class="real-time-component-list">
<button hidden="true" id="close-button"></button>
<el-row class="list-wrap">
<div class="list-container" @contextmenu="handleContextMenu">
<draggable
@end="dragOnEnd"
:list="componentData"
animation="100"
class="drag-list"
item-key="id"
>
<template #item="{ index }">
<div
:title="getComponent(index)?.name"
class="component-item"
:class="{
'container-item-not-show': !getComponent(index)?.isShow,
activated:
(curComponent && curComponent?.id === getComponent(index)?.id) ||
areaData.components.includes(getComponent(index))
}"
@click="onClick($event, transformIndex(index))"
>
<el-icon class="component-icon">
<Icon :name="getIconName(getComponent(index))"></Icon>
</el-icon>
<span
:id="`component-label-${getComponent(index)?.id}`"
class="component-label"
@dblclick="editComponentName(getComponent(index))"
>
{{ getComponent(index)?.name }}
</span>
<div
v-show="!nameEdit || (nameEdit && curComponent?.id !== getComponent(index)?.id)"
class="icon-container"
:class="{
'icon-container-lock': getComponent(index)?.isLock && getComponent(index)?.isShow,
'icon-container-show': !getComponent(index)?.isShow
}"
>
<el-icon
class="component-base component-icon-display"
v-show="!getComponent(index).isShow"
@click="showComponent"
>
<Icon name="dv-eye-close" class="opt-icon"></Icon>
</el-icon>
<el-icon
class="component-base"
v-show="getComponent(index)?.isShow"
@click="hideComponent"
>
<Icon name="dv-show" class="opt-icon"></Icon>
</el-icon>
<el-icon v-show="!getComponent(index)?.isLock" class="component-base" @click="lock">
<Icon class="opt-icon" name="dv-unlock"></Icon>
</el-icon>
<el-icon
class="component-base component-icon-display"
v-show="getComponent(index)?.isLock"
@click="unlock"
>
<Icon name="dv-lock" class="opt-icon"></Icon>
</el-icon>
<el-dropdown
ref="dropdownMore"
trigger="click"
placement="bottom-start"
effect="dark"
:hide-timeout="0"
>
<span :class="'dropdownMore-' + index" @click="onClick(transformIndex(index))">
<el-icon class="component-base">
<Icon name="dv-more" class="opt-icon"></Icon>
</el-icon>
</span>
<template #dropdown>
<context-menu-aside-details
:element="getComponent(index)"
@close="menuAsideClose($event, index)"
></context-menu-aside-details>
</template>
</el-dropdown>
</div>
<el-dropdown
class="compose-dropdown"
trigger="contextmenu"
placement="bottom-start"
effect="dark"
:hide-timeout="0"
>
<compose-show
:show-border="false"
:element-index="transformIndex(index)"
:element="getComponent(index)"
></compose-show>
<template #dropdown>
<context-menu-aside-details
:element="getComponent(index)"
@close="menuAsideClose($event, index)"
></context-menu-aside-details>
</template>
</el-dropdown>
</div>
</template>
</draggable>
<el-row style="width: 100%; height: 150px"></el-row>
</div>
</el-row>
<Teleport v-if="editComponentId && nameEdit" :to="editComponentId">
<input
@keydown.stop
@keyup.stop
ref="nameInput"
v-model="inputName"
@blur="closeEditComponentName"
/>
</Teleport>
</div>
</template>
<style lang="less" scoped>
.real-time-component-list {
white-space: nowrap;
.list-wrap {
max-height: calc(100% - @component-toolbar-height);
overflow-y: auto;
width: 100%;
.list-container {
width: 100%;
.component-item {
position: relative;
height: 30px;
width: 100%;
cursor: grab;
color: @dv-canvas-main-font-color;
display: flex;
align-items: center;
justify-content: flex-start;
font-size: 12px;
padding: 0 2px 0 22px;
user-select: none;
.component-icon {
color: #a6a6a6;
font-size: 14px;
}
.component-label {
color: #ebebeb;
}
> span.component-label {
font-size: 12px;
margin-left: 10px;
position: relative;
min-width: 65px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
input {
position: absolute;
left: 0;
width: 100%;
background-color: white;
outline: none;
border: none;
border-radius: 2px;
padding: 0 4px;
height: 100%;
}
}
&:active {
cursor: grabbing;
}
&:hover {
background-color: rgba(235, 235, 235, 0.1);
.icon-container {
.component-base {
opacity: 1;
}
width: 70px !important;
}
}
.icon-container {
.component-base {
opacity: 0;
}
width: 0px;
display: flex;
justify-content: flex-end;
align-items: center;
flex-grow: 1;
cursor: none;
i {
font-size: 16px;
cursor: pointer;
}
}
}
.activated {
background-color: var(--ed-color-primary-1a, rgba(51, 112, 255, 0.1)) !important;
:deep(.component-icon) {
color: var(--ed-color-primary);
}
:deep(.component-label) {
color: var(--ed-color-primary);
}
}
}
}
}
.real-time-component-list :deep(.ed-popper) {
background: #303133 !important;
}
.component-base {
cursor: pointer;
height: 22px !important;
width: 22px !important;
border-radius: 4px;
padding: 0 4px;
.opt-icon {
font-size: 14px;
}
&:hover {
background: rgba(235, 235, 235, 0.1);
}
&:active {
background: rgba(235, 235, 235, 0.1);
}
}
.component-icon-display {
opacity: 1 !important;
}
.icon-container-show {
width: 70px !important;
}
.icon-container-lock {
width: 45px !important;
}
.container-item-not-show {
color: #5f5f5f !important;
:deep(.component-icon) {
color: #5f5f5f !important;
}
:deep(.component-label) {
color: #5f5f5f !important;
}
}
</style>
<style lang="less">
.compose-dropdown {
position: initial !important;
}
</style>

View File

@ -101,7 +101,7 @@ let isShiftDown = false
// 全局监听按键操作并执行相应命令
export function listenGlobalKeyDown() {
window.onkeydown = e => {
if (!isInEditor.value || editMode.value === 'preview' || checkDialog()) return
if (editMode.value === 'preview' || checkDialog()) return
const { keyCode } = e
if (positionMoveKey[keyCode] && curComponent.value) {
positionMoveKey[keyCode](keyCode)