Files
cmdb/cmdb-ui/src/App.vue

222 lines
6.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-config-provider :locale="antdLocale">
<div id="app" :class="{ 'ops-fullscreen': isOpsFullScreen, 'ops-only-topmenu': isOpsOnlyTopMenu }">
<router-view v-if="alive" />
</div>
</a-config-provider>
</template>
<script>
import { mapState, mapActions, mapMutations } from 'vuex'
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import enUS from 'ant-design-vue/lib/locale-provider/en_US'
import { AppDeviceEnquire } from '@/utils/mixin'
import { debounce } from './utils/util'
import { getSystemLanguage } from '@/api/system.js'
import { h } from 'snabbdom'
import { DomEditor, Boot } from '@wangeditor/editor'
export default {
mixins: [AppDeviceEnquire],
provide() {
return {
reload: this.reload,
}
},
data() {
return {
alive: true,
timer: null,
}
},
computed: {
...mapState(['locale']),
antdLocale() {
if (this.locale === 'zh') {
return zhCN
}
return enUS
},
isOpsFullScreen() {
return ['cmdb_screen'].includes(this.$route.name)
},
isOpsOnlyTopMenu() {
return ['fullscreen_index', 'setting_person', 'notice_center'].includes(this.$route.name)
},
},
created() {
this.initLanguage()
this.timer = setInterval(() => {
this.setTime(new Date().getTime())
}, 1000)
},
mounted() {
this.$store.dispatch('setWindowSize')
window.addEventListener(
'resize',
debounce(() => {
this.$store.dispatch('setWindowSize')
})
)
this.handleEditor()
},
beforeDestroy() {
clearInterval(this.timer)
},
methods: {
...mapActions(['setTime']),
...mapMutations(['SET_LOCALE']),
reload() {
this.alive = false
this.$nextTick(() => {
this.alive = true
})
},
async initLanguage() {
let saveLocale = localStorage.getItem('ops_locale')
if (!saveLocale) {
let requestLanguage = ''
try {
const languageRes = await getSystemLanguage()
requestLanguage = languageRes?.language || ''
} catch (e) {
console.error('getSystemLanguage error:', e)
}
// request language variable || user local system language
const userLanguage = requestLanguage || navigator.language || navigator.userLanguage
if (userLanguage.includes('zh')) {
saveLocale = 'zh'
} else {
saveLocale = 'en'
}
}
this.SET_LOCALE(saveLocale)
this.$i18n.locale = saveLocale
},
handleEditor() {
// register custom rich text element: attachment
function withAttachment(editor) {
const { isInline, isVoid } = editor
const newEditor = editor
newEditor.isInline = (elem) => {
const type = DomEditor.getNodeType(elem)
if (type === 'attachment') return true // For type: attachment, set to inline
return isInline(elem)
}
newEditor.isVoid = (elem) => {
const type = DomEditor.getNodeType(elem)
if (type === 'attachment') return true // For type: attachment set to void
return isVoid(elem)
}
return newEditor // Must return, important!!!
}
Boot.registerPlugin(withAttachment)
/**
* Render "attachment" element in editor
* @param elem Attachment element
* @param children Child nodes (ignored for void elements)
* @param editor Editor instance
* @returns vnode (generated by snabbdom's h function)
*/
function renderAttachment(elem, children, editor) {
const { attachmentLabel = '', attachmentValue = '' } = elem
const attachVnode = h(
// HTML tag
'span',
// HTML attr, style, event
{
props: { contentEditable: false },
style: {
display: 'inline-block',
margin: '0 3px',
padding: '0 3px',
backgroundColor: '#e6f7ff',
border: '1px solid #91d5ff',
borderRadius: '2px',
color: '#1890ff',
},
on: {
click() {
console.log('clicked', attachmentValue)
}
},
},
// child node
[attachmentLabel]
)
return attachVnode
}
const renderElemConf = {
type: 'attachment',
renderElem: renderAttachment,
}
Boot.registerRenderElem(renderElemConf)
/**
* Generate HTML for "attachment" element
* @param elem Attachment element
* @param childrenHtml Child HTML (ignored for void elements)
* @returns HTML string
*/
function attachmentToHtml(elem, childrenHtml) {
// Getting data for attached elements
const { attachmentValue = '', attachmentLabel = '' } = elem
// generate HTML
const html = `<span data-w-e-type="attachment" data-w-e-is-void data-w-e-is-inline data-attachmentValue="${attachmentValue}" data-attachmentLabel="${attachmentLabel}">${attachmentLabel}</span>`
return html
}
const elemToHtmlConf = {
type: 'attachment',
elemToHtml: attachmentToHtml,
}
Boot.registerElemToHtml(elemToHtmlConf)
/**
* Parse HTML to generate "attachment" element
* @param domElem DOM element
* @param children Children
* @param editor Editor instance
* @returns Attachment element
*/
function parseAttachmentHtml(domElem, children, editor) {
// Getting attachment information from DOM element
const attachmentValue = domElem.getAttribute('data-attachmentValue') || ''
const attachmentLabel = domElem.getAttribute('data-attachmentLabel') || ''
const myResume = {
type: 'attachment',
attachmentValue,
attachmentLabel,
children: [{ text: '' }], // The void node must have children with an empty string in it, important!!!!
}
return myResume
}
const parseHtmlConf = {
selector: 'span[data-w-e-type="attachment"]', // CSS selector to match specific HTML tags
parseElemHtml: parseAttachmentHtml,
}
Boot.registerParseElemHtml(parseHtmlConf)
}
},
}
</script>
<style lang="less">
@import './style/index.less';
#app {
height: 100%;
}
</style>