NEZ-3057 feat:chart text 图表支持markdown格式
This commit is contained in:
@@ -519,6 +519,18 @@
|
|||||||
.chart-text-preview .ql-container.ql-snow {
|
.chart-text-preview .ql-container.ql-snow {
|
||||||
border: unset !important;
|
border: unset !important;
|
||||||
}
|
}
|
||||||
|
.rich-text-container{
|
||||||
|
.v-md-editor-preview{
|
||||||
|
white-space: initial;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 12px 15px;
|
||||||
|
}
|
||||||
|
.v-md-copy-code-btn{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.chart-table ,.chart-preview-dialog {
|
.chart-table ,.chart-preview-dialog {
|
||||||
.nz-table .el-table__row .custom-value .cell{
|
.nz-table .el-table__row .custom-value .cell{
|
||||||
padding: 1px 0;
|
padding: 1px 0;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
.rich-text-editor {
|
.rich-text-editor {
|
||||||
color: $--color-text-regular;
|
color: $--color-text-regular;
|
||||||
|
.ql-toolbar.ql-snow{
|
||||||
|
padding: 7px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
.ql-toolbar {
|
.ql-toolbar {
|
||||||
border: 1px solid $--border-color-light;
|
border: 1px solid $--border-color-light;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,3 +45,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.markdownEditor{
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 1px solid $--border-color-light;
|
||||||
|
box-shadow: none;
|
||||||
|
background: transparent;
|
||||||
|
.v-md-editor__toolbar{
|
||||||
|
border-bottom: 1px solid $--border-color-light;
|
||||||
|
.v-md-editor__tooltip{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.v-md-editor__toolbar-item:hover,.v-md-editor__toolbar-item--active{
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.v-md-editor__menu{
|
||||||
|
background: $--background-color-empty;
|
||||||
|
border: 1px solid $--border-color-light;
|
||||||
|
.v-md-editor__menu-item{
|
||||||
|
color: $--color-text-regular;
|
||||||
|
}
|
||||||
|
.v-md-editor__menu-item:hover{
|
||||||
|
background: $--background-color-base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-md-textarea-editor{
|
||||||
|
&>textarea{
|
||||||
|
padding: 12px 15px;
|
||||||
|
background: transparent;
|
||||||
|
color: $--color-text-regular;
|
||||||
|
font-family: menlo,Ubuntu Mono,consolas,Courier New,Microsoft Yahei,Hiragino Sans GB,WenQuanYi Micro Hei,sans-serif !important;
|
||||||
|
}
|
||||||
|
&>pre{
|
||||||
|
padding: 12px 15px;
|
||||||
|
section{
|
||||||
|
font-family: menlo,Ubuntu Mono,consolas,Courier New,Microsoft Yahei,Hiragino Sans GB,WenQuanYi Micro Hei,sans-serif !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
<div class="mt-10 rich-text-container" v-cloak style="height: 100%;width: 100%;">
|
<div class="mt-10 rich-text-container" v-cloak style="height: 100%;width: 100%;">
|
||||||
<div :id="'chartContainer' + chartInfo.id" ref="chartContainer" class="text-content" >
|
<div :id="'chartContainer' + chartInfo.id" ref="chartContainer" class="text-content" >
|
||||||
<el-scrollbar style="height: 100%;" class="el-scrollbar-normal">
|
<el-scrollbar style="height: 100%;" class="el-scrollbar-normal">
|
||||||
<div class="el-scrollbar-normal__color" style="height: 100%;" v-html="text" ></div>
|
<v-md-preview v-if="chartInfo.param.editorType==='markdown'" :text="text"></v-md-preview>
|
||||||
|
<div v-else class="el-scrollbar-normal__color" style="height: 100%;" v-html="text"></div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
43
nezha-fronted/src/components/chart/markdownEditor.vue
Normal file
43
nezha-fronted/src/components/chart/markdownEditor.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-md-editor v-model="text" @change="textChange" mode="edit" height="390px" :leftToolbar="leftToolbar" right-toolbar="" class="markdownEditor"></v-md-editor>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import enUS from '@kangc/v-md-editor/lib/lang/en-US'
|
||||||
|
import zhEn from '@kangc/v-md-editor/lib/lang/zh-CN'
|
||||||
|
import VueMarkdownEditor from '@kangc/v-md-editor'
|
||||||
|
export default {
|
||||||
|
name: 'markdownEditor',
|
||||||
|
props: {
|
||||||
|
editData: String
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
language () {
|
||||||
|
return this.$store.getters.getLanguage
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
text: undefined,
|
||||||
|
leftToolbar: 'h bold italic strikethrough quote ul ol table hr link code'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.text = this.editData
|
||||||
|
if (this.language == 'en') {
|
||||||
|
VueMarkdownEditor.lang.use('en-US', enUS)
|
||||||
|
} else {
|
||||||
|
VueMarkdownEditor.lang.use('zh-US', zhEn)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
textChange (val) {
|
||||||
|
if (this.text !== undefined) {
|
||||||
|
this.$emit('textChange', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -473,6 +473,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.chart.type == 'text' && !this.chart.param.editorType) {
|
||||||
|
this.chart.param.editorType = 'richText'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.rightBox.loading = true
|
this.rightBox.loading = true
|
||||||
this.$get('visual/dashboard/chart/' + data.id).then(res => {
|
this.$get('visual/dashboard/chart/' + data.id).then(res => {
|
||||||
@@ -536,6 +539,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.chart.type == 'text' && !this.chart.param.editorType) {
|
||||||
|
this.chart.param.editorType = 'richText'
|
||||||
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.addChartModal.isStable = 'stable'
|
this.$refs.addChartModal.isStable = 'stable'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -400,7 +400,11 @@ export default {
|
|||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
},
|
},
|
||||||
dataLink: []
|
dataLink: [],
|
||||||
|
tooltip: {
|
||||||
|
mode: 'all',
|
||||||
|
sort: 'none'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,20 @@
|
|||||||
<el-option :label="$t('overall.collapse')" :value="true"></el-option>
|
<el-option :label="$t('overall.collapse')" :value="true"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!--Editor type-->
|
||||||
|
<el-form-item class="form-item--half-width" v-if="isText(chartConfig.type)" :label='$t("dashboard.dashboard.chartForm.editorType")' prop="param.editorType">
|
||||||
|
<el-select
|
||||||
|
id="chart-box-collapse"
|
||||||
|
v-model="chartConfig.param.editorType"
|
||||||
|
placeholder=""
|
||||||
|
popper-class="right-box-select-top prevent-clickoutside"
|
||||||
|
size="small"
|
||||||
|
@change="editorTypeChange"
|
||||||
|
>
|
||||||
|
<el-option :label="$t('dashboard.dashboard.chartForm.richText')" value="richText"></el-option>
|
||||||
|
<el-option :label="$t('dashboard.dashboard.chartForm.markDown')" value="markdown"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-items--half-width-group" v-if="!isGroup(chartConfig.type)">
|
<div class="form-items--half-width-group" v-if="!isGroup(chartConfig.type)">
|
||||||
<!--width-->
|
<!--width-->
|
||||||
@@ -166,8 +180,9 @@
|
|||||||
:isChart="true"
|
:isChart="true"
|
||||||
/>
|
/>
|
||||||
<!--text-->
|
<!--text-->
|
||||||
<el-form-item v-if="isText(chartConfig.type)" :rules="{ required: true, message: $t('validate.required'), trigger: 'change' }" prop="param.text">
|
<el-form-item v-if="isText(chartConfig.type)" :rules="{ required: true, message: $t('validate.required'), trigger: 'change' }" prop="param.text">
|
||||||
<rich-text-editor ref="richTextEditor" :edit-data="chartConfig.param.text" @textChange="textChange"></rich-text-editor>
|
<markdownEditor v-if="chartConfig.param.editorType==='markdown'" :edit-data="chartConfig.param.text" @textChange="textChange"></markdownEditor>
|
||||||
|
<rich-text-editor v-else ref="richTextEditor" :edit-data="chartConfig.param.text" @textChange="textChange"></rich-text-editor>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- visibility -->
|
<!-- visibility -->
|
||||||
@@ -340,6 +355,7 @@
|
|||||||
import publicConfig from '@/components/common/rightBox/chart/publicConfig'
|
import publicConfig from '@/components/common/rightBox/chart/publicConfig'
|
||||||
import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow'
|
import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow'
|
||||||
import richTextEditor from '@/components/chart/richTextEditor'
|
import richTextEditor from '@/components/chart/richTextEditor'
|
||||||
|
import markdownEditor from '@/components/chart/markdownEditor'
|
||||||
import beforeMeta2d from '@/components/common/mixin/beforeMeta2d'
|
import beforeMeta2d from '@/components/common/mixin/beforeMeta2d'
|
||||||
import meta2dMain from '@/components/common/project/meta2d/meta2dMain'
|
import meta2dMain from '@/components/common/project/meta2d/meta2dMain'
|
||||||
import { clearTopology } from '@/components/common/js/common'
|
import { clearTopology } from '@/components/common/js/common'
|
||||||
@@ -349,6 +365,7 @@ export default {
|
|||||||
mixins: [publicConfig, chartTypeShow],
|
mixins: [publicConfig, chartTypeShow],
|
||||||
components: {
|
components: {
|
||||||
richTextEditor,
|
richTextEditor,
|
||||||
|
markdownEditor,
|
||||||
meta2dMain
|
meta2dMain
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -408,6 +425,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
editorTypeChange () {
|
||||||
|
this.chartConfig.param.text = ''
|
||||||
|
this.change()
|
||||||
|
},
|
||||||
init () {
|
init () {
|
||||||
this.chartConfig = JSON.parse(JSON.stringify(this.params))
|
this.chartConfig = JSON.parse(JSON.stringify(this.params))
|
||||||
this.reloadTopo()
|
this.reloadTopo()
|
||||||
@@ -451,7 +472,8 @@ export default {
|
|||||||
operator: 'equal',
|
operator: 'equal',
|
||||||
varValue: '',
|
varValue: '',
|
||||||
result: 'show'
|
result: 'show'
|
||||||
}
|
},
|
||||||
|
editorType: 'richText'
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'diagram':
|
case 'diagram':
|
||||||
@@ -525,9 +547,13 @@ export default {
|
|||||||
this.topologyDialogChange(false, topo)
|
this.topologyDialogChange(false, topo)
|
||||||
},
|
},
|
||||||
textChange (val) {
|
textChange (val) {
|
||||||
const html = `<div class="editor-core ql-container ql-snow"><div class="ql-editor">${val}</div></div>`
|
if (this.$lodash.get(this.chartConfig, 'param.editorType', 'richText') === 'richText') {
|
||||||
this.chartConfig.param.text = html
|
const html = `<div class="editor-core ql-container ql-snow"><div class="ql-editor">${val}</div></div>`
|
||||||
this.$refs.chartForm.validateField('param.text')
|
this.chartConfig.param.text = html
|
||||||
|
} else {
|
||||||
|
this.chartConfig.param.text = val
|
||||||
|
}
|
||||||
|
this.$refs.chartForm && this.$refs.chartForm.validateField('param.text')
|
||||||
this.change()
|
this.change()
|
||||||
},
|
},
|
||||||
reloadTopo () {
|
reloadTopo () {
|
||||||
|
|||||||
@@ -648,6 +648,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.chart.type == 'text' && !this.chart.param.editorType) {
|
||||||
|
this.chart.param.editorType = 'richText'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.rightBox.loading = true
|
this.rightBox.loading = true
|
||||||
this.$get('visual/dashboard/chart/' + data.id).then(res => {
|
this.$get('visual/dashboard/chart/' + data.id).then(res => {
|
||||||
@@ -711,6 +714,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.chart.type == 'text' && !this.chart.param.editorType) {
|
||||||
|
this.chart.param.editorType = 'richText'
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$refs.addChartModal.isStable = 'stable'
|
this.$refs.addChartModal.isStable = 'stable'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,15 +45,20 @@ import htmlToPdf from '@/components/common/js/htmlToPdf'
|
|||||||
import mainMixin from '@/components/common/mixin/mainMixinFun'
|
import mainMixin from '@/components/common/mixin/mainMixinFun'
|
||||||
import introJS from 'intro.js'
|
import introJS from 'intro.js'
|
||||||
|
|
||||||
// v-md-editor
|
// v-md-editor 预览组件
|
||||||
import VMdPreview from '@kangc/v-md-editor/lib/preview'
|
import VMdPreview from '@kangc/v-md-editor/lib/preview'
|
||||||
import '@kangc/v-md-editor/lib/style/preview.css'
|
import '@kangc/v-md-editor/lib/style/preview.css'
|
||||||
import githubTheme from '@kangc/v-md-editor/lib/theme/github.js'
|
import githubTheme from '@kangc/v-md-editor/lib/theme/github.js'
|
||||||
import '@kangc/v-md-editor/lib/theme/style/github.css'
|
import '@kangc/v-md-editor/lib/theme/style/github.css'
|
||||||
import hljs from 'highlight.js'
|
|
||||||
// markdown支持代码复制
|
// markdown支持代码复制
|
||||||
import createCopyCodePlugin from '@/components/common/copy-code/index'
|
import createCopyCodePlugin from '@/components/common/copy-code/index'
|
||||||
import '@/components/common/copy-code/copy-code.css'
|
import '@/components/common/copy-code/copy-code.css'
|
||||||
|
// highlightjs
|
||||||
|
import hljs from 'highlight.js'
|
||||||
|
// markdown编辑器
|
||||||
|
import VMdEditor from '@kangc/v-md-editor'
|
||||||
|
import '@kangc/v-md-editor/lib/style/base-editor.css'
|
||||||
|
|
||||||
VMdPreview.xss.extend({
|
VMdPreview.xss.extend({
|
||||||
// extend white list
|
// extend white list
|
||||||
whiteList: {
|
whiteList: {
|
||||||
@@ -65,6 +70,10 @@ VMdPreview.use(githubTheme, {
|
|||||||
})
|
})
|
||||||
VMdPreview.use(createCopyCodePlugin())
|
VMdPreview.use(createCopyCodePlugin())
|
||||||
Vue.use(VMdPreview)
|
Vue.use(VMdPreview)
|
||||||
|
VMdEditor.use(githubTheme, {
|
||||||
|
Hljs: hljs
|
||||||
|
})
|
||||||
|
Vue.use(VMdEditor)
|
||||||
|
|
||||||
// Pace.on("done", function() {
|
// Pace.on("done", function() {
|
||||||
// $self.isShowAuth = false;
|
// $self.isShowAuth = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user