UNPKG

@ovine/craft

Version:
210 lines (170 loc) 4.08 kB
import { get, includes, isEmpty, isObjectLike, map, cloneDeep, uniqueId, isArray } from 'lodash' import React from 'react' import { nodeIdKey } from '@/constants' const getEditNodeInfo = (type) => { const nodeConf = { dialog: { text: '弹窗', }, drawer: { text: '抽屉', }, } if (includes(Object.keys(nodeConf), type)) { return nodeConf[type] } return false } export const genNodeId = (type) => { if (type === 'none') { return uniqueId('none-') } return uniqueId('node-') } // 根据 ID 获取 key 的路径 export function getIdKeyPath(source, nodeId) { if (!isObjectLike(source)) { return [] } const path = [] let found = false function search(stack) { if (get(stack, nodeIdKey) === nodeId) { found = true return } map(stack, (value, key) => { if (found) { return } path.push(key) if (isObjectLike(stack[key])) { search(value) if (found) { return } } path.pop() }) } search(source) return path } // 获取 渲染时 配置 export function getRenderSchema(self) { const cursor = self.editCursor const schema = cursor.get() // 异常数据 if (!isObjectLike(schema) || isEmpty(schema)) { return { type: 'tpl', tpl: '请输入有效 schema', } } if (!getEditNodeInfo(schema.type)) { return schema } // 重写 dialog/drawer 容器组件 禁止 预览时 弹出 const Component = ({ children }) => ( <div data-id={schema[nodeIdKey]} className="bg-white"> {children} </div> ) const renderSchema = { ...schema, wrapperComponent: Component, } return renderSchema } // 获取所有的节点信息 export function getAllNodes(schema) { // 异常数据 if (!isObjectLike(schema) || isEmpty(schema)) { return [] } const nodes = [] // 遍历节点 const travel = (node, key, items = []) => { if (!isObjectLike(node)) { return } const item = { children: [] } if (isArray(node)) { item.type = `${key}-array` item.id = genNodeId('none') items.push(item) } else { const type = get(node, 'type') // 将每一个有 type 属性的渲染器,与 id 标记 const omitEditNode = getEditNodeInfo(schema.type) || !getEditNodeInfo(type) if (type && omitEditNode && !!node[nodeIdKey]) { item.type = type item.id = node[nodeIdKey] items.push(item) } } map(node, (subNode, subKey) => { travel(subNode, subKey, item.children) }) } travel(schema, '', nodes) return nodes } // 获取需要独立编辑的 节点 export function getEditNodes(schema) { const nodes = [ { id: '', label: '页面', }, ] if (!isObjectLike(schema)) { return nodes } // 遍历设置 const travel = (node) => { if (!isObjectLike(node)) { return } const type = get(node, 'type') const id = get(node, nodeIdKey) const info = getEditNodeInfo(type) // 将每一个有 type 属性的渲染器,添加 id 标记 if (type && id && info) { nodes.push({ id, // TODO: label 需要优化 更明确的 标示 label: `${info.text}-${node.title || id}`, }) } map(node, travel) } travel(schema) return nodes } export function setSchemaNodeId(source, option = {}) { const { isClone = false, forceUpdate = false } = option // 防止数据篡改 const schema = isClone ? cloneDeep(source) : source // 异常数据 if (!isObjectLike(schema) || isEmpty(schema)) { return { type: 'tpl', tpl: '请输入有效 schema', } } // 遍历设置 const travel = (node) => { if (!isObjectLike(node)) { return } const type = get(node, 'type') // 将每一个有 type 属性的渲染器,添加 id 标记 if (type && (!node[nodeIdKey] || forceUpdate)) { node[nodeIdKey] = genNodeId() } map(node, travel) } travel(schema) return schema }