Merge pull request #6884 from dataease/pr@dev-v2@refactor_market-UI

refactor: UI调整
This commit is contained in:
王嘉豪 2023-11-28 10:33:43 +08:00 committed by GitHub
commit 3c1ba64d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 221 additions and 157 deletions

View File

@ -18,7 +18,7 @@ CREATE TABLE `visualization_template` (
BEGIN; BEGIN;
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 0, 1, 1); VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 1, 1, 0);
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (20, 15, 2, 'template-setting', 'system/template-setting', 4, 'icon_template', '/template-setting', 0, 1, 1); VALUES (20, 15, 2, 'template-setting', 'system/template-setting', 4, 'icon_template', '/template-setting', 0, 1, 1);
COMMIT; COMMIT;

View File

@ -20,7 +20,7 @@ CREATE TABLE `visualization_template`
BEGIN; BEGIN;
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 0, 1, 1); VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 1, 1, 0);
INSERT INTO `core_menu` INSERT INTO `core_menu`
VALUES (20, 15, 2, 'template-setting', 'system/template-setting', 4, 'icon_template', '/template-setting', 0, 1, 1); VALUES (20, 15, 2, 'template-setting', 'system/template-setting', 4, 'icon_template', '/template-setting', 0, 1, 1);
COMMIT; COMMIT;

View File

