feat(仪表板、数据大屏): Tab标题支持设置背景图片边框等

This commit is contained in:
wangjiahao
2025-02-12 17:31:43 +08:00
committed by 王嘉豪
parent 85dcf480c9
commit cd1492360d
5 changed files with 144 additions and 63 deletions

View File

@@ -30,34 +30,54 @@
>
<template #label>
<div class="custom-tab-title" @mousedown.stop>
<span class="title-inner" :style="titleStyle(tabItem.name)">{{ tabItem.title }}</span>
<el-dropdown
v-if="isEditMode"
:effect="curThemes"
style="line-height: 4 !important"
trigger="click"
@command="handleCommand"
>
<span class="el-dropdown-link">
<el-icon v-if="isEdit"><ArrowDown /></el-icon>
<span class="title-inner" :style="titleStyle(tabItem.name)"
>{{ tabItem.title }}
<Board
v-show="svgInnerActiveEnable(tabItem.name)"
:style="{
color: element.titleBackground.active.innerImageColor,
pointerEvents: 'none'
}"
:name="titleBackgroundActiveSvgInner"
></Board>
<Board
v-show="svgInnerInActiveEnable(tabItem.name)"
:style="{
color: element.titleBackground.inActive.innerImageColor,
pointerEvents: 'none'
}"
:name="titleBackgroundInActiveSvgInner"
></Board>
<span v-if="isEditMode">
<el-dropdown
popper-class="custom-de-tab-dropdown"
:effect="curThemes"
trigger="click"
@command="handleCommand"
>
<span class="el-dropdown-link">
<el-icon v-if="isEdit"><ArrowDown /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu :style="{ 'font-family': fontFamily }">
<el-dropdown-item :command="beforeHandleCommand('editTitle', tabItem)">
{{ t('visualization.edit_title') }}
</el-dropdown-item>
<el-dropdown-item :command="beforeHandleCommand('copyCur', tabItem)">
{{ t('visualization.copy') }}
</el-dropdown-item>
<el-dropdown-item
v-if="element.propValue.length > 1"
:command="beforeHandleCommand('deleteCur', tabItem)"
>
{{ t('visualization.delete') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</span>
<template #dropdown>
<el-dropdown-menu :style="{ 'font-family': fontFamily }">
<el-dropdown-item :command="beforeHandleCommand('editTitle', tabItem)">
{{ t('visualization.edit_title') }}
</el-dropdown-item>
<el-dropdown-item :command="beforeHandleCommand('copyCur', tabItem)">
{{ t('visualization.copy') }}
</el-dropdown-item>
<el-dropdown-item
v-if="element.propValue.length > 1"
:command="beforeHandleCommand('deleteCur', tabItem)"
>
{{ t('visualization.delete') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</span>
</div>
</template>
</el-tab-pane>
@@ -150,6 +170,7 @@ import { deepCopyTabItemHelper } from '@/store/modules/data-visualization/copy'
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
import { useI18n } from '@/hooks/web/useI18n'
import { imgUrlTrans } from '@/utils/imgUtils'
import Board from '@/components/de-board/Board.vue'
const dvMainStore = dvMainStoreWithOut()
const snapshotStore = snapshotStoreWithOut()
const { tabMoveInActiveId, bashMatrixInfo, editMode, mobileInPc } = storeToRefs(dvMainStore)
@@ -216,6 +237,37 @@ const {
searchCount
} = toRefs(props)
const titleBackgroundActiveSvgInner = computed(() => {
return element.value.titleBackground.active.innerImage.replace('board/', '').replace('.svg', '')
})
const titleBackgroundInActiveSvgInner = computed(() => {
return element.value.titleBackground.inActive.innerImage.replace('board/', '').replace('.svg', '')
})
const svgInnerInActiveEnable = itemName => {
const { backgroundImageEnable, backgroundType, innerImage } =
element.value.titleBackground.inActive
return (
editableTabsValue.value !== itemName &&
element.value.titleBackground?.enable &&
backgroundImageEnable &&
backgroundType === 'innerImage' &&
typeof innerImage === 'string'
)
}
const svgInnerActiveEnable = itemName => {
const { backgroundImageEnable, backgroundType, innerImage } = element.value.titleBackground.active
return (
editableTabsValue.value === itemName &&
element.value.titleBackground?.enable &&
backgroundImageEnable &&
backgroundType === 'innerImage' &&
typeof innerImage === 'string'
)
}
const handleMouseEnter = () => {
state.hoverFlag = true
}
@@ -475,7 +527,8 @@ const titleStyle = itemName => {
textDecoration: element.value.style.textDecoration,
fontStyle: element.value.style.fontStyle,
fontWeight: element.value.style.fontWeight,
fontSize: (element.value.style.activeFontSize || 18) * scale.value + 'px'
fontSize: (element.value.style.activeFontSize || 18) * scale.value + 'px',
lineHeight: (element.value.style.activeFontSize || 18) * scale.value + 'px'
}
if (element.value.titleBackground?.enable) {
style = {
@@ -488,7 +541,8 @@ const titleStyle = itemName => {
textDecoration: element.value.style.textDecoration,
fontStyle: element.value.style.fontStyle,
fontWeight: element.value.style.fontWeight,
fontSize: (element.value.style.fontSize || 16) * scale.value + 'px'
fontSize: (element.value.style.fontSize || 16) * scale.value + 'px',
lineHeight: (element.value.style.fontSize || 16) * scale.value + 'px'
}
if (element.value.titleBackground?.enable) {
style = {
@@ -635,6 +689,7 @@ onBeforeMount(() => {
}
:deep(.ed-tabs__item) {
font-family: inherit;
padding-right: 0 !important;
}
}
@@ -688,7 +743,11 @@ onBeforeMount(() => {
}
.custom-tab-title {
.title-inner {
position: relative;
background-size: 100% 100% !important;
}
:deep(.ed-dropdown) {
vertical-align: middle !important;
}
}
</style>

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import BackgroundOverallCommon from '@/components/visualization/component-background/BackgroundOverallCommon.vue'
import { toRefs } from 'vue'
import { ref, toRefs } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
const emits = defineEmits(['onTitleBackgroundChange'])
const { t } = useI18n()
const activeName = ref('activeBackground')
const props = withDefaults(
defineProps<{
@@ -29,35 +30,39 @@ const onTitleBackgroundChange = (params, paramsName) => {
<template>
<div class="tab-title-background">
<div class="background-label">{{ t('visualization.active_title_background') }}</div>
<background-overall-common
:themes="themes"
:common-background-pop="element.titleBackground.active"
component-position="component"
@onBackgroundChange="onTitleBackgroundChange($event, 'active')"
/>
<div class="background-label">
<span>{{ t('visualization.inactive_title_background') }}</span>
<span style="margin: -2px 0 0 24px">
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
v-model="element.titleBackground.multiply"
@change="onTitleBackgroundChange(null, null)"
>
{{ t('visualization.multiply_active_title_background') }}
</el-checkbox>
</el-form-item>
</span>
</div>
<background-overall-common
v-show="!element.titleBackground.multiply"
:themes="themes"
:common-background-pop="element.titleBackground.inActive"
component-position="component"
@onBackgroundChange="onTitleBackgroundChange($event, 'inActive')"
/>
<el-tabs class="background-tabs" v-model="activeName" stretch>
<el-tab-pane :label="t('visualization.active_title_background')" name="activeBackground">
<background-overall-common
:themes="themes"
:common-background-pop="element.titleBackground.active"
component-position="component"
@onBackgroundChange="onTitleBackgroundChange($event, 'active')"
/>
</el-tab-pane>
<el-tab-pane :label="t('visualization.inactive_title_background')" name="inActiveBackground">
<div class="background-label">
<span>
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
v-model="element.titleBackground.multiply"
@change="onTitleBackgroundChange(null, null)"
>
{{ t('visualization.reuse_active_title_background') }}
</el-checkbox>
</el-form-item>
</span>
</div>
<background-overall-common
v-show="!element.titleBackground.multiply"
:themes="themes"
:common-background-pop="element.titleBackground.inActive"
component-position="component"
@onBackgroundChange="onTitleBackgroundChange($event, 'inActive')"
/>
</el-tab-pane>
</el-tabs>
</div>
</template>
@@ -72,4 +77,19 @@ const onTitleBackgroundChange = (params, paramsName) => {
margin-bottom: 8px;
display: flex;
}
.background-tabs {
--ed-tabs-header-height: 24px;
:deep(.ed-tabs__active-bar) {
height: 1px;
}
:deep(.ed-tabs__item) {
font-size: 12px;
}
:deep(.ed-tabs__content) {
padding: 12px 0;
}
}
</style>

View File

@@ -2820,7 +2820,7 @@ Scatter chart (bubble) chart: {a} (series name), {b} (data name), {c} (value arr
sync_pc_design: 'Synchronize PC Design',
title_background: 'Title Background',
active_title_background: 'Active Title Background',
multiply_active_title_background: 'Reuse Active Title Background',
reuse_active_title_background: 'Reuse Active Title Background',
inactive_title_background: 'Inactive Title Background',
no_hidden_components: 'No Hidden Components',
hidden_components: 'Hidden Components',

View File

@@ -2748,7 +2748,7 @@ export default {
sync_pc_design: '同步PC設計',
title_background: '標題背景',
active_title_background: '激活標題背景',
multiply_active_title_background: '復用激活標題背景',
reuse_active_title_background: '復用激活標題背景',
inactive_title_background: '非激活標題背景',
no_hidden_components: '當前無隱藏組件',
hidden_components: '已隱藏的組件',

View File

@@ -5,6 +5,7 @@ import componentList, {
BASE_EVENTS,
COMMON_COMPONENT_BACKGROUND_DARK,
COMMON_COMPONENT_BACKGROUND_LIGHT,
COMMON_TAB_TITLE_BACKGROUND,
MULTI_DIMENSIONAL
} from '@/custom-component/component-list'
import eventBus from '@/utils/eventBus'
@@ -17,8 +18,7 @@ import {
findById,
findCopyResource,
saveCanvas,
updateCanvas,
updateCheckVersion
updateCanvas
} from '@/api/visualization/dataVisualization'
import { storeToRefs } from 'pinia'
import { getPanelAllLinkageInfo } from '@/api/visualization/linkage'
@@ -211,6 +211,8 @@ export function historyItemAdaptor(
componentItem['category'] = componentItem['category'] || 'base'
if (componentItem.component === 'DeTabs') {
componentItem['titleBackground'] =
componentItem['titleBackground'] || deepCopy(COMMON_TAB_TITLE_BACKGROUND)
componentItem.style.fontStyle = componentItem.style.fontStyle || 'normal'
componentItem.style.fontWeight = componentItem.style.fontWeight || 'normal'
componentItem.style.textDecoration = componentItem.style.textDecoration || 'none'