UNPKG

@nocobase/plugin-block-template

Version:

Create and manage block templates for reuse on pages.

396 lines (394 loc) 17.9 kB
/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var template_exports = {}; __export(template_exports, { cleanSchema: () => cleanSchema, getNewFullBlock: () => getNewFullBlock, mergeSchema: () => mergeSchema }); module.exports = __toCommonJS(template_exports); var import_utils = require("@nocobase/utils"); var import_lodash = __toESM(require("lodash")); async function getNewFullBlock(db, transaction, blockUid) { const repository = db.getRepository("uiSchemas"); const block = await repository.getJsonSchema(blockUid, { includeAsyncNode: true, readFromCache: true, transaction }); const templateId = block["x-template-root-uid"]; if (!templateId) { return block; } const template = await repository.getJsonSchema(templateId, { includeAsyncNode: true, readFromCache: true, transaction }); const newSchema = mergeSchema(template, block, import_lodash.default.cloneDeep(template)); cleanSchema(newSchema, templateId); return newSchema; } function getNewObjectValue(itemsMap) { const remainingTemplateItems = { properties: {} }; for (const [_uid, item] of itemsMap.entries()) { let current = remainingTemplateItems; for (const pathItem of item.path.slice(1)) { if (!current.properties) { current.properties = {}; } if (!current.properties[pathItem.key]) { current.properties[pathItem.key] = { ...pathItem.schema, properties: {} }; } current = current.properties[pathItem.key]; } current.properties = current.properties || {}; current.properties[item.key] = item.schema; } return remainingTemplateItems.properties; } const NestedGridComponents = ["Grid", "Grid.Row", "Grid.Col"]; function collectGridItems(schema, itemsMap, parentPath = [], schemaKey) { const properties = schema.properties || {}; const component = schema["x-component"]; if (NestedGridComponents.includes(component)) { parentPath = [ ...parentPath, { schema, type: component, key: schemaKey || "" } ]; } for (const [key, property] of Object.entries(properties)) { if (!property) continue; const propertyComponent = property["x-component"]; if (NestedGridComponents.includes(propertyComponent)) { collectGridItems(property, itemsMap, parentPath, key); } else if (property["x-uid"]) { itemsMap.set(property["x-uid"], { schema: property, path: parentPath, key }); } } } function mergeSchema(template, schema, rootTemplate) { if (template["properties"] && !schema["properties"]) { schema["properties"] = {}; } return import_lodash.default.mergeWith( template, schema, (objectValue, sourceValue, keyName, object, source) => { var _a, _b, _c, _d, _e, _f, _g, _h; if (sourceValue == null) { return objectValue; } if (keyName === "default" && object["x-settings"] === "actionSettings:filter") { return sourceValue || objectValue; } if (import_lodash.default.isObject(sourceValue)) { if (import_lodash.default.isArray(sourceValue)) { return sourceValue || objectValue; } if (keyName === "properties") { const sourceKeys = Object.keys(sourceValue); let targetKeys = Object.keys(objectValue || {}); if (NestedGridComponents.includes(source["x-component"]) && NestedGridComponents.includes(object["x-component"])) { const tItemsMap = /* @__PURE__ */ new Map(); const sItemsMap = /* @__PURE__ */ new Map(); collectGridItems(object, tItemsMap); collectGridItems(source, sItemsMap); for (const [uid2, sourceItem] of sItemsMap.entries()) { if (!sourceItem.schema["x-template-uid"]) continue; const templateItem = tItemsMap.get(sourceItem.schema["x-template-uid"]); if (templateItem) { const mergedSchema = mergeSchema(templateItem.schema || {}, sourceItem.schema, rootTemplate); sourceItem.path[sourceItem.path.length - 1].schema.properties[sourceItem.key] = mergedSchema; sourceItem.schema = mergedSchema; tItemsMap.delete(sourceItem.schema["x-template-uid"]); } } objectValue = getNewObjectValue(tItemsMap); object["properties"] = objectValue; targetKeys = Object.keys(objectValue); } if (object["x-component"] === "CollectionField") { for (const skey of sourceKeys) { const assFieldCom = (_a = sourceValue[skey]) == null ? void 0 : _a["x-component"]; if ([ "Action.Container", "AssociationField.Viewer", "AssociationField.Selector", "AssociationField.Nester", "AssociationField.SubTable" ].includes(assFieldCom)) { const tkey = targetKeys.find((k) => objectValue[k]["x-component"] === assFieldCom); if (tkey) { sourceValue[skey]["x-template-uid"] = objectValue[tkey]["x-uid"]; sourceValue[skey] = mergeSchema(objectValue[tkey] || {}, sourceValue[skey], rootTemplate); targetKeys = targetKeys.filter((k) => k !== tkey); } } } } if (/:configure.*Actions/.test(object["x-initializer"])) { for (const skey of sourceKeys) { if (object["x-initializer"] === "filterForm:configureActions") { const sourceUseComponentProps = (_b = sourceValue[skey]) == null ? void 0 : _b["x-use-component-props"]; if (sourceUseComponentProps && ["useFilterBlockActionProps", "useResetBlockActionProps"].includes(sourceUseComponentProps)) { const removedTargetKeys = import_lodash.default.remove(targetKeys, (key) => { var _a2; const targetUseComponentProps = (_a2 = objectValue[key]) == null ? void 0 : _a2["x-use-component-props"]; return sourceUseComponentProps === targetUseComponentProps; }); if (removedTargetKeys.length > 0) { sourceValue[skey]["x-template-uid"] = objectValue[removedTargetKeys[0]]["x-uid"]; } } } if (((_c = sourceValue[skey]) == null ? void 0 : _c["x-component"]) && ((_e = (_d = sourceValue[skey]) == null ? void 0 : _d["x-settings"]) == null ? void 0 : _e.includes("actionSettings"))) { const actionName = sourceValue[skey]["x-settings"].split(":")[1]; const targetActionName = [ "bulkDelete", "filter", "refresh", "delete", "print", "stepsFormNext", "stepsFormPrevious", "disassociate", "MailSend", "MailRefresh", "MailAccountSetting", "MailMarkAsRead", "MailMarkAsUnRead" ].find((name) => name === actionName); if (targetActionName) { const removedTargetKeys = import_lodash.default.remove( targetKeys, (key) => { var _a2; return ((_a2 = objectValue[key]) == null ? void 0 : _a2["x-settings"]) === `actionSettings:${targetActionName}`; } ); if (removedTargetKeys.length > 0) { sourceValue[skey]["x-template-uid"] = objectValue[removedTargetKeys[0]]["x-uid"]; } } } } } for (const skey of sourceKeys) { if ((_f = object["x-initializer"]) == null ? void 0 : _f.includes(":configureColumns")) { if (sourceValue[skey]["x-component"] && sourceValue[skey]["x-settings"] === "fieldSettings:TableColumn") { const sourceColFieldSchema = Object.values(((_g = sourceValue[skey]) == null ? void 0 : _g["properties"]) || {})[0]; const xColField = import_lodash.default.get(sourceColFieldSchema, "x-collection-field"); if (xColField) { let targetColFieldSchema = null; const removedTargetKeys = import_lodash.default.remove(targetKeys, (key) => { var _a2; targetColFieldSchema = Object.values(((_a2 = objectValue[key]) == null ? void 0 : _a2["properties"]) || {})[0]; const targetColField = import_lodash.default.get(targetColFieldSchema, "x-collection-field"); return xColField === targetColField; }); if (removedTargetKeys.length > 0) { sourceValue[skey]["x-template-uid"] = objectValue[removedTargetKeys[0]]["x-uid"]; sourceColFieldSchema["x-template-uid"] = targetColFieldSchema == null ? void 0 : targetColFieldSchema["x-uid"]; } } } if ((_h = sourceValue[skey]["x-initializer"]) == null ? void 0 : _h.includes(":configureItemActions")) { const removedTargetKeys = import_lodash.default.remove(targetKeys, (key) => { var _a2, _b2; return (_b2 = (_a2 = objectValue[key]) == null ? void 0 : _a2["x-initializer"]) == null ? void 0 : _b2.includes(":configureItemActions"); }); if (removedTargetKeys.length > 0) { sourceValue[skey]["x-template-uid"] = objectValue[removedTargetKeys[0]]["x-uid"]; } } } } if (/:configureFields/.test(source["x-initializer"])) { const targetFieldsMap = /* @__PURE__ */ new Map(); collectGridItems(object, targetFieldsMap); const targetFields = Array.from(targetFieldsMap.values()); for (const skey of sourceKeys) { const sourceFieldsMap = /* @__PURE__ */ new Map(); collectGridItems(sourceValue[skey], sourceFieldsMap); for (const [uid2, sourceItem] of sourceFieldsMap.entries()) { const xColField = import_lodash.default.get(sourceItem.schema, "x-collection-field"); if (!xColField) continue; const targetItem = import_lodash.default.find(targetFields, (field) => field.schema["x-collection-field"] === xColField); if (targetItem) { targetFieldsMap.delete(targetItem.schema["x-uid"]); sourceItem.schema["x-template-uid"] = targetItem.schema["x-uid"]; sourceItem.schema = mergeSchema(targetItem.schema || {}, sourceItem.schema, rootTemplate); } } objectValue = getNewObjectValue(targetFieldsMap); object["properties"] = objectValue; targetKeys = Object.keys(objectValue); } } if (object["x-decorator"] === "DndContext") { for (const skey of sourceKeys) { const actionSettings = sourceValue[skey]["x-settings"]; if (sourceValue[skey]["x-component"] && ["actionSettings:disassociate", "actionSettings:delete"].includes(actionSettings)) { const removedTargetKeys = import_lodash.default.remove(targetKeys, (key) => { var _a2; return ((_a2 = objectValue[key]) == null ? void 0 : _a2["x-settings"]) === actionSettings; }); if (removedTargetKeys.length > 0) { sourceValue[skey]["x-template-uid"] = objectValue[removedTargetKeys[0]]["x-uid"]; } } } } const keys = import_lodash.default.union(targetKeys, sourceKeys); const newKeys = import_lodash.default.difference(targetKeys, sourceKeys); if (newKeys.length > 0) { const newProperties = import_lodash.default.cloneDeep(import_lodash.default.pick(objectValue, newKeys)); const newSchemas = []; for (const key of newKeys) { const newSchema = convertTplBlock(newProperties[key]); newSchema["name"] = key; newSchemas.push(newSchema); source["properties"][key] = newSchema; } } const properties = {}; for (let i = 0; i < keys.length; i++) { const k = keys[i]; const sourceProperty = (sourceValue == null ? void 0 : sourceValue[k]) || {}; if (import_lodash.default.get(objectValue, [k, "properties"])) { sourceProperty["properties"] = sourceProperty["properties"] || {}; } properties[k] = mergeSchema((objectValue == null ? void 0 : objectValue[k]) || {}, sourceValue == null ? void 0 : sourceValue[k], rootTemplate); if (properties[k]["x-template-root-uid"] && properties[k]["x-template-root-uid"] === rootTemplate["x-uid"]) { properties[k] = mergeSchema(import_lodash.default.cloneDeep(rootTemplate), properties[k], rootTemplate); } } const parentIndexs = []; for (const key in properties) { if (properties[key]["x-index"]) { const xIndex = properties[key]["x-index"]; if (parentIndexs.includes(xIndex)) { properties[key]["x-index"] = Math.max(...parentIndexs) + 1; } parentIndexs.push(properties[key]["x-index"]); } } return properties; } return mergeSchema(objectValue || {}, sourceValue || {}, rootTemplate); } return sourceValue; } ); } function shouldDeleteNoComponentSchema(schema) { if (!schema["x-no-component"]) { return true; } const properties = schema == null ? void 0 : schema.properties; return properties && Object.values(properties).some((s) => s["x-component"] == null); } function cleanSchema(schema, templateId) { var _a, _b, _c; const properties = (schema == null ? void 0 : schema.properties) || {}; for (const key of Object.keys(properties)) { if (schema.properties[key]["x-component"] == null && schema.properties[key]["x-template-id"] && !schema.properties[key]["x-template-root-uid"] && shouldDeleteNoComponentSchema(schema.properties[key])) { delete schema.properties[key]; continue; } if (schema.properties[key]["x-template-root-uid"] && schema.properties[key]["x-template-root-uid"] !== templateId) { continue; } if (((_a = properties[key]) == null ? void 0 : _a["x-component-props"]) === null) { delete properties[key]["x-component-props"]; } if (((_b = properties[key]) == null ? void 0 : _b["x-component"]) === "Grid.Row") { let hasProperties = false; const cols = Object.values(((_c = properties[key]) == null ? void 0 : _c["properties"]) || {}); for (const col of cols) { if (col["x-component"] === "Grid.Col") { if (!import_lodash.default.isEmpty(col["properties"])) { hasProperties = true; } } } if (!hasProperties) { delete properties[key]; } } cleanSchema(properties[key], templateId); } if (schema) { delete schema["x-template-root-uid"]; delete schema["x-template-uid"]; delete schema["x-block-template-key"]; delete schema["x-virtual"]; delete schema["x-template-version"]; } } function convertTplBlock(tpl) { const newSchema = import_lodash.default.cloneDeep(tpl); const regeneratedUid = (schema) => { if (schema["x-uid"]) { schema["x-uid"] = (0, import_utils.uid)(); } if (schema["properties"]) { for (const key in schema["properties"]) { regeneratedUid(schema["properties"][key]); } } }; regeneratedUid(newSchema); return newSchema; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { cleanSchema, getNewFullBlock, mergeSchema });