@ -1,10 +1,5 @@
<template> <template>
<p class="router-title">模版管理</p> <template-manage></template-manage>
<div class="sys-setting-p">
<div class="container-sys-param">
<template-manage></template-manage>
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -19,30 +14,3 @@ const handleClick = (tab, event: Event) => {
console.log(tab, event) console.log(tab, event)
} }
</script> </script>
<style lang="less">
.router-title {
color: #1f2329;
font-feature-settings: 'clig' off, 'liga' off;
font-family: PingFang SC;
font-size: 20px;
font-style: normal;
font-weight: 500;
line-height: 28px;
}
.sys-setting-p {
width: 100%;
background: var(--ContentBG, #ffffff);
height: calc(100vh - 176px);
box-sizing: border-box;
margin-top: 12px;
}
.setting-auto-h {
height: auto !important;
}
.container-sys-param {
height: 100%;
overflow-y: auto;
}
</style>
<style lang="less" scoped></style>

View File

@ -9,12 +9,11 @@
</el-tooltip> </el-tooltip>
<el-row v-show="state.asideActive" style="padding: 24px 12px 0"> <el-row v-show="state.asideActive" style="padding: 24px 12px 0">
<el-row style="align-items: center"> <el-row style="align-items: center">
<el-breadcrumb separator-icon="ArrowRight"> <span class="custom-breadcrumb-item" @click="closePreview()">{{
<el-breadcrumb-item class="custom-breadcrumb-item" @click="closePreview()">{{ t('visualization.template_preview')
t('visualization.template_preview') }}</span>
}}</el-breadcrumb-item> <el-icon><ArrowRight /></el-icon> <span class="custom-breadcrumb-item-to"></span>
<el-breadcrumb-item>预览</el-breadcrumb-item>
</el-breadcrumb>
<el-tooltip class="box-item" effect="dark" content="收起" placement="right"> <el-tooltip class="box-item" effect="dark" content="收起" placement="right">
<el-icon class="insert-retract" @click="asideActiveChange(false)"> <el-icon class="insert-retract" @click="asideActiveChange(false)">
<Icon name="market-retract"></Icon> <Icon name="market-retract"></Icon>
@ -571,9 +570,13 @@ onMounted(() => {
} }
.custom-breadcrumb-item { .custom-breadcrumb-item {
font-size: 14px;
cursor: pointer; cursor: pointer;
::v-deep(.ed-breadcrumb__inner) { color: rgba(100, 106, 115, 1);
color: rgba(100, 106, 115, 1); }
}
.custom-breadcrumb-item-to {
font-size: 14px;
color: rgba(31, 35, 41, 1);
} }
</style> </style>

View File

@ -55,11 +55,21 @@
id="template-show-area" id="template-show-area"
class="template-right" class="template-right"
> >
<el-col class="main-head">
<div class="custom-split-line"></div>
<span v-show="!state.searchText" class="custom-category">{{
state.marketActiveTab
}}</span>
<span v-show="state.searchText" class="custom-search">{{ state.marketActiveTab }}</span>
<span v-if="state.searchText" class="custom-search-result"
>的搜索结果是{{ searchResultCount }}</span
>
</el-col>
<el-col <el-col
v-for="templateItem in state.currentMarketTemplateShowList" v-for="templateItem in state.currentMarketTemplateShowList"
v-show="templateItem.showFlag" v-show="templateItem.showFlag"
:key="templateItem.id" :key="templateItem.id"
style="padding: 24px 12px 0; text-align: center; flex: 0" style="float: left; padding: 24px 12px 0; text-align: center; flex: 0"
:style="{ width: state.templateSpan }" :style="{ width: state.templateSpan }"
> >
<template-market-v2-item <template-market-v2-item
@ -90,7 +100,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getCategoriesObject, searchMarket } from '@/api/templateMarket' import { getCategoriesObject, searchMarket } from '@/api/templateMarket'
import elementResizeDetectorMaker from 'element-resize-detector' import elementResizeDetectorMaker from 'element-resize-detector'
import { nextTick, reactive, watch, onMounted, ref } from 'vue' import { nextTick, reactive, watch, onMounted, ref, computed } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { ElMessage } from 'element-plus-secondary' import { ElMessage } from 'element-plus-secondary'
import { decompression } from '@/api/visualization/dataVisualization' import { decompression } from '@/api/visualization/dataVisualization'
@ -180,6 +190,11 @@ watch(
initTemplateShow() initTemplateShow()
} }
) )
const searchResultCount = computed(
() => state.currentMarketTemplateShowList.filter(template => template.showFlag).length
)
const nodeClick = data => { const nodeClick = data => {
state.marketActiveTab = data.label state.marketActiveTab = data.label
initTemplateShow() initTemplateShow()
@ -317,10 +332,10 @@ onMounted(() => {
if (templateMainDom) { if (templateMainDom) {
erd.listenTo(templateMainDom, element => { erd.listenTo(templateMainDom, element => {
nextTick(() => { nextTick(() => {
const curSeparator = Math.trunc(templateMainDom.offsetWidth / state.templateMiniWidth) const offsetWidth = templateMainDom.offsetWidth - 26
state.templateSpan = const curSeparator = Math.trunc(offsetWidth / state.templateMiniWidth)
100 / Math.trunc(templateMainDom.offsetWidth / state.templateMiniWidth) + '%' state.templateSpan = 100 / Math.trunc(offsetWidth / state.templateMiniWidth) + '%'
state.templateCurWidth = Math.trunc(templateMainDom.offsetWidth / curSeparator) - 33 state.templateCurWidth = Math.trunc(offsetWidth / curSeparator) - 33
}) })
}) })
} }
@ -380,10 +395,11 @@ const previewInit = () => {
} }
.template-right { .template-right {
flex: 1; flex: 1;
display: inherit; display: inline;
height: 100%; height: 100%;
background: rgba(239, 240, 241, 1); background: rgba(239, 240, 241, 1);
overflow-y: auto; overflow-y: auto;
padding: 16px 12px;
} }
.template-empty { .template-empty {
@ -398,6 +414,41 @@ const previewInit = () => {
} }
} }
} }
.main-head {
width: 100%;
float: left;
height: 24px;
display: inline;
.custom-split-line {
margin: 4px 8px 0 12px;
width: 2px;
height: 16px;
background: rgba(51, 112, 255, 1);
float: left;
}
.custom-category {
float: left;
font-weight: 500;
font-size: 16px;
color: rgba(31, 35, 41, 1);
}
.custom-search {
float: left;
font-weight: 500;
font-size: 16px;
color: rgba(51, 112, 255, 1);
margin-right: 8px;
}
.custom-search-result {
float: left;
font-weight: 500;
font-size: 16px;
color: rgba(31, 35, 41, 1);
margin-right: 8px;
}
}
</style> </style>
<style lang="less"> <style lang="less">

View File

