diff --git a/cmdb-ui/src/App.vue b/cmdb-ui/src/App.vue index f57f232..6e1e114 100644 --- a/cmdb-ui/src/App.vue +++ b/cmdb-ui/src/App.vue @@ -47,6 +47,134 @@ export default { this.$store.dispatch('setWindowSize') }) ) + + // 注册富文本自定义元素 + const resume = { + type: 'attachment', + attachmentLabel: '', + attachmentValue: '', + children: [{ text: '' }], // void 元素必须有一个 children ,其中只有一个空字符串,重要!!! + } + + function withAttachment(editor) { + // JS 语法 + const { isInline, isVoid } = editor + const newEditor = editor + + newEditor.isInline = (elem) => { + const type = DomEditor.getNodeType(elem) + if (type === 'attachment') return true // 针对 type: attachment ,设置为 inline + return isInline(elem) + } + + newEditor.isVoid = (elem) => { + const type = DomEditor.getNodeType(elem) + if (type === 'attachment') return true // 针对 type: attachment ,设置为 void + return isVoid(elem) + } + + return newEditor // 返回 newEditor ,重要!!! + } + Boot.registerPlugin(withAttachment) + /** + * 渲染“附件”元素到编辑器 + * @param elem 附件元素,即上文的 myResume + * @param children 元素子节点,void 元素可忽略 + * @param editor 编辑器实例 + * @returns vnode 节点(通过 snabbdom.js 的 h 函数生成) + */ + function renderAttachment(elem, children, editor) { + // JS 语法 + + // 获取“附件”的数据,参考上文 myResume 数据结构 + const { attachmentLabel = '', attachmentValue = '' } = elem + + // 附件元素 vnode + const attachVnode = h( + // HTML tag + 'span', + // HTML 属性、样式、事件 + { + props: { contentEditable: false }, // HTML 属性,驼峰式写法 + style: { + display: 'inline-block', + margin: '0 3px', + padding: '0 3px', + backgroundColor: '#e6f7ff', + border: '1px solid #91d5ff', + borderRadius: '2px', + color: '#1890ff', + }, // style ,驼峰式写法 + on: { + click() { + console.log('clicked', attachmentValue) + } /* 其他... */, + }, + }, + // 子节点 + [attachmentLabel] + ) + + return attachVnode + } + const renderElemConf = { + type: 'attachment', // 新元素 type ,重要!!! + renderElem: renderAttachment, + } + Boot.registerRenderElem(renderElemConf) + + /** + * 生成“附件”元素的 HTML + * @param elem 附件元素,即上文的 myResume + * @param childrenHtml 子节点的 HTML 代码,void 元素可忽略 + * @returns “附件”元素的 HTML 字符串 + */ + function attachmentToHtml(elem, childrenHtml) { + // JS 语法 + + // 获取附件元素的数据 + const { attachmentValue = '', attachmentLabel = '' } = elem + + // 生成 HTML 代码 + const html = `${attachmentLabel}` + + return html + } + const elemToHtmlConf = { + type: 'attachment', // 新元素的 type ,重要!!! + elemToHtml: attachmentToHtml, + } + Boot.registerElemToHtml(elemToHtmlConf) + + /** + * 解析 HTML 字符串,生成“附件”元素 + * @param domElem HTML 对应的 DOM Element + * @param children 子节点 + * @param editor editor 实例 + * @returns “附件”元素,如上文的 myResume + */ + function parseAttachmentHtml(domElem, children, editor) { + // JS 语法 + + // 从 DOM element 中获取“附件”的信息 + const attachmentValue = domElem.getAttribute('data-attachmentValue') || '' + const attachmentLabel = domElem.getAttribute('data-attachmentLabel') || '' + + // 生成“附件”元素(按照此前约定的数据结构) + const myResume = { + type: 'attachment', + attachmentValue, + attachmentLabel, + children: [{ text: '' }], // void node 必须有 children ,其中有一个空字符串,重要!!! + } + + return myResume + } + const parseHtmlConf = { + selector: 'span[data-w-e-type="attachment"]', // CSS 选择器,匹配特定的 HTML 标签 + parseElemHtml: parseAttachmentHtml, + } + Boot.registerParseElemHtml(parseHtmlConf) }, beforeDestroy() { clearInterval(this.timer) diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue index 51d7bb2..679d79a 100644 --- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue +++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/index.vue @@ -1,163 +1,168 @@ - - - - - - - + + + + + + + diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/node.js b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/node.js index b2b4143..af8cd49 100644 --- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/node.js +++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelationTopo/node.js @@ -1,56 +1,56 @@ -/* eslint-disable no-useless-constructor */ -import { TreeNode } from 'butterfly-dag' - -import $ from 'jquery' - -class BaseNode extends TreeNode { - constructor(opts) { - super(opts) - } - - draw = (opts) => { - const container = $(`
`) - .css('top', opts.top) - .css('left', opts.left) - .attr('id', opts.id) - let icon - if (opts.options.icon) { - if (opts.options.icon.split('$$')[2]) { - icon = $(`