mirror of
https://github.com/dataease/dataease.git
synced 2026-05-15 21:42:32 +08:00
feat(仪表板、数据大屏): Tab标题支持设置背景图片边框等
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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: '已隱藏的組件',
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user