UNPKG

@ovine/craft

Version:
165 lines (164 loc) 4.71 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 }) => (React.createElement("div", { "data-id": schema[nodeIdKey], className: "bg-white" }, children)); const renderSchema = Object.assign(Object.assign({}, 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; }