NEZ-3174 notebook导出html

This commit is contained in:
zyh
2023-09-20 11:00:00 +08:00
parent 0ac19a8d21
commit 22bbd8b982
8 changed files with 173 additions and 121 deletions

View File

@@ -41,114 +41,115 @@
margin-right: 10px;
}
}
.notebook-scrollWrap{
width: 100%;
height: 100%;
overflow: hidden scroll;
position: relative;
}
}
.notebook-scrollWrap{
width: 100%;
height: 100%;
overflow: hidden scroll;
position: relative;
.notebook-content{
width: 100%;
max-width: 1200px;
margin: auto;
&>:not(.notebook-list){
width: calc(100% - 40px);
margin-left: 20px;
margin-right: 20px;
}
.notebook-content{
width: 100%;
max-width: 1200px;
margin: auto;
&>:not(.notebook-list){
width: calc(100% - 40px);
margin-left: 20px;
margin-right: 20px;
}
}
.notebook-title{
box-sizing: border-box;
margin-top: 30px;
padding-bottom: 20px;
}
.notebook-title{
box-sizing: border-box;
margin-top: 30px;
padding-bottom: 20px;
font-family: Roboto-Medium;
font-size: 24px;
color: $--color-text-primary;
letter-spacing: 0;
font-weight: 500;
line-height: 28px;
border-bottom: 1px solid $--border-color-light;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.notebook-title-input{
box-sizing: border-box;
margin-top: 30px;
.el-input__inner{
height: 46px;
font-family: Roboto-Medium;
font-size: 24px;
color: $--color-text-primary;
letter-spacing: 0;
font-weight: 500;
line-height: 28px;
border-bottom: 1px solid $--border-color-light;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
line-height: 46px;
}
.notebook-title-input{
box-sizing: border-box;
margin-top: 30px;
.el-input__inner{
height: 46px;
font-family: Roboto-Medium;
font-size: 24px;
color: $--color-text-primary;
letter-spacing: 0;
font-weight: 500;
line-height: 46px;
}
}
.notebook-list{
height: auto;
.panel-chart.my-loading-parent--relative{
height: 100% !important;
}
.notebook-list{
height: auto;
.panel-chart.my-loading-parent--relative{
height: 100% !important;
}
.no-data{
text-align: center;
position: absolute;
left: 0;
right: 0;
top: 50%;
margin-top: -54px;
.no-data-div {
color: $--color-text-regular;
}
}
}
.notebook-add{
padding-bottom: 60px;
.notebook-add-title{
margin-bottom: 10px;
font-family: Roboto-Regular;
font-size: 14px;
color: $--color-text-primary;
font-weight: 400;
}
.notebook-add-list{
display: grid;
grid-gap:10px;
grid-template-columns:repeat(auto-fill, minmax(172px, 1fr));
}
.notebook-add-item{
min-width: 172px;
height: 62px;
border: 1px solid $--border-color-light;
border-radius: 4px;
padding: 0 20px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
&:hover{
background: #FFFBF5;
border: 1px solid rgba(250,144,28,0.49);
box-shadow: 0px 1px 4px 0px rgba(250,144,28,0.13);
}
.notebook-chart-icon{
width: 24px;
margin-right: 12px;
}
span{
font-size: 14px;
color: $--color-text-primary;
}
}
.notebook-add-show{
font-family: Roboto-Regular;
font-size: 14px;
color: #FA901C;
font-weight: 400;
margin-top: 16px;
cursor: pointer;
.no-data{
text-align: center;
position: absolute;
left: 0;
right: 0;
top: 50%;
margin-top: -54px;
.no-data-div {
color: $--color-text-regular;
}
}
}
.notebook-add{
padding-bottom: 60px;
.notebook-add-title{
margin-bottom: 10px;
font-family: Roboto-Regular;
font-size: 14px;
color: $--color-text-primary;
font-weight: 400;
}
.notebook-add-list{
display: grid;
grid-gap:10px;
grid-template-columns:repeat(auto-fill, minmax(172px, 1fr));
}
.notebook-add-item{
min-width: 172px;
height: 62px;
border: 1px solid $--border-color-light;
border-radius: 4px;
padding: 0 20px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
&:hover{
background: #FFFBF5;
border: 1px solid rgba(250,144,28,0.49);
box-shadow: 0px 1px 4px 0px rgba(250,144,28,0.13);
}
.notebook-chart-icon{
width: 24px;
margin-right: 12px;
}
span{
font-size: 14px;
color: $--color-text-primary;
}
}
.notebook-add-show{
font-family: Roboto-Regular;
font-size: 14px;
color: #FA901C;
font-weight: 400;
margin-top: 16px;
cursor: pointer;
}
}
}

View File

@@ -70,6 +70,7 @@
:globalVariables="globalVariables"
></chart-url>
<chart-text
:from="from"
:ref="'chart' + chartInfo.id"
v-if="isText(chartInfo.type)"
:chart-data="chartData"

View File

@@ -134,7 +134,7 @@
<chart-temp-box v-if="rightBox.chartTemp.show" :from="from" :obj="chart" :panel-data="panelData" :show-panel="showPanel" @close="closeRightBox" @on-create-success="createSuccess"></chart-temp-box>
</transition>
<!-- 快照进度 -->
<snapshotProgress v-if="snapshotVisible" :showPanel="showPanel" :searchTime="searchTime" :snapshotVisible.sync="snapshotVisible"></snapshotProgress>
<snapshotProgress v-if="snapshotVisible" :showPanel="showPanel" :searchTime="searchTime" :snapshotVisible.sync="snapshotVisible" api="dashboard"></snapshotProgress>
</div>
</template>

View File

@@ -32,7 +32,7 @@
<div @click="download('markdown')">{{$t('notebook.downloadAs',{format:'markdown'})}}</div>
</el-dropdown-item>
<el-dropdown-item v-has="'dashboard_view'">
<div @click="download('json')">{{$t('notebook.downloadNotebook')}} JSON</div>
<div @click="download('html')">{{$t('notebook.downloadAs',{format:'html'})}}</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@@ -88,7 +88,7 @@
</transition>
<!-- 快照进度 -->
<snapshotProgress v-if="snapshotVisible" :showPanel="showPanel" :searchTime="searchTime" :snapshotVisible.sync="snapshotVisible"></snapshotProgress>
<snapshotProgress v-if="snapshotVisible" :showPanel="showPanel" :searchTime="searchTime" :snapshotVisible.sync="snapshotVisible" api="notebook"></snapshotProgress>
</div>
</template>
@@ -245,6 +245,8 @@ export default {
const index = this.$refs.notebookList.copyDataList.findIndex(item => item.id == chart.id)
this.$refs.notebookList.copyDataList.splice(index, 1)
this.$refs.notebookList.onScroll(this.scrollbarWrap.scrollTop)
this.chart = {}
this.$store.dispatch('clearPanel')
},
/* 图表相关操作--start */
addChart (chart) {
@@ -278,6 +280,22 @@ export default {
this.$refs.addChartModal.isStable = 'stable'
})
},
addText () {
const chart = {
name: '',
type: 'text',
unit: 2,
datasource: 'misc',
span: 12,
height: 4,
w: 12,
h: 4,
x: 0,
y: this.getMaxY(this.$refs.notebookList.copyDataList),
param: this.newChart('text')
}
this.createSuccess(chart)
},
getMaxId (arr) { // 获取当前列表最大的id
if (!arr.length) {
return 1
@@ -446,13 +464,18 @@ export default {
varValue: '',
result: 'show'
},
editorType: 'markdown'
editorType: 'markdown',
isEdit: true
}
break
}
return param
},
addChartBefore (chart) {
// if (chart.type === 'text') {
// this.addText()
// return false
// }
this.$store.dispatch('dispatchEditChart', {
chart: chart,
type: 'add'
@@ -485,7 +508,8 @@ export default {
this.$store.commit('setNotebookEdit', true)
},
download (type) {
console.log(type)
this.showPanel.format = type
this.snapshotVisible = true
},
// 获取数据,用在子页面
getData () {

View File

@@ -98,7 +98,7 @@
</el-form-item>
</div>
<!--content-->
<div v-if="contentShow(chartConfig.type)" class="form__sub-title">
<div v-if="contentShow(chartConfig.type)&&from!=='notebook'" class="form__sub-title">
<span>{{$t('dashboard.dashboard.chartForm.content')}}</span>
<span style="cursor: pointer" v-if="isDiagram(chartConfig.type)"><i class="nz-icon nz-icon-edit" @click="topologyDialogChange(true)"></i></span>
</div>
@@ -130,7 +130,7 @@
:isChart="true"
/>
<!--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)&&from!=='notebook'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change' }" prop="param.text">
<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>

View File

@@ -75,7 +75,8 @@ export default {
snapshotVisible: {
type: Boolean,
default: false
}
},
api: String
},
data () {
return {
@@ -99,14 +100,18 @@ export default {
}
})
const params = {
format: 'html',
dashboardId: this.showPanel.id,
format: this.showPanel.format || 'html',
start: this.$stringTimeParseToUnix(bus.formateTimeToTime(this.searchTime[0])),
end: this.$stringTimeParseToUnix(bus.formateTimeToTime(this.searchTime[1])),
vars: vars
end: this.$stringTimeParseToUnix(bus.formateTimeToTime(this.searchTime[1]))
}
if (this.api === 'dashboard') {
params.dashboardId = this.showPanel.id
params.vars = vars
} else {
params.id = this.showPanel.id
}
// 创建任务
const res = await this.$post('/visual/dashboard/snapshot/task', params)
const res = await this.$post(`/visual/${this.api}/snapshot/task`, params)
if (res.code === 200) {
// 定时获取运行时间
this.timer = createWorker(() => {
@@ -124,7 +129,7 @@ export default {
this.task = setInterval(async () => {
if (this.process < 100) {
try {
const res = await this.$get('/visual/dashboard/snapshot/result/' + this.tid)
const res = await this.$get(`/visual/${this.api}/snapshot/result/` + this.tid)
this.total = res.data.taskId.total
this.done = res.data.taskId.done
this.process = parseFloat(res.data.taskId.process)
@@ -140,7 +145,7 @@ export default {
downloadSnapshot () {
let total = 10
let loaded = 0
this.$get('/visual/dashboard/snapshot/download/' + this.tid, {}, {
this.$get(`/visual/${this.api}/snapshot/download/` + this.tid, {}, {
onDownloadProgress: function (progressEvent) {
// 处理原生进度事件
total = progressEvent.total
@@ -165,13 +170,13 @@ export default {
if (window.navigator.msSaveOrOpenBlob) {
// 兼容ie11
const blobObject = new Blob([res])
window.navigator.msSaveOrOpenBlob(blobObject, fileName + '.html')
window.navigator.msSaveOrOpenBlob(blobObject, fileName + '.' + (this.showPanel.format || 'html'))
} else {
const blob = new Blob([res])
const link = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 下载链接
link.href = href
link.download = fileName + '.html' // 下载后文件名
link.download = fileName + '.' + (this.showPanel.format || 'html') // 下载后文件名
document.body.appendChild(link)
link.click() // 点击下载
document.body.removeChild(link) // 下载完成移除元素
@@ -217,7 +222,7 @@ export default {
beforeDestroy () {
this.clearTimer()
if (this.tid) {
this.$get('/visual/dashboard/snapshot/cancel/' + this.tid)
this.$get(`/visual/${this.api}/snapshot/cancel/` + this.tid)
}
}
}

View File

@@ -153,7 +153,7 @@
<dashboardTempBox v-if="rightBox.dashboardTemp.show" :from="fromRoute.dashboard" @close="closeDashboardTempBox"></dashboardTempBox>
</transition>
<!-- 快照进度 -->
<snapshotProgress v-if="snapshotVisible" :showPanel="showPanel" :searchTime="searchTime" :snapshotVisible.sync="snapshotVisible"></snapshotProgress>
<snapshotProgress v-if="snapshotVisible" :showPanel="showPanel" :searchTime="searchTime" :snapshotVisible.sync="snapshotVisible" api="dashboard"></snapshotProgress>
</div>
</template>

View File

@@ -13,8 +13,11 @@
<div style="display: flex;flex-direction: column">
<!-- <i class="nz-icon nz-icon-arrow-down"/>-->
<div style="font-size: 18px;font-weight: 600;color: #333;margin-bottom: 3px;text-align: right" v-if="!dataJson.type"> {{dataJson.dashboard.data.name}} </div>
<div style="font-size: 18px;font-weight: 600;color: #333;margin-bottom: 3px;text-align: right" v-if="dataJson.type"> Explore </div>
<div style="font-size: 18px;font-weight: 600;color: #333;margin-bottom: 3px;text-align: right">
<span v-if="dataJson.type==='dashboard'">{{dataJson.dashboard.data.name}}</span>
<span v-else-if="dataJson.type==='notebook'">{{dataJson.notebook.data.name}}</span>
<span v-else>Explore</span>
</div>
<span> {{dateFormat(dataJson.start * 1000)}} - {{dateFormat(dataJson.end * 1000)}} ({{dataJson.timezone}})</span>
</div>
</div>
@@ -47,6 +50,22 @@
>
</exploreItem>
</div>
<div v-if="dataJson.type==='notebook'" ref="scrollbar" class="notebook-scrollWrap" style='background: #fffffe; height: calc(100% - 72px);'>
<div class="notebook-content">
<notebook-list
ref="notebookList"
:from="'notebook'"
:data-list="dataJson.charts.data.list"
:dataJson = "dataJson.chartsData"
:is-export-html="true"
:time-range="searchTime"
:nowTimeType="nowTimeType"
>
</notebook-list>
</div>
</div>
</div>
</div>
@@ -58,6 +77,7 @@
<script>
import chartList from '@/components/chart/chartList.vue'
import exploreItem from '@/components/page/dashboard/explore/exploreItemHtml'
import notebookList from '@/components/page/notebook/notebookList.vue'
import moment from 'moment-timezone'
import { loadI18n } from '@/components/common/i18n'
import i18nData from '@/entrance/exportHtml/i18nData'
@@ -74,7 +94,8 @@ export default {
},
components: {
chartList: chartList,
exploreItem
exploreItem,
notebookList
},
created () {
this.$i18n.locale = this.dataJson.language