feat: dashboard preview single

This commit is contained in:
wangjiahao
2025-06-11 18:19:24 +08:00
parent 7b2695e567
commit b170450463
8 changed files with 121 additions and 42 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M14.3333 1.33325H1.66667C1.29848 1.33325 1 1.63173 1 1.99992V11.3333C1 11.7014 1.29848 11.9999 1.66667 11.9999H14.3333C14.7015 11.9999 15 11.7014 15 11.3333V1.99992C15 1.63173 14.7015 1.33325 14.3333 1.33325ZM2.33333 8.66659V2.66659H13.6667V8.66659H2.33333ZM2.33333 9.99992H13.6667V10.6666H2.33333V9.99992ZM4.66667 13.3333H11.3333V14.6666H4.66667V13.3333Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 437 B

+1 -1
View File
@@ -171,7 +171,7 @@ const name = ref('admin')
const activeMenu = computed(() => route.path)
const routerList = computed(() => {
return router.getRoutes().filter(route => {
return !route.path.includes('canvas') && route.path !== '/login' && !route.path.includes('/system') && !route.redirect && route.path !== '/:pathMatch(.*)*' && !route.path.includes('dsTable')
return !route.path.includes('canvas') &&!route.path.includes('preview') && route.path !== '/login' && !route.path.includes('/system') && !route.redirect && route.path !== '/:pathMatch(.*)*' && !route.path.includes('dsTable')
})
})
+7
View File
@@ -6,6 +6,7 @@ import login from "@/views/login/index.vue";
import chat from "@/views/chat/index.vue";
import ds from "@/views/ds/index.vue";
import DashboardEditor from "@/views/dashboard/editor/index.vue";
import DashboardPreview from "@//views/dashboard/preview/SQPreviewSingle.vue";
import Dashboard from "@/views/dashboard/index.vue";
import Model from "@/views/system/model/index.vue";
// import User from "@/views/system/user/index.vue";
@@ -75,6 +76,12 @@ const router = createRouter({
component: DashboardEditor,
meta: { title: "canvas", icon: "dashboard" },
},
{
path: "/dashboard-preview",
name: "preview",
component: DashboardPreview,
meta: { title: "DashboardPreview", icon: "dashboard" },
},
/* {
path: "/setting",
component: Layout,
@@ -56,10 +56,12 @@ const viewDemoInnerId = computed(() => 'enlarge-inner-content-' + configItem.val
<style lang="less" scoped>
.wrapper-outer {
position: absolute;
.wrapper-inner {
width: 100%;
height: 100%;
position: relative;
background: #fff;
background-size: 100% 100% !important;
.wrapper-inner-adaptor {
@@ -46,12 +46,10 @@ const props = defineProps({
}
})
const { canvasStyleData, componentData, showPosition,
canvasId
} = toRefs(props)
const { canvasStyleData, componentData, showPosition, canvasId} = toRefs(props)
const domId = 'preview-' + canvasId.value
const previewCanvas = ref(null)
const renderReady = ref(false)
const renderReady = ref(true)
const state = reactive({
initState: true,
scrollMain: 0
@@ -64,7 +62,7 @@ const baseHeight = ref(0)
const baseMarginLeft = ref(0)
const baseMarginTop = ref(0)
const canvasStyle = computed(() => {
return {}
return {background: '#f5f6f7'}
})
const restore = () => {
@@ -83,9 +81,9 @@ function nowItemStyle(item: CanvasItem) {
const sizeInit = () => {
if (previewCanvas.value) {
//@ts-ignore
const screenWidth = dashboardEditorRef.value.offsetWidth
const screenWidth = previewCanvas.value.offsetWidth
//@ts-ignore
const screenHeight = dashboardEditorRef.value.offsetHeight
const screenHeight = previewCanvas.value.offsetHeight
baseMarginLeft.value = 10
baseMarginTop.value = 10
baseWidth.value = (screenWidth - baseMarginLeft.value) / props.baseMatrixCount.x - baseMarginLeft.value
@@ -97,12 +95,9 @@ const sizeInit = () => {
onMounted(() => {
window.addEventListener('resize', sizeInit)
const erd = elementResizeDetectorMaker()
sizeInit()
//@ts-ignore
erd.listenTo(document.getElementById(domId), () => {
restore()
})
elementResizeDetectorMaker().listenTo(document.getElementById(domId), sizeInit)
})
defineExpose({
@@ -111,13 +106,7 @@ defineExpose({
</script>
<template>
<div
:id="domId"
class="canvas-container"
:style="canvasStyle"
ref="previewCanvas"
v-if="state.initState"
>
<div :id="domId" class="canvas-container" :style="canvasStyle" ref="previewCanvas" v-if="state.initState">
<template v-if="renderReady">
<SQComponentWrapper
v-for="(item, index) in componentData"
@@ -3,12 +3,15 @@ import dashboardInfoSvg from '@/assets/svg/dashboard-info.svg'
import icon_pc_outlined from '@/assets/svg/icon_pc_outlined.svg'
import icon_edit_outlined from '@/assets/svg/icon_edit_outlined.svg'
import DashboardDetailInfo from "@/views/dashboard/common/DashboardDetailInfo.vue";
const emit = defineEmits(['reload', 'download', 'downloadAsAppTemplate'])
const preview = () => {}
const edit = () =>{}
defineProps({
const preview = () => {
window.open(`#/dashboard-preview?resourceId=${props.dashboardInfo.id}`, '_blank')
}
const edit = () => {
window.open(`#/canvas?resourceId=${props.dashboardInfo.id}`, '_blank')
}
const props = defineProps({
dashboardInfo: {
type: Object,
required: true
@@ -20,12 +23,14 @@ defineProps({
<template>
<div class="preview-head flex-align-center">
<div class="canvas-name ellipsis">{{ dashboardInfo.name }}</div>
<el-divider style="margin: 5px 10px 0 17px" direction="vertical" />
<el-divider style="margin: 5px 10px 0 17px" direction="vertical"/>
<span class="create-area" style="line-height: 22px">Creator:{{ dashboardInfo.createName }}</span>
<div style="padding-top: 4px" class="create-area flex-align-center">
<el-popover show-arrow :offset="8" placement="bottom" width="400" trigger="hover">
<template #reference>
<el-icon class="info-tips"><dashboardInfoSvg class="svg-icon" /></el-icon>
<el-icon class="info-tips">
<dashboardInfoSvg class="svg-icon"/>
</el-icon>
</template>
<DashboardDetailInfo :dashboard-info="dashboardInfo"></DashboardDetailInfo>
</el-popover>
@@ -33,15 +38,20 @@ defineProps({
<div class="canvas-opt-button">
<el-button secondary @click="preview">
<template #icon>
<icon name="icon_pc_outlined"><icon_pc_outlined class="svg-icon" /></icon>
<icon name="icon_pc_outlined">
<icon_pc_outlined class="svg-icon"/>
</icon>
</template>
Preview
</el-button>
<el-button class="custom-button" type="primary" @click="edit">
<template #icon>
<Icon name="icon_edit_outlined"><icon_edit_outlined class="svg-icon" /></Icon>
<Icon name="icon_edit_outlined">
<icon_edit_outlined class="svg-icon"/>
</Icon>
</template>
Edit</el-button
Edit
</el-button
>
</div>
</div>
@@ -55,6 +65,7 @@ defineProps({
.ed-icon {
margin-right: 8px;
}
.arrow-right_icon {
position: absolute;
right: 12px;
@@ -66,6 +77,7 @@ defineProps({
}
}
}
.preview-head {
display: flex;
width: 100%;
@@ -73,11 +85,13 @@ defineProps({
height: 56px;
padding: 16px 24px;
border-bottom: 1px solid rgba(31, 35, 41, 0.15);
.canvas-name {
max-width: 200px;
font-size: 16px;
font-weight: 500;
}
.canvas-have-update {
background-color: rgba(52, 199, 36, 0.2);
color: rgba(44, 169, 31, 1);
@@ -88,20 +102,24 @@ defineProps({
padding: 0 4px;
margin-left: 8px;
}
.custom-icon {
cursor: pointer;
margin-left: 8px;
}
.create-area {
color: #646a73;
font-weight: 400;
font-size: 14px;
}
.canvas-opt-button {
display: flex;
justify-content: right;
align-items: center;
flex: 1;
.head-more-icon {
color: #1f2329;
margin-left: 12px;
@@ -109,6 +127,7 @@ defineProps({
font-size: 20px;
border-radius: 4px;
position: relative;
&:hover {
&::after {
content: '';
@@ -124,6 +143,7 @@ defineProps({
}
}
}
.info-tips {
margin-left: 4px;
font-size: 16px;
@@ -14,16 +14,11 @@ const previewCanvasContainer = ref(null)
const dashboardPreview = ref(null)
const slideShow = ref(true)
const dataInitState = ref(true)
const downloadStatus = ref(false)
const state = reactive({
canvasDataPreview: [],
canvasStylePreview: {},
canvasViewInfoPreview: {},
dashboardInfo: {},
showOffset: {
top: 110,
left: 280
}
dashboardInfo: {}
})
const props = defineProps({
@@ -53,12 +48,9 @@ const rootManage = computed(() => {
const mounted = computed(() => {
return resourceTreeRef.value?.mounted
})
function createNew() {
resourceTreeRef.value?.createNewObject()
}
const loadCanvasData = (params: any) => {
dataInitState.value = false
load_resource_prepare({id: params.id},
@@ -128,8 +120,6 @@ defineExpose({
:canvas-style-data="state.canvasStylePreview"
:canvas-view-info="state.canvasViewInfoPreview"
:show-position="showPosition"
:download-status="downloadStatus"
:show-linkage-button="false"
></SQPreview>
</div>
</template>
@@ -0,0 +1,71 @@
<script setup lang="ts">
import SQPreview from "@/views/dashboard/preview/SQPreview.vue";
import {load_resource_prepare} from "@/views/dashboard/utils/canvasUtils.ts";
import {onMounted, reactive, ref} from "vue";
import router from "@/router";
const previewCanvasContainer = ref(null)
const dashboardPreview = ref(null)
const dataInitState = ref(true)
const downloadStatus = ref(false)
const state = reactive({
resourceId: null,
canvasDataPreview: [],
canvasStylePreview: {},
canvasViewInfoPreview: {},
dashboardInfo: {}
})
onMounted(() => {
//@ts-ignore
state.resourceId = router.currentRoute.value.query.resourceId
if (state.resourceId) {
loadCanvasData({id: state.resourceId})
}
}
)
const loadCanvasData = (params: any) => {
dataInitState.value = false
load_resource_prepare({id: params.id},
//@ts-ignore
function ({dashboardInfo, canvasDataResult, canvasStyleResult, canvasViewInfoPreview}) {
state.canvasDataPreview = canvasDataResult
state.canvasStylePreview = canvasStyleResult
state.canvasViewInfoPreview = canvasViewInfoPreview
state.dashboardInfo = dashboardInfo
dataInitState.value = true
}
)
}
</script>
<template>
<div ref="previewCanvasContainer" class="content" id="sq-preview-content">
<SQPreview
ref="dashboardPreview"
v-if="state.canvasStylePreview && dataInitState"
:dashboard-info="state.dashboardInfo"
:component-data="state.canvasDataPreview"
:canvas-style-data="state.canvasStylePreview"
:canvas-view-info="state.canvasViewInfoPreview"
:download-status="downloadStatus"
></SQPreview>
</div>
</template>
<style scoped lang="less">
.content {
position: relative;
display: flex;
width: 100%;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
align-items: center;
}
</style>