<template>
<el-dialog
class="create-dialog"
:title="t('visualization.new_from_template')"
v-model="state.dialogShow"
width="700"
:before-close="close"
@submit.prevent
>
<el-row class="create-main" v-loading="state.loading">
<el-row>
<el-col :span="18" style="height: 40px">
<el-radio v-model="state.inputType" label="new_outer_template"
>{{ t('visualization.import_template') }}
</el-radio>
<el-radio v-model="state.inputType" label="new_inner_template" @click="getTree"
>{{ t('visualization.copy_template') }}
</el-radio>
</el-col>
<el-col v-if="state.inputType === 'new_outer_template'" :span="6" class="button-main">
<el-button class="el-icon-upload" size="small" type="primary" @click="goFile"
>{{ t('visualization.upload_template') }}
</el-button>
<input
id="input"
ref="files"
type="file"
accept=".DET2"
hidden
@change="handleFileChange"
/>
</el-col>
</el-row>
<el-row style="margin-top: 5px">
<el-col :span="4" class="name-area">{{ t('visualization.name') }}</el-col>
<el-col :span="20">
<el-input v-model="state.dvCreateInfo.name" clearable size="small" />
</el-col>
</el-row>
<el-row v-if="state.inputType === 'new_inner_template'" class="preview">
<el-col :span="8" style="height: 100%; overflow-y: auto">
<de-template-preview-list
:template-list="state.templateList"
@showCurrentTemplateInfo="showCurrentTemplateInfo"
/>
</el-col>
<el-col :span="16" :style="classBackground" class="preview-show" />
</el-row>
<el-row
v-if="state.inputType === 'new_outer_template'"
class="preview"
:style="classBackground"
/>
<el-row class="root-class">
<el-button size="small" @click="cancel()">{{ t('commons.cancel') }} </el-button>
<el-button type="primary" size="small" :disabled="!saveStatus" @click="save()"
>{{ t('commons.confirm') }}
</el-button>
</el-row>
</el-row>
</el-dialog>
</template>
<script setup lang="ts">
import { showTemplateList } from '@/api/template'
import { useI18n } from '@/hooks/web/useI18n'
import { computed, reactive, ref, watch } from 'vue'
import { imgUrlTrans } from '@/utils/imgUtils'
import { ElMessage } from 'element-plus-secondary'
import { decompression } from '@/api/visualization/dataVisualization'
import DeTemplatePreviewList from '@/views/common/DeTemplatePreviewList.vue'
const { t } = useI18n()
const emits = defineEmits(['finish'])
const files = ref(null)
const props = defineProps({
curCanvasType: {
type: String,
required: true
}
})
const state = reactive({
dialogShow: false,
loading: false,
inputType: 'new_outer_template',
fieldName: 'name',
tableRadio: null,
keyWordSearch: '',
columnLabel: t('visualization.belong_to_category'),
templateList: [],
importTemplateInfo: {
snapshot: ''
},
dvCreateInfo: {
pid: -1,
name: null,
canvasStyleData: null,
componentData: null,
templateId: null,
dynamicData: null,
staticResource: null
},
templateSelected: false
})
const saveStatus = computed(() => {
return state.dvCreateInfo.name && state.templateSelected
})
const classBackground = computed(() => {
if (state.importTemplateInfo.snapshot) {
return {
background: `url(${imgUrlTrans(state.importTemplateInfo.snapshot)}) no-repeat`
}
} else {
return {}
}
})
watch(
() => state.inputType,
() => {
createInit()
}
)
const createInit = () => {
state.templateSelected = false
state.dvCreateInfo.name = null
state.dvCreateInfo.canvasStyleData = null
state.dvCreateInfo.componentData = null
state.importTemplateInfo.snapshot = null
state.dvCreateInfo.templateId = null
}
const showCurrentTemplateInfo = data => {
state.dvCreateInfo.templateId = data.id
if (data.nodeType === 'folder') {
state.dvCreateInfo.name = null
state.importTemplateInfo.snapshot = null
state.templateSelected = false
} else {
state.dvCreateInfo.name = data.name
state.importTemplateInfo.snapshot = data.snapshot
state.templateSelected = true
}
}
const getTree = () => {
const request = {
level: '0',
leafDvType: props.curCanvasType,
withChildren: true
}
state.loading = true
showTemplateList(request).then(res => {
state.templateList = res.data
state.loading = false
})
}
const cancel = () => {
emits('finish')
}
const save = () => {
if (!state.dvCreateInfo.name) {
ElMessage.warning(t('common.save_success'))
return false
}
if (state.dvCreateInfo.name.length > 50) {
ElMessage.warning(t('common.char_can_not_more_50'))
return false
}
if (!state.dvCreateInfo.templateId && state.inputType === 'new_inner_template') {
ElMessage.warning('chart.template_can_not_empty')
return false
}
state.dvCreateInfo['newFrom'] = state.inputType
state.loading = true
decompression(state.dvCreateInfo)
.then(response => {
state.loading = false
emits('finish', response.data)
})
.catch(() => {
state.loading = false
})
}
const handleFileChange = e => {
const file = e.target.files[0]
const reader = new FileReader()
reader.onload = res => {
state.templateSelected = true
const result = res.target.result
state.importTemplateInfo = JSON.parse(result)
state.dvCreateInfo.name = state.importTemplateInfo['name'].name
state.dvCreateInfo.canvasStyleData = state.importTemplateInfo['canvasStyleData']
state.dvCreateInfo.componentData = state.importTemplateInfo['componentData']
state.dvCreateInfo.dynamicData = state.importTemplateInfo['dynamicData']
state.dvCreateInfo.staticResource = state.importTemplateInfo['staticResource']
}
reader.readAsText(file)
}
const goFile = () => {
files.value.click()
}
const close = () => {
state.dialogShow = false
}
const optInit = () => {
state.dialogShow = true
createInit()
}
defineExpose({
optInit
})
</script>
<style scoped lang="less">
.create-main {
display: inherit;
}
.name-area {
display: flex;
align-items: center;
justify-content: left;
}
.button-main {
display: flex;
align-items: center;
justify-content: right;
}
.root-class {
display: flex;
align-items: center;
justify-content: right;
margin: 15px 0px 5px;
}
.preview {
margin-top: 5px;
border: 1px solid #e6e6e6;
height: 310px !important;
overflow: hidden;
background-size: 100% 100% !important;
}
.preview-show {
border-left: 1px solid #e6e6e6;
height: 310px;
background-size: 100% 100% !important;
}
</style>