/**
 * 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 builder_exports = {};
__export(builder_exports, {
  assignClientKeysToUids: () => assignClientKeysToUids,
  buildActionTree: () => buildActionTree,
  buildBlockTree: () => buildBlockTree,
  buildCanonicalTableActionsColumnNode: () => buildCanonicalTableActionsColumnNode,
  buildFieldTree: () => buildFieldTree,
  buildPersistedRootPageModel: () => buildPersistedRootPageModel,
  buildPopupPageTree: () => buildPopupPageTree,
  buildStandaloneFieldNode: () => buildStandaloneFieldNode,
  buildSyntheticRootPageTabModel: () => buildSyntheticRootPageTabModel,
  getStandaloneFieldDefaults: () => getStandaloneFieldDefaults
});
module.exports = __toCommonJS(builder_exports);
var import_utils = require("@nocobase/utils");
var import_lodash = __toESM(require("lodash"));
var import_catalog = require("./catalog");
var import_chart_config = require("./chart-config");
var import_approval = require("./approval");
var import_service_utils = require("./service-utils");
var import_public_compatibility = require("./public-compatibility");
var import_hidden_popup_contract = require("./hidden-popup-contract");
const JS_BLOCK_DEFAULT_CODE = [
  "// Welcome to the JS block",
  "ctx.render(`",
  `  <div style="padding: 24px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6;">`,
  '    <h2 style="color: #1890ff; margin: 0 0 12px 0; font-size: 24px; font-weight: 600;">JS Block</h2>',
  '    <p style="color: #666; margin: 0;">Replace this code with your custom JavaScript to build an interactive block.</p>',
  "  </div>",
  "`);"
].join("\n");
const JS_FIELD_DEFAULT_CODE = [
  "function JsReadonlyField() {",
  "  const React = ctx.React;",
  "  const { prefix, suffix, overflowMode } = ctx.model?.props || {};",
  "  const text = String(ctx.value ?? '');",
  "  const whiteSpace = overflowMode === 'wrap' ? 'pre-line' : 'nowrap';",
  "",
  "  return (",
  "    <span style={{ whiteSpace }}>",
  "      {prefix}",
  "      {text}",
  "      {suffix}",
  "    </span>",
  "  );",
  "}",
  "",
  "ctx.render(<JsReadonlyField />);"
].join("\n");
const JS_EDITABLE_FIELD_DEFAULT_CODE = [
  "// Render an editable antd Input via JSX and keep it in sync with form value.",
  "function JsEditableField() {",
  "  const React = ctx.React;",
  "  const { Input } = ctx.antd;",
  "  const [value, setValue] = React.useState(ctx.getValue?.() ?? '');",
  "",
  "  React.useEffect(() => {",
  "    const handler = (ev) => setValue(ev?.detail ?? '');",
  "    ctx.element?.addEventListener('js-field:value-change', handler);",
  "    return () => ctx.element?.removeEventListener('js-field:value-change', handler);",
  "  }, []);",
  "",
  "  const onChange = (e) => {",
  "    const v = e?.target?.value ?? '';",
  "    setValue(v);",
  "    ctx.setValue?.(v);",
  "  };",
  "",
  "  return <Input {...ctx.model.props} value={value} onChange={onChange} />;",
  "}",
  "",
  "ctx.render(<JsEditableField />);"
].join("\n");
const JS_ITEM_DEFAULT_CODE = [
  "function JsItem() {",
  "  return (",
  `    <div style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif", lineHeight: 1.6 }}>`,
  "      <h3 style={{ color: '#1890ff', margin: '0 0 12px 0', fontSize: 18, fontWeight: 600 }}>JS Item</h3>",
  "      <div style={{ color: '#555' }}>This area is rendered by your JavaScript code.</div>",
  "    </div>",
  "  );",
  "}",
  "",
  "ctx.render(<JsItem />);"
].join("\n");
const JS_COLUMN_DEFAULT_CODE = `ctx.render('<span class="nb-js-column">JS column</span>');`;
const JS_ITEM_ACTION_DEFAULT_CODE = [
  "const { Button } = ctx.antd;",
  "",
  "function JsItemAction() {",
  "  return (",
  '    <Button onClick={() => ctx.message.success("Click from JS item")}>',
  "      JS item",
  "    </Button>",
  "  );",
  "}",
  "",
  "ctx.render(<JsItemAction />);"
].join("\n");
const CALENDAR_QUICK_CREATE_ACTION_KEY = "quickCreateAction";
const CALENDAR_EVENT_VIEW_ACTION_KEY = "eventViewAction";
const KANBAN_QUICK_CREATE_ACTION_KEY = "quickCreateAction";
const KANBAN_CARD_VIEW_ACTION_KEY = "cardViewAction";
const KANBAN_LEGACY_PARENT_CARD_POPUP_PROP_KEYS = [
  "cardOpenMode",
  "cardPopupSize",
  "cardPopupTemplateUid",
  "cardPopupPageModelClass",
  "cardPopupTargetUid"
];
const KANBAN_LEGACY_QUICK_CREATE_POPUP_PROP_KEYS = [
  "popupMode",
  "popupSize",
  "popupTemplateUid",
  "popupPageModelClass",
  "popupTargetUid"
];
const KANBAN_BLOCK_CARD_POPUP_STEP_PARAMS_PATH = ["cardSettings", "popup"];
const CALENDAR_READONLY_ACTION_MODEL_USES = /* @__PURE__ */ new Set([
  "CalendarNavActionModel",
  "CalendarTitleActionModel",
  "CalendarViewSelectActionModel"
]);
const AI_EMPLOYEE_ACTION_USE = "AIEmployeeButtonModel";
const AI_EMPLOYEE_DEFAULT_STYLE = {
  size: 40,
  mask: false
};
function resolveModelStepParamsOrLegacyObject(model, path, legacyValue) {
  if (import_lodash.default.has(model.stepParams, path)) {
    const value = import_lodash.default.get(model.stepParams, path);
    return import_lodash.default.isPlainObject(value) ? value : {};
  }
  return import_lodash.default.isPlainObject(legacyValue) ? legacyValue : void 0;
}
function resolvePersistableModelStepParamsOrLegacyObject(model, path, legacyValue) {
  const value = resolveModelStepParamsOrLegacyObject(model, path, legacyValue);
  if (!import_lodash.default.isPlainObject(value)) {
    return void 0;
  }
  const normalized = normalizeInitialKanbanPopupSettings(value);
  return Object.keys(normalized).length ? normalized : void 0;
}
function extractPersistableModelStepParamsOrLegacyObject(model, path, legacyValue) {
  const value = resolvePersistableModelStepParamsOrLegacyObject(model, path, legacyValue);
  import_lodash.default.unset(model.stepParams, path);
  return value;
}
function persistModelPopupStepParams(model, path, popupSettings) {
  if (!import_lodash.default.isPlainObject(popupSettings)) {
    return;
  }
  import_lodash.default.set(model.stepParams, path, import_lodash.default.cloneDeep(popupSettings));
}
function normalizeInitialKanbanPopupSettings(popupSettings) {
  return (0, import_hidden_popup_contract.normalizeHiddenPopupSettings)(popupSettings);
}
function normalizeInitialKanbanPopupSettingsFromProps(actionKey, props) {
  if (!import_lodash.default.isPlainObject(props)) {
    return void 0;
  }
  const rawSettings = actionKey === KANBAN_QUICK_CREATE_ACTION_KEY ? (0, import_service_utils.buildDefinedPayload)({
    mode: props.popupMode,
    size: props.popupSize,
    popupTemplateUid: props.popupTemplateUid,
    pageModelClass: props.popupPageModelClass,
    uid: props.popupTargetUid
  }) : (0, import_service_utils.buildDefinedPayload)({
    mode: props.cardOpenMode,
    size: props.cardPopupSize,
    popupTemplateUid: props.cardPopupTemplateUid,
    pageModelClass: props.cardPopupPageModelClass,
    uid: props.cardPopupTargetUid
  });
  const normalized = normalizeInitialKanbanPopupSettings(rawSettings);
  return Object.keys(normalized).length ? normalized : void 0;
}
const JS_ACTION_DEFAULT_CODE_BY_USE = {
  JSCollectionActionModel: [
    "const rows = ctx.resource?.getSelectedRows?.() || [];",
    "if (!rows.length) {",
    "  ctx.message.warning('Please select data first.');",
    "} else {",
    "  ctx.message.success('Selected ' + rows.length + ' row(s).');",
    "}"
  ].join("\n"),
  JSRecordActionModel: [
    "if (!ctx.record) {",
    "  ctx.message.error('No record');",
    "} else {",
    "  ctx.message.success('Record ID: ' + (ctx.filterByTk ?? ctx.record?.id));",
    "}"
  ].join("\n"),
  JSFormActionModel: [
    "const values = ctx.form?.getFieldsValue?.() || {};",
    "ctx.message.success('Current form values: ' + JSON.stringify(values));"
  ].join("\n"),
  FilterFormJSActionModel: "",
  JSActionModel: "ctx.message.info('Hello JS action.');"
};
function buildRunJsStepParams(code) {
  return {
    runJs: {
      version: "v2",
      code
    }
  };
}
function buildPersistedRootPageModel(options) {
  const pageUid = options.pageUid || (0, import_utils.uid)();
  const enableTabs = !!options.enableTabs;
  const displayTitle = options.displayTitle !== false;
  return {
    uid: pageUid,
    use: "RootPageModel",
    props: {
      routeId: options.routeId,
      title: options.pageTitle,
      enableTabs,
      displayTitle
    },
    stepParams: {
      pageSettings: {
        general: {
          title: options.pageTitle,
          displayTitle,
          enableTabs,
          documentTitle: options.pageDocumentTitle
        }
      }
    }
  };
}
function buildSyntheticRootPageTabModel(options) {
  var _a;
  const stepParams = import_lodash.default.cloneDeep(options.stepParams || {});
  return {
    uid: options.uid,
    use: options.use || "RootPageTabModel",
    props: {
      ...options.props || {},
      route: import_lodash.default.cloneDeep(options.route),
      title: options.title,
      icon: options.icon
    },
    decoratorProps: import_lodash.default.cloneDeep(options.decoratorProps || {}),
    flowRegistry: import_lodash.default.cloneDeep(options.flowRegistry || {}),
    stepParams: {
      ...stepParams,
      pageTabSettings: {
        ...stepParams.pageTabSettings || {},
        tab: {
          ...((_a = stepParams.pageTabSettings) == null ? void 0 : _a.tab) || {},
          title: options.title,
          icon: options.icon,
          documentTitle: options.documentTitle
        }
      }
    },
    ...options.grid ? { subModels: { grid: options.grid } } : {}
  };
}
function buildBlockTree(options) {
  var _a, _b, _c, _d;
  const use = (0, import_catalog.resolveSupportedBlockCatalogItem)(
    {
      type: options.type,
      use: options.use,
      containerUse: options.containerUse
    },
    {
      requireCreateSupported: true
    }
  ).use;
  const defaults = buildBlockDefaults(use);
  const approvalBlockDefaults = (0, import_approval.buildApprovalBlockDefaults)(use);
  const baseStepParams = import_lodash.default.merge(
    {},
    import_lodash.default.cloneDeep(defaults.stepParams || {}),
    import_lodash.default.cloneDeep((approvalBlockDefaults == null ? void 0 : approvalBlockDefaults.stepParams) || {}),
    import_lodash.default.cloneDeep(options.stepParams || {})
  );
  const normalizedResourceInit = import_lodash.default.pickBy(import_lodash.default.cloneDeep(options.resourceInit || {}), (value) => !import_lodash.default.isUndefined(value));
  if (use === "ChartBlockModel") {
    import_lodash.default.unset(baseStepParams, "resourceSettings");
    const currentConfigure = import_lodash.default.get(baseStepParams, ["chartSettings", "configure"]) || {};
    const nextConfigure = import_lodash.default.merge(
      {
        query: {
          mode: "builder"
        },
        chart: {
          option: {
            mode: "basic"
          }
        }
      },
      import_lodash.default.cloneDeep(currentConfigure)
    );
    if (Object.keys(normalizedResourceInit).length) {
      import_lodash.default.set(nextConfigure, ["query", "mode"], "builder");
      import_lodash.default.set(
        nextConfigure,
        ["query", "collectionPath"],
        [normalizedResourceInit.dataSourceKey || import_chart_config.CHART_DEFAULT_DATA_SOURCE_KEY, normalizedResourceInit.collectionName]
      );
      import_lodash.default.unset(nextConfigure, ["query", "resource"]);
    }
    import_lodash.default.set(baseStepParams, ["chartSettings", "configure"], nextConfigure);
  } else if (Object.keys(normalizedResourceInit).length) {
    import_lodash.default.set(baseStepParams, ["resourceSettings", "init"], normalizedResourceInit);
  }
  if (options.enableDefaultSorting) {
    applyDefaultSortingIfMissing(baseStepParams, use);
  }
  const model = {
    ...use === "CalendarBlockModel" || use === "KanbanBlockModel" ? { uid: (0, import_utils.uid)() } : {},
    use,
    ...typeof (approvalBlockDefaults == null ? void 0 : approvalBlockDefaults.async) === "boolean" ? { async: approvalBlockDefaults.async } : {},
    props: import_lodash.default.merge(
      {},
      import_lodash.default.cloneDeep(defaults.props || {}),
      import_lodash.default.cloneDeep((approvalBlockDefaults == null ? void 0 : approvalBlockDefaults.props) || {}),
      import_lodash.default.cloneDeep(options.props || {})
    ),
    decoratorProps: import_lodash.default.merge(
      {},
      import_lodash.default.cloneDeep(defaults.decoratorProps || {}),
      import_lodash.default.cloneDeep((approvalBlockDefaults == null ? void 0 : approvalBlockDefaults.decoratorProps) || {}),
      import_lodash.default.cloneDeep(options.decoratorProps || {})
    ),
    stepParams: baseStepParams
  };
  const flowRegistry = import_lodash.default.merge(
    {},
    import_lodash.default.cloneDeep(defaults.flowRegistry || {}),
    import_lodash.default.cloneDeep((approvalBlockDefaults == null ? void 0 : approvalBlockDefaults.flowRegistry) || {}),
    import_lodash.default.cloneDeep(options.flowRegistry || {})
  );
  if (Object.keys(flowRegistry).length) {
    model.flowRegistry = flowRegistry;
  }
  if (approvalBlockDefaults == null ? void 0 : approvalBlockDefaults.subModels) {
    model.subModels = {};
    const gridDefaults = (0, import_service_utils.getSingleNodeSubModel)(approvalBlockDefaults.subModels.grid);
    if (gridDefaults == null ? void 0 : gridDefaults.use) {
      model.subModels.grid = {
        uid: (0, import_utils.uid)(),
        use: gridDefaults.use
      };
    }
    if (Array.isArray(approvalBlockDefaults.subModels.actions) && approvalBlockDefaults.subModels.actions.length) {
      model.subModels.actions = approvalBlockDefaults.subModels.actions.map((action) => ({
        uid: (0, import_utils.uid)(),
        ...buildActionTree({
          use: action.use,
          containerUse: use
        })
      }));
    }
  } else if (use === "TableBlockModel") {
    model.subModels = {
      columns: [buildCanonicalTableActionsColumnNode()]
    };
  } else if (["FormBlockModel", "CreateFormModel", "EditFormModel", "AssignFormModel"].includes(use)) {
    model.subModels = {
      grid: {
        uid: (0, import_utils.uid)(),
        use: use === "AssignFormModel" ? "AssignFormGridModel" : "FormGridModel"
      }
    };
  } else if (use === "DetailsBlockModel") {
    model.subModels = {
      grid: {
        uid: (0, import_utils.uid)(),
        use: "DetailsGridModel"
      }
    };
  } else if (use === "FilterFormBlockModel") {
    model.subModels = {
      grid: {
        uid: (0, import_utils.uid)(),
        use: "FilterFormGridModel"
      }
    };
  } else if (use === "ListBlockModel") {
    model.subModels = {
      item: {
        uid: (0, import_utils.uid)(),
        use: "ListItemModel",
        subModels: {
          grid: {
            uid: (0, import_utils.uid)(),
            use: "DetailsGridModel"
          }
        }
      }
    };
  } else if (use === "GridCardBlockModel") {
    model.subModels = {
      item: {
        uid: (0, import_utils.uid)(),
        use: "GridCardItemModel",
        subModels: {
          grid: {
            uid: (0, import_utils.uid)(),
            use: "DetailsGridModel"
          }
        }
      }
    };
  } else if (use === "KanbanBlockModel") {
    const blockUid = model.uid || (0, import_utils.uid)();
    model.uid = blockUid;
    const quickCreatePopupSettings = resolvePersistableModelStepParamsOrLegacyObject(
      model,
      ["kanbanSettings", "popup"],
      (_a = model.props) == null ? void 0 : _a.quickCreatePopupSettings
    ) || normalizeInitialKanbanPopupSettingsFromProps(KANBAN_QUICK_CREATE_ACTION_KEY, model.props);
    const cardPopupSettings = extractPersistableModelStepParamsOrLegacyObject(
      model,
      KANBAN_BLOCK_CARD_POPUP_STEP_PARAMS_PATH,
      (_b = model.props) == null ? void 0 : _b.cardPopupSettings
    ) || normalizeInitialKanbanPopupSettingsFromProps(KANBAN_CARD_VIEW_ACTION_KEY, model.props);
    persistModelPopupStepParams(model, ["kanbanSettings", "popup"], quickCreatePopupSettings);
    if (model.props) {
      delete model.props.quickCreatePopupSettings;
      delete model.props.cardPopupSettings;
      for (const propKey of KANBAN_LEGACY_QUICK_CREATE_POPUP_PROP_KEYS) {
        delete model.props[propKey];
      }
      for (const propKey of KANBAN_LEGACY_PARENT_CARD_POPUP_PROP_KEYS) {
        delete model.props[propKey];
      }
    }
    model.subModels = {
      item: {
        uid: (0, import_utils.uid)(),
        use: "KanbanCardItemModel",
        ...cardPopupSettings && import_lodash.default.isPlainObject(cardPopupSettings) ? {
          stepParams: {
            cardSettings: {
              popup: import_lodash.default.cloneDeep(cardPopupSettings)
            }
          }
        } : {},
        subModels: {
          grid: {
            uid: (0, import_utils.uid)(),
            use: "DetailsGridModel"
          }
        }
      },
      [KANBAN_QUICK_CREATE_ACTION_KEY]: buildKanbanPopupActionNode({
        actionKey: KANBAN_QUICK_CREATE_ACTION_KEY,
        blockUid,
        resourceInit: normalizedResourceInit,
        popupSettings: quickCreatePopupSettings
      }),
      [KANBAN_CARD_VIEW_ACTION_KEY]: buildKanbanPopupActionNode({
        actionKey: KANBAN_CARD_VIEW_ACTION_KEY,
        blockUid,
        resourceInit: normalizedResourceInit,
        popupSettings: cardPopupSettings
      })
    };
  } else if (use === "CalendarBlockModel") {
    const blockUid = model.uid || (0, import_utils.uid)();
    model.uid = blockUid;
    const quickCreatePopupSettings = resolveModelStepParamsOrLegacyObject(
      model,
      ["calendarSettings", "quickCreatePopupSettings"],
      (_c = model.props) == null ? void 0 : _c.quickCreatePopupSettings
    );
    const eventPopupSettings = resolveModelStepParamsOrLegacyObject(
      model,
      ["calendarSettings", "eventPopupSettings"],
      (_d = model.props) == null ? void 0 : _d.eventPopupSettings
    );
    persistModelPopupStepParams(model, ["calendarSettings", "quickCreatePopupSettings"], quickCreatePopupSettings);
    persistModelPopupStepParams(model, ["calendarSettings", "eventPopupSettings"], eventPopupSettings);
    if (model.props) {
      delete model.props.quickCreatePopupSettings;
      delete model.props.eventPopupSettings;
    }
    model.subModels = {
      [CALENDAR_QUICK_CREATE_ACTION_KEY]: buildCalendarPopupActionNode({
        actionKey: CALENDAR_QUICK_CREATE_ACTION_KEY,
        blockUid,
        resourceInit: normalizedResourceInit,
        popupSettings: quickCreatePopupSettings
      }),
      [CALENDAR_EVENT_VIEW_ACTION_KEY]: buildCalendarPopupActionNode({
        actionKey: CALENDAR_EVENT_VIEW_ACTION_KEY,
        blockUid,
        resourceInit: normalizedResourceInit,
        popupSettings: eventPopupSettings
      })
    };
  } else if (use === "CommentsBlockModel") {
    model.subModels = {
      items: [
        {
          uid: (0, import_utils.uid)(),
          use: "CommentItemModel"
        }
      ]
    };
  }
  return assignClientKeysToUids(model, {});
}
function buildKanbanPopupActionNode(options) {
  const actionUid = options.actionKey === KANBAN_QUICK_CREATE_ACTION_KEY ? `${options.blockUid}-quick-create-action` : `${options.blockUid}-card-view-action`;
  return {
    uid: actionUid,
    use: options.actionKey === KANBAN_QUICK_CREATE_ACTION_KEY ? "KanbanQuickCreateActionModel" : "KanbanCardViewActionModel",
    stepParams: {
      popupSettings: {
        openView: buildKanbanPopupOpenView({
          actionUid,
          resourceInit: options.resourceInit,
          popupSettings: options.popupSettings
        })
      }
    }
  };
}
function buildKanbanPopupOpenView(options) {
  return (0, import_hidden_popup_contract.buildHiddenPopupOpenView)({
    actionUid: options.actionUid,
    resourceInit: options.resourceInit,
    popupSettings: options.popupSettings,
    normalizePopupSettings: normalizeInitialKanbanPopupSettings
  });
}
function buildCalendarPopupActionNode(options) {
  const actionUid = `${options.blockUid}-${options.actionKey}`;
  return {
    uid: actionUid,
    use: options.actionKey === CALENDAR_QUICK_CREATE_ACTION_KEY ? "CalendarQuickCreateActionModel" : "CalendarEventViewActionModel",
    stepParams: {
      popupSettings: {
        openView: buildCalendarPopupOpenView({
          actionUid,
          resourceInit: options.resourceInit,
          popupSettings: options.popupSettings
        })
      }
    }
  };
}
function buildCalendarPopupOpenView(options) {
  return (0, import_hidden_popup_contract.buildHiddenPopupOpenView)(options);
}
function buildPopupPageTree(options) {
  const pageUid = options.pageUid || (0, import_utils.uid)();
  const tabUid = options.tabUid || (0, import_utils.uid)();
  const gridUid = options.gridUid || (0, import_utils.uid)();
  const displayTitle = options.displayTitle === true;
  const enableTabs = options.enableTabs !== false;
  const tabTitle = options.tabTitle || '{{t("Details")}}';
  return {
    uid: pageUid,
    use: "ChildPageModel",
    props: {
      ...options.pageTitle ? { title: options.pageTitle } : {},
      displayTitle,
      enableTabs
    },
    stepParams: {
      pageSettings: {
        general: {
          ...options.pageTitle ? { title: options.pageTitle } : {},
          displayTitle,
          enableTabs
        }
      }
    },
    subModels: {
      tabs: [
        {
          uid: tabUid,
          use: "ChildPageTabModel",
          props: {
            title: tabTitle
          },
          stepParams: {
            pageTabSettings: {
              tab: {
                title: tabTitle
              }
            }
          },
          subModels: {
            grid: {
              uid: gridUid,
              use: "BlockGridModel"
            }
          }
        }
      ]
    }
  };
}
function buildFieldTree(params) {
  const wrapperUid = params.uid || (0, import_utils.uid)();
  const innerUid = params.innerUid || (0, import_utils.uid)();
  const fieldDefaults = getStandaloneFieldDefaults(params.fieldUse);
  const approvalTree = (0, import_approval.buildApprovalFieldTree)({
    ...params,
    uid: wrapperUid,
    innerUid,
    fieldDefaults
  });
  if (approvalTree) {
    return {
      wrapperUid: approvalTree.wrapperUid,
      innerUid: approvalTree.innerUid,
      model: approvalTree.model
    };
  }
  const initPayload = import_lodash.default.pickBy(
    {
      dataSourceKey: params.dataSourceKey,
      collectionName: params.collectionName,
      fieldPath: params.fieldPath,
      ...params.associationPathName ? { associationPathName: params.associationPathName } : {}
    },
    (value) => !import_lodash.default.isUndefined(value)
  );
  const stepParams = {
    fieldSettings: {
      init: initPayload
    }
  };
  if (params.filterFormInit) {
    stepParams.filterFormItemSettings = {
      init: params.filterFormInit
    };
  }
  return {
    wrapperUid,
    innerUid,
    model: {
      uid: wrapperUid,
      use: params.wrapperUse,
      props: import_lodash.default.cloneDeep(params.wrapperProps || {}),
      stepParams,
      subModels: {
        field: {
          uid: innerUid,
          use: params.fieldUse,
          props: import_lodash.default.cloneDeep(params.fieldProps || {}),
          stepParams: import_lodash.default.merge(
            {},
            fieldDefaults.stepParams || {},
            import_lodash.default.cloneDeep({
              fieldSettings: {
                init: initPayload
              }
            })
          ),
          ...fieldDefaults.subModels ? { subModels: import_lodash.default.cloneDeep(fieldDefaults.subModels) } : {}
        }
      }
    }
  };
}
function buildStandaloneFieldNode(options) {
  const defaults = getStandaloneFieldDefaults(options.use);
  return {
    uid: options.uid || (0, import_utils.uid)(),
    use: options.use,
    props: import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.props || {}), import_lodash.default.cloneDeep(options.props || {})),
    decoratorProps: import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.decoratorProps || {}), import_lodash.default.cloneDeep(options.decoratorProps || {})),
    stepParams: import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.stepParams || {}), import_lodash.default.cloneDeep(options.stepParams || {}))
  };
}
function buildActionTree(options) {
  var _a;
  const catalogItem = (0, import_catalog.resolveSupportedActionCatalogItem)(
    {
      type: options.type,
      use: options.use,
      containerUse: options.containerUse
    },
    {
      requireCreateSupported: true
    }
  );
  const use = catalogItem.use;
  const defaults = buildActionDefaults({
    use,
    catalogItem,
    containerUse: options.containerUse,
    resourceInit: options.resourceInit
  });
  const requestedProps = options.props;
  const requestedButtonGeneral = import_lodash.default.get(options.stepParams, ["buttonSettings", "general"]);
  const stripImplicitTitle = shouldStripImplicitIconOnlyActionTitle(requestedProps, requestedButtonGeneral);
  const props = import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.props || {}), import_lodash.default.cloneDeep(options.props || {}));
  if (stripImplicitTitle) {
    delete props.title;
  }
  const stepParams = import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.stepParams || {}), import_lodash.default.cloneDeep(options.stepParams || {}));
  if (import_lodash.default.isPlainObject((_a = stepParams == null ? void 0 : stepParams.buttonSettings) == null ? void 0 : _a.general)) {
    stepParams.buttonSettings.general = import_lodash.default.merge({}, stepParams.buttonSettings.general, pickButtonGeneralProps(props));
    if (stripImplicitTitle) {
      delete stepParams.buttonSettings.general.title;
    }
  }
  return {
    use,
    props,
    decoratorProps: import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.decoratorProps || {}), import_lodash.default.cloneDeep(options.decoratorProps || {})),
    stepParams,
    flowRegistry: import_lodash.default.merge({}, import_lodash.default.cloneDeep(defaults.flowRegistry || {}), import_lodash.default.cloneDeep(options.flowRegistry || {})),
    ...defaults.subModels ? { subModels: import_lodash.default.cloneDeep(defaults.subModels) } : {}
  };
}
function buildCanonicalTableActionsColumnNode(options = {}) {
  return {
    uid: options.uid || (0, import_utils.uid)(),
    use: "TableActionsColumnModel",
    props: import_lodash.default.cloneDeep(options.props || {}),
    decoratorProps: import_lodash.default.cloneDeep(options.decoratorProps || {}),
    stepParams: import_lodash.default.merge(
      {},
      {
        tableColumnSettings: {
          title: {
            title: '{{t("Actions")}}'
          }
        }
      },
      import_lodash.default.cloneDeep(options.stepParams || {})
    ),
    flowRegistry: import_lodash.default.cloneDeep(options.flowRegistry || {})
  };
}
function pickButtonGeneralProps(props) {
  return import_lodash.default.pickBy(
    import_lodash.default.pick(props || {}, ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color"]),
    (value) => !import_lodash.default.isUndefined(value)
  );
}
function shouldStripImplicitIconOnlyActionTitle(props, buttonGeneral) {
  const hasRequestedOnlyIcon = import_lodash.default.isPlainObject(props) && Object.prototype.hasOwnProperty.call(props, "iconOnly") && props.iconOnly === true || import_lodash.default.isPlainObject(buttonGeneral) && Object.prototype.hasOwnProperty.call(buttonGeneral, "iconOnly") && buttonGeneral.iconOnly === true;
  const hasRequestedTitle = import_lodash.default.isPlainObject(props) && Object.prototype.hasOwnProperty.call(props, "title") || import_lodash.default.isPlainObject(buttonGeneral) && Object.prototype.hasOwnProperty.call(buttonGeneral, "title");
  return hasRequestedOnlyIcon && !hasRequestedTitle;
}
function assignClientKeysToUids(spec, clientKeyToUid) {
  const next = import_lodash.default.cloneDeep(spec);
  const walk = (node) => {
    if (!node.uid) {
      node.uid = (0, import_utils.uid)();
    }
    if (node.clientKey) {
      clientKeyToUid[node.clientKey] = node.uid;
    }
    Object.values(node.subModels || {}).forEach((value) => {
      import_lodash.default.castArray(value).forEach((child) => walk(child));
    });
  };
  walk(next);
  return next;
}
function buildActionDefaults(options) {
  var _a, _b, _c;
  if (options.use === AI_EMPLOYEE_ACTION_USE) {
    return {
      props: {
        style: import_lodash.default.cloneDeep(AI_EMPLOYEE_DEFAULT_STYLE)
      },
      stepParams: {}
    };
  }
  const approvalDefaults = (0, import_approval.buildApprovalActionDefaults)(options.use);
  const readonlyCalendarAction = CALENDAR_READONLY_ACTION_MODEL_USES.has(options.use);
  const props = import_lodash.default.merge(
    {},
    inferActionDefaultProps(options.use, options.catalogItem.scope),
    (approvalDefaults == null ? void 0 : approvalDefaults.props) || {}
  );
  const normalizedProps = applyContainerActionStyle(props, options.containerUse);
  const stepParams = import_lodash.default.merge(
    {},
    import_lodash.default.cloneDeep((approvalDefaults == null ? void 0 : approvalDefaults.stepParams) || {}),
    readonlyCalendarAction ? {} : {
      buttonSettings: {
        general: pickButtonGeneralProps(normalizedProps)
      }
    }
  );
  const subModels = import_lodash.default.cloneDeep((approvalDefaults == null ? void 0 : approvalDefaults.subModels) || {});
  if (approvalDefaults) {
    return {
      props: normalizedProps,
      stepParams,
      ...Object.keys(subModels).length ? { subModels } : {}
    };
  }
  if ([
    "AddNewActionModel",
    "ViewActionModel",
    "EditActionModel",
    "PopupCollectionActionModel",
    "DuplicateActionModel",
    "AddChildActionModel",
    "MailSendActionModel"
  ].includes(options.use)) {
    const popupSourceId = inferPopupActionSourceId(options.resourceInit);
    stepParams.popupSettings = {
      openView: {
        mode: "drawer",
        size: "medium",
        pageModelClass: "ChildPageModel",
        ...((_a = options.resourceInit) == null ? void 0 : _a.dataSourceKey) ? { dataSourceKey: options.resourceInit.dataSourceKey } : {},
        ...((_b = options.resourceInit) == null ? void 0 : _b.collectionName) ? { collectionName: options.resourceInit.collectionName } : {},
        ...((_c = options.resourceInit) == null ? void 0 : _c.associationName) ? { associationName: options.resourceInit.associationName } : {},
        ...popupSourceId ? { sourceId: popupSourceId } : {}
      }
    };
  }
  if (options.use === "DeleteActionModel" || options.use === "BulkDeleteActionModel") {
    stepParams.deleteSettings = {
      confirm: {
        enable: true,
        title: '{{t("Delete record")}}',
        content: '{{t("Are you sure you want to delete it?")}}'
      }
    };
  }
  if (options.use === "DeleteCommentActionModel") {
    stepParams.deleteSettings = {
      confirm: {
        enable: true,
        title: '{{t("Delete record")}}',
        content: '{{t("Are you sure you want to delete it?")}}'
      }
    };
  }
  if (options.use === "FormSubmitActionModel") {
    stepParams.submitSettings = {
      confirm: {
        enable: false,
        title: '{{t("Submit record")}}',
        content: '{{t("Are you sure you want to save it?")}}'
      }
    };
  }
  if (["UpdateRecordActionModel", "BulkUpdateActionModel"].includes(options.use)) {
    stepParams.assignSettings = {
      confirm: {
        enable: false,
        title: options.use === "BulkUpdateActionModel" ? '{{t("Bulk update")}}' : '{{t("Perform the Update record")}}',
        content: '{{t("Are you sure you want to perform the Update record action?")}}'
      },
      assignFieldValues: {
        assignedValues: {}
      }
    };
    stepParams.apply = {
      apply: {
        assignedValues: {}
      }
    };
    subModels.assignForm = {
      uid: (0, import_utils.uid)(),
      use: "AssignFormModel",
      stepParams: {
        resourceSettings: {
          init: import_lodash.default.cloneDeep(options.resourceInit || {})
        }
      },
      subModels: {
        grid: {
          uid: (0, import_utils.uid)(),
          use: "AssignFormGridModel"
        }
      }
    };
  }
  if (JS_ACTION_DEFAULT_CODE_BY_USE[options.use] !== void 0) {
    stepParams.clickSettings = buildRunJsStepParams(JS_ACTION_DEFAULT_CODE_BY_USE[options.use]);
  }
  if (options.use === "JSItemActionModel") {
    stepParams.jsSettings = buildRunJsStepParams(JS_ITEM_ACTION_DEFAULT_CODE);
  }
  return {
    props: normalizedProps,
    stepParams,
    ...Object.keys(subModels).length ? { subModels } : {}
  };
}
function inferPopupActionSourceId(resourceInit) {
  if (!(resourceInit == null ? void 0 : resourceInit.associationName)) {
    return void 0;
  }
  if (!Object.prototype.hasOwnProperty.call(resourceInit, "sourceId")) {
    return "{{ctx.view.inputArgs.sourceId}}";
  }
  const sourceId = typeof (resourceInit == null ? void 0 : resourceInit.sourceId) === "string" ? resourceInit.sourceId.trim() : resourceInit == null ? void 0 : resourceInit.sourceId;
  if (!sourceId) {
    return void 0;
  }
  if (sourceId === "{{ctx.view.inputArgs.filterByTk}}") {
    return "{{ctx.view.inputArgs.sourceId}}";
  }
  return sourceId;
}
function inferActionDefaultProps(use, scope) {
  const map = {
    AddNewActionModel: {
      type: "primary",
      title: '{{t("Add new")}}',
      icon: "PlusOutlined"
    },
    ViewActionModel: {
      type: "link",
      title: '{{t("View")}}',
      icon: "EyeOutlined"
    },
    EditActionModel: {
      title: '{{t("Edit")}}',
      icon: "EditOutlined"
    },
    PopupCollectionActionModel: {
      title: '{{t("Popup")}}',
      icon: "ExportOutlined"
    },
    DeleteActionModel: {
      type: "link",
      title: '{{t("Delete")}}',
      icon: "DeleteOutlined"
    },
    EditCommentActionModel: {
      type: "link",
      title: '{{t("Edit")}}'
    },
    DeleteCommentActionModel: {
      type: "link",
      title: '{{t("Delete")}}'
    },
    QuoteReplyActionModel: {
      type: "link",
      title: '{{t("Quote reply", { ns: "comments" })}}'
    },
    UpdateRecordActionModel: {
      type: "link",
      title: '{{t("Update record")}}',
      icon: "EditOutlined"
    },
    BulkUpdateActionModel: {
      title: '{{t("Bulk update")}}',
      icon: "EditOutlined"
    },
    FilterActionModel: {
      title: '{{t("Filter")}}',
      icon: "FilterOutlined"
    },
    RefreshActionModel: {
      title: '{{t("Refresh")}}',
      icon: "ReloadOutlined"
    },
    RecordHistoryExpandActionModel: {
      title: '{{t("Expand all")}}',
      icon: "NodeExpandOutlined"
    },
    RecordHistoryCollapseActionModel: {
      title: '{{t("Collapse all")}}',
      icon: "NodeCollapseOutlined"
    },
    ExpandCollapseActionModel: {
      icon: "DownOutlined"
    },
    BulkDeleteActionModel: {
      title: "",
      tooltip: '{{t("Delete")}}',
      icon: "DeleteOutlined",
      iconOnly: true,
      position: "right"
    },
    BulkEditActionModel: {
      title: '{{t("Bulk edit")}}',
      icon: "EditOutlined"
    },
    ExportActionModel: {
      title: '{{t("Export")}}',
      icon: "DownloadOutlined"
    },
    ExportAttachmentActionModel: {
      title: '{{t("Export attachments")}}',
      icon: "DownloadOutlined"
    },
    ImportActionModel: {
      title: '{{t("Import")}}',
      icon: "UploadOutlined"
    },
    LinkActionModel: {
      type: "link",
      title: '{{t("Link")}}'
    },
    UploadActionModel: {
      title: '{{t("Upload")}}',
      icon: "UploadOutlined"
    },
    DuplicateActionModel: {
      type: "link",
      title: '{{t("Duplicate")}}',
      icon: "CopyOutlined"
    },
    AddChildActionModel: {
      type: "link",
      title: '{{t("Add child")}}',
      icon: "PlusOutlined"
    },
    TemplatePrintCollectionActionModel: {
      title: '{{t("Template print", { ns: "@nocobase/plugin-action-template-print" })}}',
      icon: "PrinterOutlined"
    },
    TemplatePrintRecordActionModel: {
      type: "link",
      title: '{{t("Template print", { ns: "@nocobase/plugin-action-template-print" })}}',
      icon: "PrinterOutlined"
    },
    CollectionTriggerWorkflowActionModel: {
      title: '{{t("Trigger workflow", { ns: "@nocobase/plugin-workflow-custom-action-trigger" })}}',
      icon: "PlayCircleOutlined"
    },
    RecordTriggerWorkflowActionModel: {
      type: "link",
      title: '{{t("Trigger workflow", { ns: "@nocobase/plugin-workflow-custom-action-trigger" })}}',
      icon: "PlayCircleOutlined"
    },
    FormTriggerWorkflowActionModel: {
      title: '{{t("Trigger workflow", { ns: "@nocobase/plugin-workflow-custom-action-trigger" })}}',
      icon: "PlayCircleOutlined"
    },
    WorkbenchTriggerWorkflowActionModel: {
      title: '{{t("Trigger global workflow", { ns: "@nocobase/plugin-workflow-custom-action-trigger" })}}',
      icon: "PlayCircleOutlined"
    },
    MailSendActionModel: {
      title: '{{t("Compose email", { ns: ["@nocobase/plugin-email-manager", "client"] })}}',
      icon: "MailOutlined"
    },
    FormSubmitActionModel: {
      title: '{{t("Submit")}}',
      type: "primary",
      htmlType: "submit"
    },
    FilterFormSubmitActionModel: {
      title: '{{t("Filter")}}',
      type: "primary"
    },
    FilterFormResetActionModel: {
      title: '{{t("Reset")}}'
    },
    FilterFormCollapseActionModel: {
      type: "link",
      title: '{{t("Collapse button")}}'
    },
    CalendarTodayActionModel: {
      type: "default",
      title: '{{t("Today", { ns: "calendar" })}}'
    },
    CalendarNavActionModel: {},
    CalendarTitleActionModel: {},
    CalendarViewSelectActionModel: {},
    JSCollectionActionModel: {
      title: '{{t("JS action")}}',
      icon: "JavaScriptOutlined"
    },
    JSRecordActionModel: {
      type: "link",
      title: '{{t("JS action")}}',
      icon: "JavaScriptOutlined"
    },
    JSFormActionModel: {
      title: '{{t("JS action")}}',
      icon: "JavaScriptOutlined"
    },
    JSItemActionModel: {
      title: '{{t("JS item")}}',
      icon: "JavaScriptOutlined"
    },
    FilterFormJSActionModel: {
      title: '{{t("JS action")}}',
      icon: "JavaScriptOutlined"
    },
    JSActionModel: {
      type: "default",
      title: '{{t("JS action")}}',
      icon: "JavaScriptOutlined"
    }
  };
  return import_lodash.default.cloneDeep(
    map[use] || {
      title: humanizeActionTitle(use),
      ...scope === "record" ? { type: "link" } : { type: "default" }
    }
  );
}
function applyContainerActionStyle(props, containerUse) {
  if (["TableActionsColumnModel", "ListItemModel", "GridCardItemModel", "CommentItemModel"].includes(
    String(containerUse || "").trim()
  )) {
    return {
      ...props,
      type: "link",
      icon: null
    };
  }
  if (containerUse === "DetailsBlockModel") {
    return {
      ...props,
      type: "default"
    };
  }
  return props;
}
const BLOCK_DEFAULT_SORTING_PATH_BY_USE = {
  KanbanBlockModel: ["kanbanSettings", "defaultSorting", "sort"],
  TreeBlockModel: ["treeSettings", "defaultSorting", "sort"],
  TableBlockModel: ["tableSettings", "defaultSorting", "sort"],
  DetailsBlockModel: ["detailsSettings", "defaultSorting", "sort"],
  ListBlockModel: ["listSettings", "defaultSorting", "sort"],
  GridCardBlockModel: ["GridCardSettings", "defaultSorting", "sort"],
  MapBlockModel: ["createMapBlock", "lineSort", "sort"]
};
function applyDefaultSortingIfMissing(stepParams, use) {
  const path = BLOCK_DEFAULT_SORTING_PATH_BY_USE[use];
  if (!path) {
    return;
  }
  const currentSorting = import_lodash.default.get(stepParams, path);
  if (Array.isArray(currentSorting) || import_lodash.default.isNull(currentSorting) || import_lodash.default.isUndefined(currentSorting)) {
    if (!import_lodash.default.has(stepParams, path) || import_lodash.default.isNull(currentSorting) || import_lodash.default.isUndefined(currentSorting)) {
      import_lodash.default.set(stepParams, path, import_lodash.default.cloneDeep(import_public_compatibility.FLOW_SURFACE_DEFAULT_SORTING));
    }
  }
}
function buildBlockDefaults(use) {
  if (use === "JSBlockModel") {
    return {
      stepParams: {
        jsSettings: buildRunJsStepParams(JS_BLOCK_DEFAULT_CODE)
      }
    };
  }
  if (use === "ChartBlockModel") {
    return {
      stepParams: {
        chartSettings: {
          configure: {
            query: {
              mode: "builder"
            },
            chart: {
              option: {
                mode: "basic"
              }
            }
          }
        }
      }
    };
  }
  if (use === "CalendarBlockModel") {
    return {
      props: {
        fieldNames: {
          id: "id"
        },
        defaultView: "month",
        enableQuickCreateEvent: true,
        weekStart: 1
      },
      stepParams: {
        cardSettings: {
          blockHeight: {
            heightMode: "fullHeight"
          }
        }
      }
    };
  }
  if (use === "KanbanBlockModel") {
    return {
      stepParams: {
        cardSettings: {
          blockHeight: {
            heightMode: "fullHeight"
          }
        }
      }
    };
  }
  if (use === "TreeBlockModel") {
    return {
      props: {
        searchable: true,
        defaultExpandAll: false,
        includeDescendants: true
      }
    };
  }
  if (use === "TableBlockModel") {
    return {};
  }
  if (use === "DetailsBlockModel") {
    return {};
  }
  if (use === "ListBlockModel") {
    return {};
  }
  if (use === "GridCardBlockModel") {
    return {};
  }
  if (use === "MapBlockModel") {
    return {};
  }
  return {};
}
function getStandaloneFieldDefaults(use) {
  switch (use) {
    case "PopupSubTableFieldModel":
      return {
        subModels: {
          subTableColumns: [
            {
              use: "PopupSubTableActionsColumnModel",
              subModels: {
                actions: [
                  {
                    use: "PopupSubTableEditActionModel"
                  },
                  {
                    use: "PopupSubTableRemoveActionModel"
                  }
                ]
              }
            }
          ]
        }
      };
    case "JSFieldModel":
      return {
        stepParams: {
          jsSettings: buildRunJsStepParams(JS_FIELD_DEFAULT_CODE)
        }
      };
    case "JSEditableFieldModel":
      return {
        stepParams: {
          jsSettings: buildRunJsStepParams(JS_EDITABLE_FIELD_DEFAULT_CODE)
        }
      };
    case "JSColumnModel":
      return {
        props: {
          title: '{{t("JS column")}}'
        },
        stepParams: {
          tableColumnSettings: {
            title: {
              title: '{{t("JS column")}}'
            }
          },
          jsSettings: buildRunJsStepParams(JS_COLUMN_DEFAULT_CODE)
        }
      };
    case "JSItemModel":
      return {
        stepParams: {
          jsSettings: buildRunJsStepParams(JS_ITEM_DEFAULT_CODE)
        }
      };
    case "DividerItemModel":
      return {
        props: {
          label: '{{t("Divider")}}',
          orientation: "left"
        }
      };
    default:
      return {};
  }
}
function humanizeActionTitle(use) {
  const normalized = String(use || "").replace(/ActionModel$/, "").replace(/(Collection|Record|Form|Workbench)$/, "");
  const title = import_lodash.default.startCase(normalized).replace(/\bJs\b/g, "JS").trim() || "Action";
  return `{{t(${JSON.stringify(title)})}}`;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  assignClientKeysToUids,
  buildActionTree,
  buildBlockTree,
  buildCanonicalTableActionsColumnNode,
  buildFieldTree,
  buildPersistedRootPageModel,
  buildPopupPageTree,
  buildStandaloneFieldNode,
  buildSyntheticRootPageTabModel,
  getStandaloneFieldDefaults
});
