openxiangda 1.0.134 → 1.0.136
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/lib/cli.js +947 -16
- package/lib/design-gates.js +40 -10
- package/lib/sdd.js +777 -0
- package/lib/workspace-init.js +3 -0
- package/openxiangda-skills/SKILL.md +11 -1
- package/openxiangda-skills/references/best-practices.md +32 -5
- package/openxiangda-skills/references/openxiangda-api.md +32 -6
- package/openxiangda-skills/references/pages/page-sdk.md +3 -0
- package/openxiangda-skills/references/pages/publish-flow.md +16 -0
- package/openxiangda-skills/references/permission-design-patterns.md +216 -0
- package/openxiangda-skills/references/permissions-settings.md +58 -0
- package/openxiangda-skills/references/platform-data-model.md +19 -4
- package/openxiangda-skills/references/resource-manifest-cheatsheet.md +32 -1
- package/openxiangda-skills/skills/openxiangda-architecture-design/SKILL.md +8 -0
- package/openxiangda-skills/skills/openxiangda-core/SKILL.md +2 -0
- package/openxiangda-skills/skills/openxiangda-permission-settings/SKILL.md +38 -1
- package/package.json +2 -1
- package/packages/sdk/dist/{ProcessPreview-Dfc4-wIq.d.mts → ProcessPreview-Ci8_UsbN.d.mts} +4 -0
- package/packages/sdk/dist/{ProcessPreview-Dfc4-wIq.d.ts → ProcessPreview-Ci8_UsbN.d.ts} +4 -0
- package/packages/sdk/dist/build/index.cjs.map +1 -1
- package/packages/sdk/dist/build/index.d.mts +7 -0
- package/packages/sdk/dist/build/index.d.ts +7 -0
- package/packages/sdk/dist/build/index.mjs.map +1 -1
- package/packages/sdk/dist/components/index.cjs +32 -4
- package/packages/sdk/dist/components/index.cjs.map +1 -1
- package/packages/sdk/dist/components/index.d.mts +8 -2
- package/packages/sdk/dist/components/index.d.ts +8 -2
- package/packages/sdk/dist/components/index.mjs +32 -4
- package/packages/sdk/dist/components/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/index.cjs +181 -28
- package/packages/sdk/dist/runtime/index.cjs.map +1 -1
- package/packages/sdk/dist/runtime/index.d.mts +2 -2
- package/packages/sdk/dist/runtime/index.d.ts +2 -2
- package/packages/sdk/dist/runtime/index.mjs +181 -28
- package/packages/sdk/dist/runtime/index.mjs.map +1 -1
- package/packages/sdk/dist/runtime/react.cjs +152 -25
- package/packages/sdk/dist/runtime/react.cjs.map +1 -1
- package/packages/sdk/dist/runtime/react.d.mts +57 -4
- package/packages/sdk/dist/runtime/react.d.ts +57 -4
- package/packages/sdk/dist/runtime/react.mjs +152 -25
- package/packages/sdk/dist/runtime/react.mjs.map +1 -1
- package/templates/openxiangda-react-spa/.cursor/rules/openxiangda.mdc +8 -1
- package/templates/openxiangda-react-spa/.qoder/rules/openxiangda.md +8 -1
- package/templates/openxiangda-react-spa/AGENTS.md +9 -1
- package/templates/openxiangda-react-spa/app-workspace.config.ts +14 -0
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-resources.mdc +5 -1
- package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda.mdc +7 -1
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-resources.md +6 -0
- package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda.md +7 -1
- package/templates/sy-lowcode-app-workspace/AGENTS.md +10 -1
- package/templates/sy-lowcode-app-workspace/app-workspace.config.ts +14 -0
- package/templates/sy-lowcode-app-workspace/examples/best-practices/README.md +3 -0
- package/templates/sy-lowcode-app-workspace/examples/best-practices/access-governance.md +239 -0
- package/templates/sy-lowcode-app-workspace/examples/best-practices/catalog.json +6 -0
- package/templates/sy-lowcode-app-workspace/examples/best-practices/decision-guide.md +25 -1
- package/templates/sy-lowcode-app-workspace/src/types/app-workspace.types.ts +12 -0
|
@@ -21,6 +21,7 @@ Read these supporting references when the design touches the topic:
|
|
|
21
21
|
- `references/architecture-patterns.md`
|
|
22
22
|
- `references/data-views.md`
|
|
23
23
|
- `references/permissions-settings.md`
|
|
24
|
+
- `references/permission-design-patterns.md`
|
|
24
25
|
- `references/workflow-v3.md`
|
|
25
26
|
- `references/automation-v3.md`
|
|
26
27
|
- `references/notifications.md`
|
|
@@ -66,6 +67,8 @@ Once the user confirms, hand execution to the relevant implementation skill and
|
|
|
66
67
|
- Do not default to `searchKeyWord` for broad fuzzy search. Prefer explicit searchable fields and structured `filterGroup` conditions.
|
|
67
68
|
- Do not use workflow forms for ordinary business lifecycles. Use normal forms, status fields, state machines, responsibility fields, action logs, permissions, and automations. Use workflow only for real approval semantics.
|
|
68
69
|
- Do not put sensitive authorization in page conditions only. Use page permission groups, form permission groups, backend data scope, and field access policy when data is sensitive.
|
|
70
|
+
- Do not design account/role/permission requirements without choosing a permission mode first: `managed-platform-account`, `existing-platform-user-assignment`, `static-role-permission`, or `query-param-context`.
|
|
71
|
+
- Do not treat query parameters as sensitive authorization. They may provide context, filters, or ticket input only; sensitive reads/writes still need public-access grants, roles, form permission groups, or App Function checks.
|
|
69
72
|
- Do not put repeated multi-form joins or fixed dashboard metrics into page-side loops. Use Data View when the query is reusable and read-only; choose `live` or `materialized` deliberately.
|
|
70
73
|
- Do not scatter reusable backend logic in pages or JS_CODE nodes. Use App Functions for logic shared by pages, automations, and workflows. Use JS_CODE V2 for node-local backend trigger logic.
|
|
71
74
|
- Do not design raw native form controls for AI-authored workspace code. Use OpenXiangda platform form components first, then Ant Design / antd-mobile wrappers.
|
|
@@ -103,6 +106,9 @@ Resolve these before finalizing:
|
|
|
103
106
|
|
|
104
107
|
- Data volume, pagination, searchable fields, sort fields, and expected indexes.
|
|
105
108
|
- Role model, data sensitivity, backend-enforced data scope, and field visibility.
|
|
109
|
+
- Account source, role membership source, permission design mode, and whether platform accounts/departments are created by the app.
|
|
110
|
+
- Which roles can manage roles, assign role members, grant role API permissions, maintain permission groups, or manage organization accounts; list the required `apiPermissionCodes`.
|
|
111
|
+
- Permission matrix for pages/routes, form submit/view/manage, data scope, field access policy, backend App Function checks, and query parameter tamper-deny tests.
|
|
106
112
|
- Which flows are status machines and which are real approvals.
|
|
107
113
|
- Report freshness: real-time live view, materialized refresh cadence, or manual snapshot.
|
|
108
114
|
- Whether dashboards and joins are bounded enough for Data View.
|
|
@@ -118,6 +124,8 @@ The final design must be decision-complete. Include:
|
|
|
118
124
|
- Architecture overview and OpenXiangda resource map.
|
|
119
125
|
- Form and field design with storage shape, hidden scope keys, searchable fields, and pagination strategy.
|
|
120
126
|
- Permission design with page groups, form groups, data scope, and field access policy.
|
|
127
|
+
- Permission mode decision with account source, role assignment source, business scope fields, hidden scalar keys, query-parameter boundary, and backend role/scope checks.
|
|
128
|
+
- Delegated role-setting design: which administrator role is first granted by a platform/app admin, which `apiPermissionCodes` it receives, and whether roles it creates can further delegate management.
|
|
121
129
|
- Page/menu/UX design, including PC/mobile and design mockup decisions.
|
|
122
130
|
- Data access and Data View plan with `live` / `materialized`, refresh, indexes, and runtime SDK calls.
|
|
123
131
|
- Status machine, workflow, automation, JS_CODE V2, and App Function plan.
|
|
@@ -19,8 +19,10 @@ description: Core OpenXiangda CLI workflow — normal-user token login, platform
|
|
|
19
19
|
openxiangda env --profile <name>
|
|
20
20
|
openxiangda auth status --profile <name>
|
|
21
21
|
openxiangda update check --json # if updateAvailable: openxiangda update install
|
|
22
|
+
openxiangda sdd context --json # high-risk changes need an approved SDD change
|
|
22
23
|
|
|
23
24
|
# 2. preview the change set (NEVER skip --dry-run on routine edits)
|
|
25
|
+
openxiangda sdd verify <change> --changed
|
|
24
26
|
openxiangda workspace publish --profile <name> --changed --dry-run
|
|
25
27
|
|
|
26
28
|
# 3. publish only what changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: openxiangda-permission-settings
|
|
3
|
-
description: Manage OpenXiangda app **roles** (角色), **page permission groups** (页面权限组 / 菜单可见), **form permission groups** (表单权限组 / 提交 / 查看 / 字段权限 / 数据范围 / 数据隔离), and **form settings** (表单设置 / 索引 / 数据管理页 / 公开访问 / public access / 分享) with profile-isolated IDs and ordinary user token permissions. Trigger on 角色 / role / 权限 / permission / 数据范围 / data scope / 字段权限 / field permission / 菜单可见 / menu visibility / 公开访问 / public access / 分享 / share, or any work touching `permission ...` / `settings ...` CLI commands or `src/resources/{roles,pagePermissionGroups,formPermissionGroups,formSettings}/`.
|
|
3
|
+
description: Manage OpenXiangda app **roles** (角色), **page permission groups** (页面权限组 / 菜单可见), **form permission groups** (表单权限组 / 提交 / 查看 / 字段权限 / 数据范围 / 数据隔离), account/role governance patterns, query-parameter authorization boundaries, and **form settings** (表单设置 / 索引 / 数据管理页 / 公开访问 / public access / 分享) with profile-isolated IDs and ordinary user token permissions. Trigger on 角色 / role / 权限 / permission / RBAC / 账号权限 / account permission / 组织账号 / organization account / 平台账号 / 数据范围 / data scope / 字段权限 / field permission / 菜单可见 / menu visibility / 公开访问 / public access / 分享 / share, or any work touching `permission ...` / `settings ...` CLI commands or `src/resources/{roles,pagePermissionGroups,formPermissionGroups,formSettings}/`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OpenXiangda Permission And Settings
|
|
@@ -12,14 +12,25 @@ description: Manage OpenXiangda app **roles** (角色), **page permission groups
|
|
|
12
12
|
- User wants to **gate form submit / view / edit / data scope / field permissions** (form permission groups).
|
|
13
13
|
- User wants to **publish a form publicly** or change form runtime settings, indexes, data-management page config.
|
|
14
14
|
- User asks about **dynamic role governance** (role maintenance form synced to platform via automation).
|
|
15
|
+
- User asks about **platform accounts, organization accounts, account-role assignment, RBAC, or query-parameter access**.
|
|
15
16
|
|
|
16
17
|
## DO / DO NOT
|
|
17
18
|
|
|
19
|
+
- ✅ Before account/role/permission design, run `openxiangda design gates --topic permissions --json` and choose one mode: `managed-platform-account`, `existing-platform-user-assignment`, `static-role-permission`, or `query-param-context`.
|
|
20
|
+
- ✅ Write a permission matrix before implementation: account source, role member source, page groups, form groups, data scope, field access policy, backend checks, query parameter boundary, and publish order.
|
|
18
21
|
- ✅ Use logical role / group codes locally; live IDs go under the active profile in `.openxiangda/state.json`.
|
|
19
22
|
- ✅ For dynamic multi-role apps, build a role maintenance form + automation/JS_CODE sync, not hardcoded role logic in page code.
|
|
20
23
|
- ✅ For permission scope keys, derive hidden scalars (`collegeScopeKey`, `classScopeKey`, `ownerDeptScopeKey`, `ownerUserScopeKey`, `roleCode`) via `valueSync` from visible select/person/department fields.
|
|
21
24
|
- ✅ Use page permission groups for entry visibility, form permission groups for real data isolation with condition-based data permissions.
|
|
25
|
+
- ✅ For app-managed platform accounts/departments, use `sdk.organization.*` / `ctx.organization.*` and require the current operator to have `app:organization:manage`.
|
|
26
|
+
- ✅ For delegated administrators such as 校区管理员, put role-setting API permissions in the role manifest with `apiPermissionCodes`; use `app:role:manage` for app role creation/member assignment/API-permission assignment, and add page/form/organization management permission codes only when needed.
|
|
27
|
+
- ✅ If a delegated administrator creates another role that can also manage accounts, roles, or permission groups, publish that new role with its own `apiPermissionCodes`.
|
|
22
28
|
- ❌ Expose raw ID text fields to users for permission scopes.
|
|
29
|
+
- ❌ Treat query parameters as sensitive authorization. They may carry context, filters, or ticket input only.
|
|
30
|
+
- ❌ Treat `PermissionBoundary`, button hiding, route hiding, or frontend role checks as the authority for sensitive data.
|
|
31
|
+
- ❌ Hardcode role strings in pages without backing roles/page groups/form groups or App Function checks.
|
|
32
|
+
- ❌ Give a user a business admin role but forget to bind `app:role:manage`, then expect role creation or role-member assignment to work.
|
|
33
|
+
- ❌ Bypass OpenXiangda SDK and call platform account/organization write APIs directly.
|
|
23
34
|
- ❌ Store platform-specific public-access IDs locally; CLI resolves by `appType + formUuid` per profile.
|
|
24
35
|
- ❌ Reuse role / permission-group IDs across profiles.
|
|
25
36
|
- ❌ Use AK/SK or legacy `/dingtalk-api/v1.0` — the logged-in user must have the matching app permission.
|
|
@@ -36,6 +47,24 @@ openxiangda workspace bind --profile dev --app-type APP_XXX
|
|
|
36
47
|
|
|
37
48
|
The logged-in user must have the matching app permission. Do not use AK/SK or legacy `/dingtalk-api/v1.0`.
|
|
38
49
|
|
|
50
|
+
For design work, also run:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
openxiangda design gates --topic permissions --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Resolve the permission mode before writing resources:
|
|
57
|
+
|
|
58
|
+
- `managed-platform-account`: the app creates/maintains platform accounts,
|
|
59
|
+
departments, and role members.
|
|
60
|
+
- `existing-platform-user-assignment`: the app selects existing platform users
|
|
61
|
+
and assigns app roles/business scopes.
|
|
62
|
+
- `static-role-permission`: fixed app roles and permission groups, no in-app
|
|
63
|
+
account governance.
|
|
64
|
+
- `query-param-context`: query parameters are only context, filters, or ticket
|
|
65
|
+
input; sensitive authorization still comes from roles, grants, form groups,
|
|
66
|
+
or App Function checks.
|
|
67
|
+
|
|
39
68
|
## Roles
|
|
40
69
|
|
|
41
70
|
Create app roles first:
|
|
@@ -53,6 +82,13 @@ openxiangda permission role-bind sales --role-id <id> --profile dev
|
|
|
53
82
|
|
|
54
83
|
For dynamic multi-role apps, do not hardcode role behavior only in page code. Create a role maintenance form and sync it to platform roles with automation / JS_CODE. Visible scope fields should be maintainable controls: personnel/department fields for people and orgs, `SelectField` / `RadioField` for enums, and `SelectField` with `optionSource.type: "linkedForm"` for records maintained by other forms. When the source form can have many records, set `remoteSearch: true` and `searchFieldId` so typing in the dropdown triggers an SDK query instead of loading every record. If form permission groups need scalar matching, derive hidden keys such as `collegeScopeKey`, `classScopeKey`, `ownerDeptScopeKey`, `ownerUserScopeKey`, and `roleCode`; do not expose raw ID text fields to users. Use page permission groups for entry visibility and form permission groups with condition-based data permissions for real data isolation.
|
|
55
84
|
|
|
85
|
+
For managed platform account governance, use organization/account forms and sync
|
|
86
|
+
functions as a closed loop: organization units, system accounts, role
|
|
87
|
+
assignments, roles resources, page groups, form groups, sync App Functions, and
|
|
88
|
+
backend role/scope checks. Platform account writes must go through
|
|
89
|
+
`sdk.organization` or `ctx.organization`; the current operator must have
|
|
90
|
+
`app:organization:manage`.
|
|
91
|
+
|
|
56
92
|
## Page Permission Groups
|
|
57
93
|
|
|
58
94
|
Page permission groups control menu/page visibility:
|
|
@@ -153,6 +189,7 @@ Do not store platform-specific public access IDs locally. The CLI resolves by `a
|
|
|
153
189
|
## References
|
|
154
190
|
|
|
155
191
|
- Permission model and examples: `references/permissions-settings.md`
|
|
192
|
+
- Account/role design modes: `references/permission-design-patterns.md`
|
|
156
193
|
- Dynamic role governance and data-isolation pattern: `references/best-practices.md`
|
|
157
194
|
- Profile-isolated IDs: `references/workspace-state.md`
|
|
158
195
|
- API fields: `references/openxiangda-api.md`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openxiangda",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.136",
|
|
4
4
|
"description": "OpenXiangda CLI, workspace build tools, runtime SDK, and form components.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"test:help-no-side-effects": "node scripts/help-no-side-effects-smoke.mjs",
|
|
74
74
|
"test:app-function-fallback": "node scripts/app-function-source-fallback-smoke.mjs",
|
|
75
75
|
"test:runtime-deploy": "node scripts/runtime-deploy-smoke.mjs",
|
|
76
|
+
"test:sdd": "node scripts/sdd-smoke.mjs",
|
|
76
77
|
"test:skill-install": "bash scripts/skill-install-smoke.sh",
|
|
77
78
|
"test:workspace-init": "bash scripts/workspace-init-smoke.sh"
|
|
78
79
|
},
|
|
@@ -316,6 +316,10 @@ interface FormEngineConfig {
|
|
|
316
316
|
navigation?: {
|
|
317
317
|
basePath?: string;
|
|
318
318
|
};
|
|
319
|
+
compatibility?: {
|
|
320
|
+
apiContracts?: 'strict' | 'legacy';
|
|
321
|
+
legacyFallbacks?: boolean;
|
|
322
|
+
};
|
|
319
323
|
effects?: FormEffect[];
|
|
320
324
|
}
|
|
321
325
|
type FormEffectConditionOperator = 'eq' | 'ne' | 'in' | 'notIn' | 'contains' | 'empty' | 'notEmpty' | 'between' | 'changed';
|
|
@@ -316,6 +316,10 @@ interface FormEngineConfig {
|
|
|
316
316
|
navigation?: {
|
|
317
317
|
basePath?: string;
|
|
318
318
|
};
|
|
319
|
+
compatibility?: {
|
|
320
|
+
apiContracts?: 'strict' | 'legacy';
|
|
321
|
+
legacyFallbacks?: boolean;
|
|
322
|
+
};
|
|
319
323
|
effects?: FormEffect[];
|
|
320
324
|
}
|
|
321
325
|
type FormEffectConditionOperator = 'eq' | 'ne' | 'in' | 'notIn' | 'contains' | 'empty' | 'notEmpty' | 'between' | 'changed';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\nexport type WorkspaceRuntimeMode = 'legacy' | 'react-spa';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n runtimeMode?: WorkspaceRuntimeMode;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string; publishLegacyBundle?: boolean };\n pages?: { dir?: string };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\nexport type WorkspaceRuntimeMode = 'legacy' | 'react-spa';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n runtimeMode?: WorkspaceRuntimeMode;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string; publishLegacyBundle?: boolean };\n pages?: { dir?: string };\n governance?: {\n sdd?: {\n enabled?: boolean;\n strictHighRisk?: boolean;\n path?: string;\n };\n };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4CO,SAAS,yBAAuD,QAAc;AACnF,SAAO;AACT;AAEA,IAAM,2BAA2B;AAEjC,SAAS,kBAAkB,UAAkB;AAC3C,QAAM,YAAsB,CAAC;AAC7B,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,aAAW,QAAQ,UAAU;AAC3B,QAAI,OAAO;AACT,iBAAW;AACX,UAAI,SAAS,MAAO,SAAQ;AAC5B;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,KAAK;AAChC,cAAQ;AACR,iBAAW;AACX;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,UAAU,GAAG;AAC/B,gBAAU,KAAK,QAAQ,KAAK,CAAC;AAC7B,gBAAU;AACV;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,MAAI,QAAQ,KAAK,EAAG,WAAU,KAAK,QAAQ,KAAK,CAAC;AACjD,SAAO;AACT;AAEA,SAAS,oBAAoB,UAAkB,QAAgB;AAC7D,MAAI,CAAC,YAAY,SAAS,SAAS,MAAM,EAAG,QAAO;AACnD,MAAI,gCAAgC,KAAK,QAAQ,EAAG,QAAO;AAC3D,MAAI,wBAAwB,KAAK,QAAQ,EAAG,QAAO;AACnD,MAAI,+BAA+B,KAAK,QAAQ,EAAG,QAAO;AAC1D,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAkB;AACjD,QAAM,UAAU,SACb,QAAQ,6BAA6B,YAAY,EACjD,QAAQ,iCAAiC,gBAAgB,EACzD,QAAQ,oDAAoD,eAAe;AAC9E,SAAO,YAAY,WAAW,OAAO;AACvC;AAEO,SAAS,oCACd,SAAS,0BACT;AACA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,KAAK,MAA2C;AAC9C,UAAI,CAAC,KAAK,SAAU;AACpB,UAAI,SAAS,KAAK;AAClB,aAAO,QAAQ;AACb,YAAI,OAAO,SAAS,YAAY,cAAc,KAAK,OAAO,IAAI,GAAG;AAC/D;AAAA,QACF;AACA,iBAAS,OAAO;AAAA,MAClB;AACA,WAAK,WAAW,MAAM;AAAA,QACpB,IAAI;AAAA,UACF,kBAAkB,KAAK,QAAQ,EAAE,QAAQ,CAAC,aAAa;AACrD,kBAAM,iBAAiB,oBAAoB,UAAU,MAAM,IACvD,WACA,GAAG,MAAM,IAAI,QAAQ;AACzB,kBAAM,YAAY,wBAAwB,cAAc;AACxD,mBAAO,YAAY,CAAC,gBAAgB,SAAS,IAAI,CAAC,cAAc;AAAA,UAClE,CAAC;AAAA,QACH;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACF;AAEC,oCAA4C,UAAU;AAEhD,IAAM,2BAA2B;","names":[]}
|
|
@@ -37,6 +37,13 @@ interface AppWorkspaceConfig {
|
|
|
37
37
|
pages?: {
|
|
38
38
|
dir?: string;
|
|
39
39
|
};
|
|
40
|
+
governance?: {
|
|
41
|
+
sdd?: {
|
|
42
|
+
enabled?: boolean;
|
|
43
|
+
strictHighRisk?: boolean;
|
|
44
|
+
path?: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
40
47
|
}
|
|
41
48
|
declare function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T;
|
|
42
49
|
declare function createOpenXiangdaNamespaceCssPlugin(prefix?: string): {
|
|
@@ -37,6 +37,13 @@ interface AppWorkspaceConfig {
|
|
|
37
37
|
pages?: {
|
|
38
38
|
dir?: string;
|
|
39
39
|
};
|
|
40
|
+
governance?: {
|
|
41
|
+
sdd?: {
|
|
42
|
+
enabled?: boolean;
|
|
43
|
+
strictHighRisk?: boolean;
|
|
44
|
+
path?: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
40
47
|
}
|
|
41
48
|
declare function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T;
|
|
42
49
|
declare function createOpenXiangdaNamespaceCssPlugin(prefix?: string): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\nexport type WorkspaceRuntimeMode = 'legacy' | 'react-spa';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n runtimeMode?: WorkspaceRuntimeMode;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string; publishLegacyBundle?: boolean };\n pages?: { dir?: string };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/build/index.ts"],"sourcesContent":["export type CssIsolation = 'namespace' | 'shadow' | 'none';\nexport type WorkspaceRuntimeMode = 'legacy' | 'react-spa';\n\nexport interface AppWorkspaceConfig {\n appType?: string;\n appName?: string;\n runtimeMode?: WorkspaceRuntimeMode;\n platformUrl?: string;\n servicePrefix?: string;\n appKey?: string;\n appSecret?: string;\n userId?: string;\n version?: string;\n buildId?: string;\n oss?: {\n region?: string;\n bucket?: string;\n accessKeyId?: string;\n accessKeySecret?: string;\n pathPrefix?: string;\n corsOrigins?: string[];\n skipCors?: boolean;\n };\n defaults?: {\n protocolVersion?: string;\n frameworkVersion?: string;\n cssIsolation?: CssIsolation;\n formMenuParentId?: string;\n formMenuIcon?: string;\n pageMenuParentId?: string;\n pageMenuIcon?: string;\n formBuilderVersion?: string;\n };\n forms?: { dir?: string; publishLegacyBundle?: boolean };\n pages?: { dir?: string };\n governance?: {\n sdd?: {\n enabled?: boolean;\n strictHighRisk?: boolean;\n path?: string;\n };\n };\n}\n\nexport function defineAppWorkspaceConfig<T extends AppWorkspaceConfig>(config: T): T {\n return config;\n}\n\nconst DEFAULT_NAMESPACE_PREFIX = '.sy-app-workspace';\n\nfunction splitCssSelectors(selector: string) {\n const selectors: string[] = [];\n let depth = 0;\n let quote = '';\n let current = '';\n for (const char of selector) {\n if (quote) {\n current += char;\n if (char === quote) quote = '';\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n current += char;\n continue;\n }\n if (char === '(' || char === '[') depth += 1;\n if (char === ')' || char === ']') depth -= 1;\n if (char === ',' && depth === 0) {\n selectors.push(current.trim());\n current = '';\n continue;\n }\n current += char;\n }\n if (current.trim()) selectors.push(current.trim());\n return selectors;\n}\n\nfunction shouldSkipNamespace(selector: string, prefix: string) {\n if (!selector || selector.includes(prefix)) return true;\n if (/^(html|body|:root)(\\b|:|\\[|$)/.test(selector)) return true;\n if (/^(@|from\\b|to\\b|\\d+%)/.test(selector)) return true;\n if (/^\\.(ant|sy-ant|anticon|adm)-/.test(selector)) return true;\n return false;\n}\n\nfunction createAntdSelectorAlias(selector: string) {\n const aliased = selector\n .replace(/(^|[^A-Za-z0-9_-])\\.ant-/g, '$1.sy-ant-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon-/g, '$1.sy-anticon-')\n .replace(/(^|[^A-Za-z0-9_-])\\.anticon(?=$|[^A-Za-z0-9_-])/g, '$1.sy-anticon');\n return aliased === selector ? null : aliased;\n}\n\nexport function createOpenXiangdaNamespaceCssPlugin(\n prefix = DEFAULT_NAMESPACE_PREFIX,\n) {\n return {\n postcssPlugin: 'openxiangda-namespace-css',\n Rule(rule: { selector?: string; parent?: any }) {\n if (!rule.selector) return;\n let parent = rule.parent;\n while (parent) {\n if (parent.type === 'atrule' && /keyframes$/i.test(parent.name)) {\n return;\n }\n parent = parent.parent;\n }\n rule.selector = Array.from(\n new Set(\n splitCssSelectors(rule.selector).flatMap((selector) => {\n const scopedSelector = shouldSkipNamespace(selector, prefix)\n ? selector\n : `${prefix} ${selector}`;\n const antdAlias = createAntdSelectorAlias(scopedSelector);\n return antdAlias ? [scopedSelector, antdAlias] : [scopedSelector];\n }),\n ),\n ).join(', ');\n },\n };\n}\n\n(createOpenXiangdaNamespaceCssPlugin as any).postcss = true;\n\nexport const createNamespaceCssPlugin = createOpenXiangdaNamespaceCssPlugin;\n"],"mappings":";AA4CO,SAAS,yBAAuD,QAAc;AACnF,SAAO;AACT;AAEA,IAAM,2BAA2B;AAEjC,SAAS,kBAAkB,UAAkB;AAC3C,QAAM,YAAsB,CAAC;AAC7B,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,aAAW,QAAQ,UAAU;AAC3B,QAAI,OAAO;AACT,iBAAW;AACX,UAAI,SAAS,MAAO,SAAQ;AAC5B;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,KAAK;AAChC,cAAQ;AACR,iBAAW;AACX;AAAA,IACF;AACA,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,SAAS,IAAK,UAAS;AAC3C,QAAI,SAAS,OAAO,UAAU,GAAG;AAC/B,gBAAU,KAAK,QAAQ,KAAK,CAAC;AAC7B,gBAAU;AACV;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,MAAI,QAAQ,KAAK,EAAG,WAAU,KAAK,QAAQ,KAAK,CAAC;AACjD,SAAO;AACT;AAEA,SAAS,oBAAoB,UAAkB,QAAgB;AAC7D,MAAI,CAAC,YAAY,SAAS,SAAS,MAAM,EAAG,QAAO;AACnD,MAAI,gCAAgC,KAAK,QAAQ,EAAG,QAAO;AAC3D,MAAI,wBAAwB,KAAK,QAAQ,EAAG,QAAO;AACnD,MAAI,+BAA+B,KAAK,QAAQ,EAAG,QAAO;AAC1D,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAkB;AACjD,QAAM,UAAU,SACb,QAAQ,6BAA6B,YAAY,EACjD,QAAQ,iCAAiC,gBAAgB,EACzD,QAAQ,oDAAoD,eAAe;AAC9E,SAAO,YAAY,WAAW,OAAO;AACvC;AAEO,SAAS,oCACd,SAAS,0BACT;AACA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,KAAK,MAA2C;AAC9C,UAAI,CAAC,KAAK,SAAU;AACpB,UAAI,SAAS,KAAK;AAClB,aAAO,QAAQ;AACb,YAAI,OAAO,SAAS,YAAY,cAAc,KAAK,OAAO,IAAI,GAAG;AAC/D;AAAA,QACF;AACA,iBAAS,OAAO;AAAA,MAClB;AACA,WAAK,WAAW,MAAM;AAAA,QACpB,IAAI;AAAA,UACF,kBAAkB,KAAK,QAAQ,EAAE,QAAQ,CAAC,aAAa;AACrD,kBAAM,iBAAiB,oBAAoB,UAAU,MAAM,IACvD,WACA,GAAG,MAAM,IAAI,QAAQ;AACzB,kBAAM,YAAY,wBAAwB,cAAc;AACxD,mBAAO,YAAY,CAAC,gBAAgB,SAAS,IAAI,CAAC,cAAc;AAAA,UAClE,CAAC;AAAA,QACH;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF;AACF;AAEC,oCAA4C,UAAU;AAEhD,IAAM,2BAA2B;","names":[]}
|
|
@@ -16183,7 +16183,23 @@ var pickFormInstanceId = (value) => {
|
|
|
16183
16183
|
if (!value) return void 0;
|
|
16184
16184
|
if (typeof value === "string") return value;
|
|
16185
16185
|
if (typeof value !== "object") return void 0;
|
|
16186
|
-
|
|
16186
|
+
const direct = value.formInstanceId || value.formInstId || value.instanceId || value.id;
|
|
16187
|
+
if (direct) return pickFormInstanceId(direct);
|
|
16188
|
+
for (const candidate of [value.result, value.data, value.raw]) {
|
|
16189
|
+
const picked = pickFormInstanceId(candidate);
|
|
16190
|
+
if (picked) return picked;
|
|
16191
|
+
}
|
|
16192
|
+
return void 0;
|
|
16193
|
+
};
|
|
16194
|
+
var getSubmitResultFormInstanceId = (submitResponse, config, submitBehavior) => {
|
|
16195
|
+
const responseId = pickFormInstanceId(submitResponse);
|
|
16196
|
+
if (responseId) return responseId;
|
|
16197
|
+
if (submitBehavior !== "create" && config.formInstanceId) {
|
|
16198
|
+
return config.formInstanceId;
|
|
16199
|
+
}
|
|
16200
|
+
throw new Error(
|
|
16201
|
+
"\u63D0\u4EA4\u63A5\u53E3\u672A\u8FD4\u56DE formInstId/formInstanceId\u3002\u4FDD\u5B58\u63A5\u53E3\u53EA\u8FD4\u56DE\u5B9E\u4F8B\u6807\u8BC6\u548C\u5DF2\u751F\u6210\u7684\u6D41\u6C34\u53F7\uFF1B\u5982\u9700\u5B8C\u6574\u6570\u636E\u3001\u516C\u5F0F\u56DE\u586B\u6216\u5176\u4ED6\u670D\u52A1\u7AEF\u5B57\u6BB5\uFF0C\u8BF7\u4FDD\u5B58\u6210\u529F\u540E\u518D\u67E5\u8BE2\u8BE6\u60C5\u3002"
|
|
16202
|
+
);
|
|
16187
16203
|
};
|
|
16188
16204
|
var normalizeFormDataForSubmit = (schema, formData) => {
|
|
16189
16205
|
const next = { ...formData };
|
|
@@ -16382,7 +16398,7 @@ var InnerFormContent = ({
|
|
|
16382
16398
|
selectedApprovers: initiatorSelectedApprovers,
|
|
16383
16399
|
initiatorSelectedApprovers
|
|
16384
16400
|
});
|
|
16385
|
-
const formInstId =
|
|
16401
|
+
const formInstId = getSubmitResultFormInstanceId(submitResponse, config, submitBehavior);
|
|
16386
16402
|
if (config.submit?.afterSubmit) {
|
|
16387
16403
|
await config.submit.afterSubmit({
|
|
16388
16404
|
formInstanceId: formInstId,
|
|
@@ -16406,6 +16422,7 @@ var InnerFormContent = ({
|
|
|
16406
16422
|
}
|
|
16407
16423
|
} catch (error) {
|
|
16408
16424
|
console.error("[FormSubmitTemplate] Submit failed:", error);
|
|
16425
|
+
import_antd37.message.error(error instanceof Error ? error.message : "\u63D0\u4EA4\u5931\u8D25");
|
|
16409
16426
|
} finally {
|
|
16410
16427
|
setSubmitting(false);
|
|
16411
16428
|
}
|
|
@@ -17433,6 +17450,7 @@ var StandardFormPage = ({
|
|
|
17433
17450
|
formInstanceId,
|
|
17434
17451
|
defaultUploadProvider,
|
|
17435
17452
|
submitBehavior,
|
|
17453
|
+
compatibility,
|
|
17436
17454
|
onSubmit,
|
|
17437
17455
|
onSubmitSuccess,
|
|
17438
17456
|
inDrawer
|
|
@@ -17506,6 +17524,7 @@ var StandardFormPage = ({
|
|
|
17506
17524
|
defaultUploadProvider,
|
|
17507
17525
|
submitBehavior,
|
|
17508
17526
|
permissions,
|
|
17527
|
+
compatibility,
|
|
17509
17528
|
api
|
|
17510
17529
|
},
|
|
17511
17530
|
formType,
|
|
@@ -18466,6 +18485,7 @@ var DataManagementList = ({
|
|
|
18466
18485
|
detailPageUrlBuilder,
|
|
18467
18486
|
submitRenderer,
|
|
18468
18487
|
requestOverride,
|
|
18488
|
+
allowSchemaFallback = false,
|
|
18469
18489
|
rowActions = [],
|
|
18470
18490
|
maxVisibleRowActions
|
|
18471
18491
|
}) => {
|
|
@@ -18633,6 +18653,11 @@ var DataManagementList = ({
|
|
|
18633
18653
|
const nextSearchKeyWord = saved?.filter?.searchKeyWord || "";
|
|
18634
18654
|
const nextFilterGroup = hydrateFilterGroup(saved?.filter?.group);
|
|
18635
18655
|
const nextFormType = propFormType || schemaResult.formType || "form";
|
|
18656
|
+
if (!schemaResult.schema && !allowSchemaFallback) {
|
|
18657
|
+
throw new Error(
|
|
18658
|
+
`\u8868\u5355 schema \u4E0D\u5B58\u5728\u6216\u672A\u53D1\u5E03: ${formUuid}\u3002\u8BF7\u5148\u53D1\u5E03\u8868\u5355 schema\uFF1B\u4E25\u683C\u6A21\u5F0F\u4E0D\u4F1A\u751F\u6210\u515C\u5E95\u8868\u5355\u3002`
|
|
18659
|
+
);
|
|
18660
|
+
}
|
|
18636
18661
|
setFields(allFields);
|
|
18637
18662
|
setRuntimeFormSchema(
|
|
18638
18663
|
schemaResult.schema || buildFallbackFormSchema({
|
|
@@ -18663,7 +18688,7 @@ var DataManagementList = ({
|
|
|
18663
18688
|
});
|
|
18664
18689
|
} catch (error) {
|
|
18665
18690
|
console.error("[DataManagementList] load schema failed:", error);
|
|
18666
|
-
import_antd39.message.error("\u52A0\u8F7D\u8868\u5355\u914D\u7F6E\u5931\u8D25");
|
|
18691
|
+
import_antd39.message.error(error instanceof Error ? error.message : "\u52A0\u8F7D\u8868\u5355\u914D\u7F6E\u5931\u8D25");
|
|
18667
18692
|
} finally {
|
|
18668
18693
|
if (mounted) setSchemaLoading(false);
|
|
18669
18694
|
}
|
|
@@ -18674,6 +18699,7 @@ var DataManagementList = ({
|
|
|
18674
18699
|
};
|
|
18675
18700
|
}, [
|
|
18676
18701
|
appType,
|
|
18702
|
+
allowSchemaFallback,
|
|
18677
18703
|
forcedConfig,
|
|
18678
18704
|
formTitle,
|
|
18679
18705
|
formUuid,
|
|
@@ -19682,7 +19708,8 @@ function LowcodePageRenderer({ schema, context }) {
|
|
|
19682
19708
|
forcedConfig: props.forcedConfig,
|
|
19683
19709
|
showForcedConfig: props.showForcedConfig,
|
|
19684
19710
|
maxVisibleRowActions: props.maxVisibleRowActions,
|
|
19685
|
-
requestOverride
|
|
19711
|
+
requestOverride,
|
|
19712
|
+
allowSchemaFallback: props.allowSchemaFallback ?? context?.compatibility?.legacyFallbacks ?? false
|
|
19686
19713
|
},
|
|
19687
19714
|
node.id
|
|
19688
19715
|
);
|
|
@@ -19695,6 +19722,7 @@ function LowcodePageRenderer({ schema, context }) {
|
|
|
19695
19722
|
mode: props.mode || context?.mode || "submit",
|
|
19696
19723
|
appType: props.appType || appType,
|
|
19697
19724
|
formUuid: props.formUuid || props.schema?.formMeta?.formUuid,
|
|
19725
|
+
compatibility: props.compatibility || context?.compatibility,
|
|
19698
19726
|
inDrawer: props.inDrawer ?? true
|
|
19699
19727
|
},
|
|
19700
19728
|
node.id
|