@ -26,7 +26,7 @@
<slot> <slot>
<el-dropdown-item command="rename"> <el-dropdown-item command="rename">
<el-icon><EditPen /></el-icon> <el-icon><EditPen /></el-icon>
{{ $t('chart.rename') }} 编辑
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item command="delete"> <el-dropdown-item command="delete">
<el-icon><Delete /></el-icon> <el-icon><Delete /></el-icon>
@ -90,6 +90,7 @@ const handleCommand = key => {
border-bottom: 1px solid var(--deCardStrokeColor, #dee0e3); border-bottom: 1px solid var(--deCardStrokeColor, #dee0e3);
height: 144px; height: 144px;
width: 100%; width: 100%;
padding: 4px 6px 0 4px;
overflow: hidden; overflow: hidden;
img { img {
@ -105,7 +106,7 @@ const handleCommand = key => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 8px 12px 9px 12px; padding: 4px 12px 9px 12px;
box-sizing: border-box; box-sizing: border-box;
.el-icon-more { .el-icon-more {

View File

@ -1,18 +1,5 @@
<template xmlns:el-col="http://www.w3.org/1999/html"> <template xmlns:el-col="http://www.w3.org/1999/html">
<div class="de-template-list"> <div class="de-template-list">
<el-input
v-model="state.templateFilterText"
:placeholder="'搜索关键字'"
size="small"
class="de-input-search"
clearable
>
<template #prefix>
<el-icon>
<Icon name="de-search" />
</el-icon>
</template>
</el-input>
<el-empty <el-empty
v-if="!templateListComputed.length && state.templateFilterText === ''" v-if="!templateListComputed.length && state.templateFilterText === ''"
:image="NoneImage" :image="NoneImage"

View File

@ -1,88 +1,105 @@
<template> <template>
<div style="width: 100%; height: 100%"> <div class="template-head">
<div class="de-template"> <p class="router-title">模版管理</p>
<div class="tabs-container flex-tabs"> <el-button style="float: right" type="primary" @click="templateImport(state.currentTemplateId)">
<div class="de-tabs-left"> {{ t('visualization.import') }}
<de-template-list </el-button>
ref="templateListRef" <el-input
:template-type="state.currentTemplateType" v-model="state.templateFilterText"
:template-list="state.templateList" :placeholder="'搜索关键字'"
@templateDelete="templateFolderDelete" class="template-search-class"
@templateEdit="templateEdit" clearable
@showCurrentTemplate="showCurrentTemplate" >
@templateImport="templateImport" <template #prefix>
@showTemplateEditDialog="showTemplateEditDialog" <el-icon>
/> <Icon name="de-search" />
</div> </el-icon>
<div class="de-tabs-right"> </template>
<div v-if="state.currentTemplateLabel" class="active-template"> </el-input>
{{ state.currentTemplateLabel }}&nbsp;&nbsp;({{ state.currentTemplateShowList.length }}) </div>
<el-button <div class="sys-setting-p">
type="primary" <div class="container-sys-param">
icon="Upload" <div style="width: 100%; height: 100%">
@click="templateImport(state.currentTemplateId)" <div class="de-template">
> <div class="tabs-container flex-tabs">
{{ t('visualization.import') }} <div class="de-tabs-left">
</el-button> <de-template-list
</div> ref="templateListRef"
<el-empty :template-type="state.currentTemplateType"
v-if="!state.currentTemplateShowList.length" :template-list="state.templateList"
:image="NoneImage" @templateDelete="templateFolderDelete"
:description="'暂无模版'" @templateEdit="templateEdit"
/> @showCurrentTemplate="showCurrentTemplate"
<div v-show="state.currentTemplateId !== ''" id="template-box" class="template-box"> @templateImport="templateImport"
<de-template-item @showTemplateEditDialog="showTemplateEditDialog"
v-for="item in state.currentTemplateShowList" />
:key="item.id" </div>
:width="state.templateCurWidth" <div class="de-tabs-right">
:model="item" <div v-if="state.currentTemplateLabel" class="active-template">
@command="key => handleCommand(key, item)" {{ state.currentTemplateLabel }}&nbsp;&nbsp;({{
/> state.currentTemplateShowList.length
}})
</div>
<el-empty
v-if="!state.currentTemplateShowList.length"
:image="NoneImage"
:description="'暂无模版'"
/>
<div v-show="state.currentTemplateId !== ''" id="template-box" class="template-box">
<de-template-item
v-for="item in state.currentTemplateShowList"
:key="item.id"
:width="state.templateCurWidth"
:model="item"
@command="key => handleCommand(key, item)"
/>
</div>
</div>
</div> </div>
</div> </div>
<el-dialog
:title="state.dialogTitle"
v-model="state.editTemplate"
append-to-body
class="de-dialog-form"
width="600px"
>
<el-form
ref="templateEditFormRef"
class="de-form-item"
:model="state.templateEditForm"
:rules="state.templateEditFormRules"
>
<el-form-item :label="state.dialogTitleLabel" prop="name">
<el-input v-model="state.templateEditForm.name" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button secondary @click="close()">{{ t('commons.cancel') }}</el-button>
<el-button type="primary" @click="saveTemplateEdit(state.templateEditForm)"
>{{ t('commons.confirm') }}
</el-button>
</div>
</template>
</el-dialog>
<!--导入templateDialog-->
<el-dialog
:title="state.templateDialog.title"
v-model="state.templateDialog.visible"
:show-close="true"
class="de-dialog-form"
width="600px"
>
<de-template-import
v-if="state.templateDialog.visible"
:pid="state.templateDialog.pid"
@refresh="showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)"
@closeEditTemplateDialog="closeEditTemplateDialog"
/>
</el-dialog>
</div> </div>
</div> </div>
<el-dialog
:title="state.dialogTitle"
v-model="state.editTemplate"
append-to-body
class="de-dialog-form"
width="600px"
>
<el-form
ref="templateEditFormRef"
class="de-form-item"
:model="state.templateEditForm"
:rules="state.templateEditFormRules"
>
<el-form-item :label="state.dialogTitleLabel" prop="name">
<el-input v-model="state.templateEditForm.name" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button secondary @click="close()">{{ t('commons.cancel') }}</el-button>
<el-button type="primary" @click="saveTemplateEdit(state.templateEditForm)"
>{{ t('commons.confirm') }}
</el-button>
</div>
</template>
</el-dialog>
<!--导入templateDialog-->
<el-dialog
:title="state.templateDialog.title"
v-model="state.templateDialog.visible"
:show-close="true"
class="de-dialog-form"
width="600px"
>
<de-template-import
v-if="state.templateDialog.visible"
:pid="state.templateDialog.pid"
@refresh="showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)"
@closeEditTemplateDialog="closeEditTemplateDialog"
/>
</el-dialog>
</div> </div>
</template> </template>
@ -118,6 +135,7 @@ const roleValidator = (rule, value, callback) => {
} }
const state = reactive({ const state = reactive({
templateFilterText: '',
showShare: false, showShare: false,
currentTemplateShowList: [], currentTemplateShowList: [],
noneImg: '@/assets/None.png', noneImg: '@/assets/None.png',
@ -145,8 +163,8 @@ const state = reactive({
currentTemplateLabel: '', currentTemplateLabel: '',
currentTemplateId: '', currentTemplateId: '',
templateList: [], templateList: [],
templateMiniWidth: 286, templateMiniWidth: 256,
templateCurWidth: 286, templateCurWidth: 256,
formType: '', formType: '',
originName: '', originName: '',
templateDialog: { templateDialog: {
@ -334,9 +352,9 @@ onMounted(() => {
// div // div
erd.listenTo(templateMainDom, element => { erd.listenTo(templateMainDom, element => {
nextTick(() => { nextTick(() => {
const curSeparator = Math.trunc(templateMainDom.offsetWidth / state.templateMiniWidth) const offsetWidth = templateMainDom.offsetWidth - 24
state.templateCurWidth = const curSeparator = Math.trunc(offsetWidth / state.templateMiniWidth)
Math.trunc(templateMainDom.offsetWidth / curSeparator) - 24 - curSeparator state.templateCurWidth = Math.trunc(offsetWidth / curSeparator) - 24 - curSeparator
}) })
}) })
}) })
@ -364,9 +382,8 @@ onMounted(() => {
.de-tabs-right { .de-tabs-right {
flex: 1; flex: 1;
background: #fff;
padding: 24px 0 24px 24px;
overflow: hidden; overflow: hidden;
background: rgba(239, 240, 241, 1);
.template-box { .template-box {
display: flex; display: flex;
@ -376,12 +393,12 @@ onMounted(() => {
align-content: flex-start; align-content: flex-start;
height: calc(100% - 10px); height: calc(100% - 10px);
width: 100%; width: 100%;
padding-bottom: 24px; padding: 16px 0px 16px 24px;
} }
.active-template { .active-template {
margin: 4px 0 20px 0; height: 56px;
padding-right: 24px; padding: 0px 24px;
font-family: 'PingFang SC'; font-family: 'PingFang SC';
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -389,8 +406,45 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
color: var(--deTextPrimary, #1f2329); color: rgba(31, 35, 41, 1);
background: #fff;
border-bottom: 1px solid rgba(31, 35, 41, 0.15);
} }
} }
} }
.router-title {
color: #1f2329;
font-feature-settings: 'clig' off, 'liga' off;
font-family: PingFang SC;
font-size: 20px;
font-style: normal;
font-weight: 500;
line-height: 28px;
float: left;
}
.sys-setting-p {
width: 100%;
background: #ffffff;
height: calc(100vh - 136px);
box-sizing: border-box;
margin-top: 12px;
}
.setting-auto-h {
height: auto !important;
}
.container-sys-param {
height: 100%;
overflow-y: auto;
}
.template-head {
height: 32px;
}
.template-search-class {
float: right;
width: 320px;
margin-right: 12px;
}
</style> </style>