|
@@ -1,5 +1,5 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, computed, onUnmounted, watch } from 'vue'
|
|
|
+import { ref, computed, onUnmounted, watch, nextTick } from 'vue'
|
|
|
import { Delete, Edit } from '@element-plus/icons-vue'
|
|
|
import Markdown from '/@/components/markdown/Markdown.vue'
|
|
|
import type { MarkdownDashBoard, Position, Size, Content, ResizeType } from './types'
|
|
@@ -35,7 +35,13 @@ const initialPosition = ref({ x: 0, y: 0 })
|
|
|
// 编辑相关状态
|
|
|
const showEditDialog = ref(false)
|
|
|
const editTitle = ref<string>()
|
|
|
+const editType = ref<MarkdownDashBoard['type']>()
|
|
|
const editData = ref('')
|
|
|
+const editCharts = ref()
|
|
|
+
|
|
|
+watch(editData,()=>{
|
|
|
+ editCharts.value?.resize()
|
|
|
+})
|
|
|
|
|
|
// 右键菜单相关状态
|
|
|
const showContextMenu = ref(false)
|
|
@@ -152,10 +158,13 @@ const stopResize = () => {
|
|
|
}
|
|
|
|
|
|
// 编辑卡片
|
|
|
-const handleEdit = () => {
|
|
|
+const handleEdit = async () => {
|
|
|
editTitle.value = props.card.title
|
|
|
editData.value = props.card.data
|
|
|
+ editType.value = props.card.type
|
|
|
showEditDialog.value = true
|
|
|
+ await nextTick()
|
|
|
+ editCharts.value?.resize()
|
|
|
}
|
|
|
|
|
|
// 确认编辑
|
|
@@ -303,40 +312,49 @@ watch(()=> props.card.h, () => {
|
|
|
<el-dialog
|
|
|
v-model="showEditDialog"
|
|
|
title="编辑卡片内容"
|
|
|
- width="600px"
|
|
|
+ width="900px"
|
|
|
:before-close="cancelEdit"
|
|
|
append-to-body
|
|
|
>
|
|
|
- <div class="edit-form">
|
|
|
- <div class="form-item" v-if="editTitle !== undefined">
|
|
|
- <label class="form-label">卡片标题</label>
|
|
|
- <el-input
|
|
|
- v-model="editTitle"
|
|
|
- placeholder="请输入卡片标题"
|
|
|
- maxlength="50"
|
|
|
- show-word-limit
|
|
|
- />
|
|
|
- </div>
|
|
|
+ <div class="edit-dialog-content">
|
|
|
+ <!-- 左侧编辑区 -->
|
|
|
+ <div class="edit-panel">
|
|
|
+ <div class="form-item" v-if="editTitle !== undefined">
|
|
|
+ <label class="form-label">卡片标题</label>
|
|
|
+ <el-input
|
|
|
+ v-model="editTitle"
|
|
|
+ placeholder="请输入卡片标题"
|
|
|
+ maxlength="50"
|
|
|
+ show-word-limit
|
|
|
+ />
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="form-item">
|
|
|
- <label class="form-label">卡片内容 (支持Markdown)</label>
|
|
|
- <el-input
|
|
|
- v-model="editData"
|
|
|
- type="textarea"
|
|
|
- placeholder="请输入卡片内容,支持Markdown语法"
|
|
|
- :rows="8"
|
|
|
- resize="vertical"
|
|
|
- />
|
|
|
+ <div class="form-item">
|
|
|
+ <label class="form-label">卡片内容 (支持Markdown)</label>
|
|
|
+ <el-input
|
|
|
+ v-model="editData"
|
|
|
+ type="textarea"
|
|
|
+ placeholder="请输入卡片内容,支持Markdown语法"
|
|
|
+ :rows="16"
|
|
|
+ resize="none"
|
|
|
+ class="edit-textarea"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="preview-section">
|
|
|
- <label class="form-label">预览效果</label>
|
|
|
+ <!-- 右侧预览区 -->
|
|
|
+ <div class="preview-panel">
|
|
|
+ <div class="preview-header">
|
|
|
+ <label class="form-label">预览效果</label>
|
|
|
+ </div>
|
|
|
<div class="preview-container">
|
|
|
<Markdown
|
|
|
- :content="editData || '暂无内容'"
|
|
|
+ v-if="editType === 'markdown'"
|
|
|
+ :content="editData"
|
|
|
:plugins="plugin"
|
|
|
class="preview-content"
|
|
|
/>
|
|
|
+ <vue-charts ref="editCharts" style="width: 100%;height: 100%" :data="editData" v-if="editType === 'echarts'"/>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -503,9 +521,25 @@ watch(()=> props.card.h, () => {
|
|
|
}
|
|
|
|
|
|
/* 编辑对话框样式 */
|
|
|
-.edit-form {
|
|
|
+.edit-dialog-content {
|
|
|
+ display: flex;
|
|
|
+ gap: 20px;
|
|
|
+ height: 500px;
|
|
|
+}
|
|
|
+
|
|
|
+.edit-panel {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
.form-item {
|
|
|
- margin-bottom: 20px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.form-label {
|
|
@@ -516,16 +550,43 @@ watch(()=> props.card.h, () => {
|
|
|
color: var(--el-text-color-primary);
|
|
|
}
|
|
|
|
|
|
- .preview-section {
|
|
|
- margin-top: 24px;
|
|
|
+ .edit-textarea {
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ :deep(.el-textarea__inner) {
|
|
|
+ height: 100% !important;
|
|
|
+ resize: none;
|
|
|
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.preview-panel {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ border-left: 1px solid var(--el-border-color-lighter);
|
|
|
+ padding-left: 20px;
|
|
|
+
|
|
|
+ .preview-header {
|
|
|
+ margin-bottom: 8px;
|
|
|
+
|
|
|
+ .form-label {
|
|
|
+ display: block;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.preview-container {
|
|
|
+ flex: 1;
|
|
|
border: 1px solid var(--el-border-color-light);
|
|
|
border-radius: 6px;
|
|
|
padding: 16px;
|
|
|
background: var(--el-fill-color-extra-light);
|
|
|
- max-height: 200px;
|
|
|
overflow-y: auto;
|
|
|
}
|
|
|
|