editor-creator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEditor Creator
编辑器创作工具
Author or modify a Datex Studio editor (configurationTypeId=4) on a branch — a single-entity view/edit screen that hydrates one record, binds fields 1:1 to its properties, toggles between read-only and edit mode, and persists changes through a wrapping function that calls a CRUD action.
在分支上创作或修改Datex Studio编辑器(configurationTypeId=4)——这是一种单实体查看/编辑界面,可加载单条记录,字段与实体属性1:1绑定,支持只读与编辑模式切换,并通过调用CRUD操作的包装函数保存修改。
References
参考资料
- ../datex-studio-shared/branch-setup.md — Branch/connection selection (shared across skills)
- references/editors.md — Authoritative editor authoring reference: file shape, runtime globals, invocation contract, common patterns, pre-flight checklist
- ../datex-studio-conventions/file-format.md — table and TypeScript-expression encoding rules
configurationTypeId - ../datex-studio-conventions/naming-conventions.md — suffix, filename stem matching, display-name rule
_editor - ../datex-studio-runtime/runtime-globals.md — platform-injected globals available in editor code (,
$editor,$flows,$shell, ...)$utils - ../datex-studio-runtime/calling-conventions.md — UI-tier calling rules (call functions, never actions; CRUD via )
$apis.<Package>.FootprintApi.extendedActions.<action_name> - ../form-creator/references/forms.md — sibling component for transient input collection (the editor-vs-form decision)
- ../grid-creator/references/grids.md — typical host for editors via row-click / row-action flows
- ../datasource-creator/references/flow-datasources.md — single-result shape required for editor-backing datasources
- ../component-wiring-check/references/component-wiring.md — host reference contracts, vars-must-be-declared rule, moduleId rule
- ../datex-studio-shared/branch-setup.md — 分支/连接选择(各技能通用)
- references/editors.md — 编辑器创作权威参考:文件结构、运行时全局变量、调用约定、通用模式、预检查清单
- ../datex-studio-conventions/file-format.md — 对照表与TypeScript表达式编码规则
configurationTypeId - ../datex-studio-conventions/naming-conventions.md — 后缀、文件名主干匹配规则、显示名称规则
_editor - ../datex-studio-runtime/runtime-globals.md — 平台注入到编辑器代码中的全局变量(、
$editor、$flows、$shell等)$utils - ../datex-studio-runtime/calling-conventions.md — UI层调用规则(仅调用函数,不直接调用操作;通过执行CRUD)
$apis.<Package>.FootprintApi.extendedActions.<action_name> - ../form-creator/references/forms.md — 用于临时输入收集的同级组件(编辑器与表单的选择判断)
- ../grid-creator/references/grids.md — 通常通过行点击/行操作流程唤起编辑器的宿主组件
- ../datasource-creator/references/flow-datasources.md — 编辑器绑定数据源所需的单结果结构
- ../component-wiring-check/references/component-wiring.md — 宿主引用约定、变量必须声明规则、moduleId规则
Dependencies
依赖项
- skill — invoked to produce a requirements brief if one doesn't already exist in the conversation context
requirements-gathering - /
form-creatorskills — invoked when the requirement is actually transient input collection (form) or a multi-record list (grid), not a single-entity detail screengrid-creator - skill — invoked when the single-result flow datasource backing the editor needs to be authored as a standalone config (rare — the embedded private datasource is the usual shape)
datasource-creator - skill — invoked to audit
component-wiring-check↔ targetconfigParameterscontracts on the editor's host (hub tab / grid row action / form) before pushinParams - skill — invoked when the editor's bound entity interface or a related type definition needs authoring or extension (e.g. adding a field to the schema that the editor must mirror with a new binding)
type-definition-creator - skill — invoked when customer-specific extensions to the editor (added fields, modified bindings) need to live in a tailored overlay rather than the base config
tailoring-overlay
- 技能 — 若对话上下文无需求说明文档,将调用该技能生成需求简报
requirements-gathering - /
form-creator技能 — 若实际需求为临时输入收集(表单)或多记录列表(表格)而非单实体详情界面,将调用对应技能grid-creator - 技能 — 若编辑器绑定的单结果流数据源需作为独立配置创作(少见,通常使用嵌入式私有数据源),将调用该技能
datasource-creator - 技能 — 在推送前,用于审核编辑器宿主(中心标签页/表格行操作/表单)的
component-wiring-check与目标configParameters约定inParams - 技能 — 若编辑器绑定的实体接口或相关类型定义需创作或扩展(例如为编辑器新增字段绑定而修改 schema),将调用该技能
type-definition-creator - 技能 — 若需为编辑器添加客户特定扩展(新增字段、修改绑定)并使其位于定制覆盖层而非基础配置中,将调用该技能
tailoring-overlay
CLI Lifecycle
CLI生命周期
Editor authoring goes through — the generic CRUD primitive over every platform configuration type. There is no subcommand and no field-level patching; you build (or fetch + extract) the whole JSON body, edit it, and push the whole thing back. The type identifier in the CLI is (lowercase, matches output), mapping to .
dxs configurationdxs editoreditorConfigurationEndpoints.normalize_typeconfigurationTypeId: 4Create a new editor:
bash
undefined编辑器创作通过完成——这是针对所有平台配置类型的通用CRUD原语。不存在子命令,也不支持字段级补丁;需构建(或获取并提取)完整JSON内容,编辑后重新推送完整内容。CLI中的类型标识符为****(小写,与输出一致),对应。
dxs configurationdxs editoreditorConfigurationEndpoints.normalize_typeconfigurationTypeId: 4创建新编辑器:
bash
undefined1. Build body.json from scratch (see references/editors.md → Minimal Valid Skeleton)
1. 从零构建body.json(参考references/editors.md → 最小有效骨架)
2. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
2. 验证 — 作为推送前置检查。退出码1表示发现错误(查看validation_errors,修复后重新运行),并非CLI故障
dxs configuration validate editor -b <branchId> -D body.json
dxs configuration validate editor -b <branchId> -D body.json
3. Create
3. 创建
dxs configuration upsert editor -b <branchId> -D body.json
**Edit an existing editor:**
```bashdxs configuration upsert editor -b <branchId> -D body.json
**编辑现有编辑器:**
```bash1. Fetch — note the envelope wrapper
1. 获取 — 注意信封包装
dxs configuration get editor <configId> -b <branchId> -O envelope.json
dxs configuration get editor <configId> -b <branchId> -O envelope.json
2. EXTRACT THE INNER BODY (round-trip footgun guard — see "Round-trip rule" below)
2. 提取内部内容(往返操作防坑规则 — 见下文“往返规则”)
jq .json envelope.json > body.json
jq .json envelope.json > body.json
3. Edit body.json
3. 编辑body.json
4. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
4. 验证 — 作为推送前置检查。退出码1表示发现错误(查看validation_errors,修复后重新运行),并非CLI故障
dxs configuration validate editor -b <branchId> -D body.json
dxs configuration validate editor -b <branchId> -D body.json
5. Push
5. 推送
dxs configuration upsert editor -b <branchId> -D body.json
undefineddxs configuration upsert editor -b <branchId> -D body.json
undefinedRound-trip rule (critical)
往返规则(关键)
When editing an existing config, never pipe the envelope.json directly into — it silently destroys configuration content. The corrected sequence above (extract inner with before editing) is mandatory for any round-trip. See ../datex-studio-shared/configuration-roundtrip.md for the canonical round-trip and the underlying bug.
dxs configuration upsert.jsonjqEditors are dense — the body carries , , , , and substantially populated, with a field on every embedded flow. Surgical edits in this much JSON are error-prone; round-trip discipline (fetch → jq-extract → edit → validate → push) is non-negotiable.
toolbarfieldsetsflowsdatasourceConfigdatasourcescode编辑现有配置时,切勿直接将envelope.json管道输入——这会静默破坏配置内容。上述正确流程(编辑前用提取内部)是所有往返操作的强制要求。有关标准往返流程及底层问题,详见../datex-studio-shared/configuration-roundtrip.md。
dxs configuration upsertjq.json编辑器内容密集——body包含大量、、、和配置,每个嵌入式流程都有字段。在如此复杂的JSON中进行精准编辑易出错;往返操作规范(获取→jq提取→编辑→验证→推送)必不可少。
toolbarfieldsetsflowsdatasourceConfigdatasourcescodeWorkflow
工作流程
[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection
|
[requirements brief in context?]
+-----+-----+
| |
YES NO -> invoke `requirements-gathering`
| |
+-----+------+
|
[Phase 2: Editor vs Form vs Grid decision]
Consult references/editors.md → "Purpose & When to Use":
- single hydrated entity, view/edit toggle, persist via CRUD -> editor
- transient input collection, returns outParams, no entity -> form
- multi-record tabular view -> grid
If form -> invoke `form-creator` instead and stop here.
If grid -> invoke `grid-creator` instead and stop here.
Create-only dialogs are usually forms, not editors.
|
[Phase 3: Author editor body]
Build body.json:
- File shape (configurationTypeId=4, *-editor.json suffix,
referenceName ends _editor)
- Embedded single-result private datasource in datasources[]
(configurationTypeId=6, type=flows, accessModifier=private,
getFlow populated; getListFlow/getByKeysFlow null;
resultIsCollection=false; outParams[0].isCollection=false)
- Flow shape: getFlow populated; getListFlow and getByKeysFlow null
(editors call .get() — code left in getListFlow silently breaks hydration)
- Entity shape mirrored: datasources[0].outParams[0].objectTypeDef
== datasourceConfig.configOutParameters.result.objectTypeDef
- onInitFlowConfig (pre-hydration; no $editor.entity reads)
vs onDataLoadedFlowConfig (post-hydration; entity-derived defaults)
- View/edit toggle via $editor.vars.edit_mode (declared in vars[])
- Save branches on $editor.entity.isNew (crud_create vs crud_update)
- onFormValidateFlowConfig gates $editor.toolbar.<save>.control.readOnly
- EditorFields parity: every entity-interface field has a binding
(stub with removed:true when UX isn't ready)
- Invoke `datasource-creator` if a standalone datasource is missing
- Invoke `component-wiring-check` to audit host's configParameters
|
[Phase 4: Validate + push]
dxs configuration validate editor -b <branchId> -D body.json
|
+----+----+
| |
CREATE MODIFY-EXISTING
| |
| use the corrected round-trip
| (get -O envelope -> jq .json -> body)
| |
+----+----+
|
v
dxs configuration upsert editor -b <branchId> -D body.json
(upsert creates or updates by referenceName — one command for both)
|
[Phase 5: Verify in Studio (optional)]
Open the editor as a dialog (from its host hub/grid); confirm
hydration, toggle into edit mode, save commits, cancel restores
|
[invoke `post-edit-verification`; then `component-validator`][阶段1:设置 + 需求]
遵循branch-setup.md完成分支/连接选择
|
[上下文是否存在需求简报?]
+-----+-----+
| |
是 否 → 调用`requirements-gathering`
| |
+-----+------+
|
[阶段2:编辑器、表单、表格的选择判断]
参考references/editors.md → “用途与适用场景”:
- 单实体加载、查看/编辑模式切换、通过CRUD保存 → 编辑器
- 临时输入收集、返回outParams、无实体关联 → 表单
- 多记录表格视图 → 表格
若选择表单 → 调用`form-creator`并终止当前流程
若选择表格 → 调用`grid-creator`并终止当前流程
仅创建功能的对话框通常使用表单而非编辑器
|
[阶段3:创作编辑器内容]
构建body.json:
- 文件结构(configurationTypeId=4,后缀*-editor.json,
referenceName以_editor结尾)
- datasources[]中包含嵌入式单结果私有数据源
(configurationTypeId=6,type=flows,accessModifier=private,
getFlow已填充;getListFlow/getByKeysFlow为null;
resultIsCollection=false; outParams[0].isCollection=false)
- 流程结构:getFlow已填充;getListFlow和getByKeysFlow为null
(编辑器调用.get() — getListFlow中遗留代码会破坏加载逻辑)
- 实体结构镜像:datasources[0].outParams[0].objectTypeDef
== datasourceConfig.configOutParameters.result.objectTypeDef
- onInitFlowConfig(加载前;不可读取$editor.entity)
与onDataLoadedFlowConfig(加载后;基于实体设置默认值)的区分
- 通过$editor.vars.edit_mode实现查看/编辑模式切换(需在vars[]中声明)
- 根据$editor.entity.isNew分支处理保存逻辑(crud_create vs crud_update)
- 通过onFormValidateFlowConfig控制$editor.toolbar.<save>.control.readOnly
- EditorFields一致性:实体接口的每个字段都有绑定
(若UX未就绪,可使用removed:true作为占位)
- 若缺少独立数据源,调用`datasource-creator`
- 调用`component-wiring-check`审核宿主的configParameters
|
[阶段4:验证 + 推送]
dxs configuration validate editor -b <branchId> -D body.json
|
+----+----+
| |
创建新编辑器 修改现有编辑器
| |
| 使用正确的往返流程
| (get -O envelope → jq .json → body)
| |
+----+----+
|
v
dxs configuration upsert editor -b <branchId> -D body.json
(upsert通过referenceName创建或更新 — 同一命令适用于两种场景)
|
[阶段5:在Studio中验证(可选)]
通过正常调用路径(中心标签页工具栏按钮、表格行操作或链式表单)打开编辑器对话框;确认
加载成功、可切换编辑模式、保存提交生效、取消恢复原始值
|
[调用`post-edit-verification`;随后调用`component-validator`]Phase Details
阶段详情
Phase 1: Setup + Requirements
阶段1:设置 + 需求
- Follow ../datex-studio-shared/branch-setup.md for branch and connection selection. Never assume a branch ID — ask the user to confirm.
- Check whether a requirements brief already exists in the conversation context (produced by or another calling skill).
requirements-gathering- Brief exists — use it. The brief should establish the entity being edited (and which key the host passes in), which fields are visible/editable, view-only-vs-edit-mode behavior, save semantics (which CRUD action persists changes), and whether the same editor handles create mode.
- No brief — invoke the skill first. Getting the entity shape and save semantics right up front avoids the dense round-trip that follows.
requirements-gathering
- 遵循../datex-studio-shared/branch-setup.md完成分支和连接选择。切勿假设分支ID——请用户确认。
- 检查对话上下文是否已存在需求简报(由或其他调用技能生成)。
requirements-gathering- 存在简报 — 使用该简报。简报应明确待编辑的实体(及宿主传入的键)、可见/可编辑字段、只读与编辑模式行为、保存语义(通过哪个CRUD操作保存修改),以及同一编辑器是否支持创建模式。
- 无简报 — 先调用技能。提前明确实体结构和保存语义可避免后续复杂的往返操作。
requirements-gathering
Phase 2: Editor vs Form vs Grid decision
阶段2:编辑器、表单、表格的选择判断
Consult references/editors.md → Purpose & When to Use before authoring. The choice is not stylistic — editors, forms, and grids serve different roles and aren't interchangeable.
Pick an editor when:
- The user views or modifies a single entity identified by a key.
- Field-level inputs map 1:1 to properties of that entity.
- The UX wants a distinct view-mode (read-only) and edit-mode (inputs unlocked, save active) toggle.
- The flow persists changes through a CRUD action (/
crud_create_entity).crud_update_entity
Pick a form instead when:
- The work is transient input collection that doesn't correspond to a stored record.
- The dialog returns to the caller; nothing persists implicitly.
outParams - The dialog is creation-only and no entity yet exists to hydrate.
Pick a grid instead when:
- The user views or operates on multiple records in a tabular layout.
If the answer is form, stop and invoke . If the answer is grid, stop and invoke . Editors can handle create mode via , but that path is justified only when the same component handles both create and edit for the same entity type — pure create dialogs are usually a better fit for a form.
form-creatorgrid-creator$editor.entity.isNew创作前参考references/editors.md → 用途与适用场景。选择并非风格问题——编辑器、表单和表格各司其职,不可互换。
选择编辑器的场景:
- 用户查看或修改由键标识的单个实体。
- 字段级输入与该实体属性1:1映射。
- UX需要区分查看模式(只读)和编辑模式(输入解锁、保存激活)。
- 流程通过CRUD操作(/
crud_create_entity)保存修改。crud_update_entity
选择表单的场景:
- 工作内容为临时输入收集,不对应存储记录。
- 对话框向调用者返回;无隐式持久化逻辑。
outParams - 对话框仅用于创建,尚无实体可加载。
选择表格的场景:
- 用户查看或操作表格布局中的多条记录。
若选择表单,终止当前流程并调用。若选择表格,终止当前流程并调用。编辑器可通过支持创建模式,但仅当同一组件处理同一实体类型的创建和编辑时才合理——纯创建对话框通常更适合使用表单。
form-creatorgrid-creator$editor.entity.isNewPhase 3: Author editor body
阶段3:创作编辑器内容
Build from the skeleton in references/editors.md → Minimal Valid Skeleton. Key points:
body.json-
File basics. Per the Pre-Flight Checklist below + ../datex-studio-conventions/universal-checklist.md; see references/editors.md → File Location & Naming for thefile shape.
-editor.json -
Embedded single-result datasource. Each editor embeds exactly one private, single-result flow datasource in. Required shape:
datasources[],configurationTypeId: 6,type: "flows",accessModifier: "private"populated,getFlow,getListFlow: null,getByKeysFlow: null,resultIsCollection: false. A collection-returning datasource breaks the editor reference —outParams[0].isCollection: falsecan't hydratedatasourceConfig.get({...})from a list. See references/editors.md → Embedded Private Datasource and ../datasource-creator/references/flow-datasources.md → Single-Result Shape. If the editor needs to share a datasource with other components (rare), invoke$editor.entityto author a standalone version. The branch's server-side usage gate independently enforces this at contract-validation time — it blocks publish if the editor's datasource doesn't implementdatasource-creatoron a single, non-collection result.get -
Entity shape mirror.(the datasource side) must mirror
datasources[0].outParams[0].objectTypeDef(the editor's consumer side) field-for-field. Any entity-shape change touches both places in the same edit. ThedatasourceConfig.configOutParameters.result.objectTypeDefondatasourceKeyDefmatches the embedded datasource'sdatasourceConfigexactly and matches thekeyDefshape the host passes.inParams -
vs
onInitFlowConfig. The single most common editor bug is flipping these.onDataLoadedFlowConfigfires before the datasource resolves —onInitis not yet populated; reading it yields undefined. Use$editor.entityfor var setup, defaultingonInitonedit_mode, or logic independent of entity data.isNewfires after the entity hydrates — use it for entity-derived defaults, stashing pre-edit snapshots, and populating UI-only state from entity fields. See references/editors.md → onInitFlowConfig vs onDataLoadedFlowConfig.onDataLoaded -
View/edit mode toggle. Declarein top-level
edit_mode(everyvars[]written in flow code must be declared — see ../component-wiring-check/references/component-wiring.md). Edit button visible when$editor.vars.<id>; Save + Cancel visible when!edit_mode. Fieldedit_modebound toreadOnly(or computed per-field when some stay locked). Cancel restores original entity values — re-call the datasource or stash pre-edit values in!edit_modeduring$editor.vars.onDataLoaded -
Save branches on. When new →
$editor.entity.isNew(or the equivalent create action wrapped in a function); when existing →crud_create_entity. Neither branch hardcoded. The UI-tier calling rule applies: editor code calls functions viacrud_update_entity; the function wraps the CRUD action call as$flows.<Package>.<fn>. See ../datex-studio-runtime/calling-conventions.md.$apis.<Package>.FootprintApi.extendedActions.<action_name>({...}) -
Save button gated by validation.runs whenever any field changes. Compute
onFormValidateFlowConfigfrom field values (often viais_validfor required strings), then set$utils.isDefinedTrimmed. Optionally push per-field messages to$editor.toolbar.<save_button>.control.readOnly = !is_valid. See references/editors.md → Save Button Gated by onFormValidateFlowConfig.control.validationMessage -
EditorFields parity. The platform auto-generates anTypeScript type from the bound entity's interface. The editor must declare a
EditorFields-bearing binding for every field on that interface — nested paths flatten withcontrolConfig(e.g.__→ field idreplenishments.rules). Missing a binding fails import. When the schema gains a field, the editor adds the binding in the same edit; a stub binding withreplenishments__rulesis acceptable if real UX isn't ready. For array-of-object sub-trees, use the button +removed: true+$editor.vars.<var>-merge pattern. See references/editors.md → EditorFields Requires a Binding for Every Schema Field and the serialized-config-JSON section for the wrapper-entity case.set_config -
TypeScript-expression encoding on every declarative-string slot. Every,
tooltip,placeholder,value, buttonformat(when bound to a var) is inlined verbatim into generated TS. Wrap display text in backticks (label), wrap plain-string literals in TS quotes ("`Manage rules…`"), leave raw expressions unwrapped ("'MM/DD/YYYY'"). An unwrapped tooltip like"$editor.vars.foo"compiles to bare TS tokens and breaks the build. See ../datex-studio-conventions/file-format.md → Declarative String Values Are TypeScript Expressions."Manage rules." -
No custom-enum FQNs in/
vars/inParams. Editors can't resolveoutParamsin param declarations — declare those fields as primitive ($types.<Package>.e_<enum>for string-valued enums,stringfor numeric) and cast at usage inside flow code.number -
slots stay
onCustomization*unless customization hooks are explicitly needed — they're platform-extension points for tailored overlays (null), not everyday editor wiring.tailoring-overlay -
Host contract audit. The hub tab, grid row action, or form that opens this editor as a dialog must declare a fullcontract — every
configParametersthe editor declares gets an entry on the host, including unused ones withinParam. Invokevalue: nullto audit reference contracts before push. See ../component-wiring-check/references/component-wiring.md.component-wiring-check
基于references/editors.md → 最小有效骨架构建。关键点:
body.json-
文件基础。遵循下文预检查清单 + ../datex-studio-conventions/universal-checklist.md;文件结构参考references/editors.md → 文件位置与命名中的规则。
-editor.json -
嵌入式单结果数据源。每个编辑器在中嵌入恰好一个私有单结果流数据源。必填结构:
datasources[]、configurationTypeId: 6、type: "flows"、accessModifier: "private"已填充、getFlow、getListFlow: null、getByKeysFlow: null、resultIsCollection: false。返回集合的数据源会破坏编辑器引用——outParams[0].isCollection: false无法从列表中加载datasourceConfig.get({...})。详见references/editors.md → 嵌入式私有数据源和../datasource-creator/references/flow-datasources.md → 单结果结构。若编辑器需与其他组件共享数据源(少见),调用$editor.entity创作独立版本。分支的服务器端使用限制会在合约验证时独立强制执行——若编辑器数据源未实现单结果datasource-creator操作,将阻止发布。get -
实体结构镜像。(数据源端)必须与
datasources[0].outParams[0].objectTypeDef(编辑器消费端)字段完全匹配。任何实体结构变更需同时修改两处内容。datasourceConfig.configOutParameters.result.objectTypeDef上的datasourceConfig需与嵌入式数据源的datasourceKeyDef完全匹配,且与宿主传入的keyDef结构一致。inParams -
与
onInitFlowConfig的区分。最常见的编辑器错误就是混淆两者。onDataLoadedFlowConfig在数据源解析前触发——onInit尚未填充;读取会返回undefined。$editor.entity用于变量设置、在onInit时默认isNew,或与实体数据无关的逻辑。edit_mode在实体加载后触发——用于基于实体设置默认值、存储编辑前快照,以及从实体字段填充仅UI状态。详见references/editors.md → onInitFlowConfig与onDataLoadedFlowConfig。onDataLoaded -
查看/编辑模式切换。在顶层中声明
vars[](流程代码中写入的每个edit_mode都必须声明——详见../component-wiring-check/references/component-wiring.md)。当$editor.vars.<id>时显示编辑按钮;当!edit_mode时显示保存+取消按钮。字段edit_mode绑定到readOnly(或按字段计算,部分字段保持锁定)。取消操作恢复原始实体值——在!edit_mode期间重新调用数据源或在onDataLoaded中存储编辑前快照。$editor.vars -
根据分支处理保存逻辑。新建实体时调用
$editor.entity.isNew(或包装在函数中的等效创建操作);现有实体时调用crud_create_entity。两者均不可硬编码。需遵循UI层调用规则:编辑器代码通过crud_update_entity调用函数;函数通过$flows.<Package>.<fn>包装CRUD操作调用。详见../datex-studio-runtime/calling-conventions.md。$apis.<Package>.FootprintApi.extendedActions.<action_name>({...}) -
保存按钮受验证控制。在任何字段变更时触发。根据字段值计算
onFormValidateFlowConfig(通常对必填字符串使用is_valid),然后设置$utils.isDefinedTrimmed。可选择将字段级消息推送到$editor.toolbar.<save_button>.control.readOnly = !is_valid。详见references/editors.md → 保存按钮受onFormValidateFlowConfig控制。control.validationMessage -
EditorFields一致性。平台会根据绑定实体的接口自动生成TypeScript类型。编辑器必须为该接口的每个字段声明带有
EditorFields的绑定——嵌套路径用controlConfig扁平化(例如__→ 字段IDreplenishments.rules)。缺少绑定会导致导入失败。当schema新增字段时,编辑器需在同一编辑操作中添加绑定;若UX未就绪,可使用replenishments__rules作为占位绑定。对于对象数组子树,使用按钮 +removed: true+$editor.vars.<var>合并模式。详见references/editors.md → EditorFields要求每个schema字段都有绑定和序列化配置JSON部分的包装实体案例。set_config -
每个声明式字符串插槽的TypeScript表达式编码。每个、
tooltip、placeholder、value、按钮format(绑定到变量时)都会直接内联到生成的TS中。显示文本用反引号包裹(label),纯字符串字面量用TS引号包裹("`Manage rules…`"),原始表达式无需包裹("'MM/DD/YYYY'")。未包裹的提示文本如"$editor.vars.foo"会编译为裸TS标记,导致构建失败。详见../datex-studio-conventions/file-format.md → 声明式字符串值为TypeScript表达式。"Manage rules." -
/
vars/inParams中无自定义枚举FQN。编辑器无法解析参数声明中的outParams——将这些字段声明为原始类型(字符串枚举用$types.<Package>.e_<enum>,数值枚举用string),并在流程代码中使用时进行类型转换。number -
插槽保持
onCustomization*,除非明确需要自定义钩子——它们是平台为定制覆盖层(null)提供的扩展点,并非日常编辑器配置所需。tailoring-overlay -
宿主合约审核。将此编辑器作为对话框打开的中心标签页、表格行操作或表单必须声明完整的合约——编辑器声明的每个
configParameters都需在宿主中有对应条目,包括未使用的条目(inParam)。推送前调用value: null审核引用合约。详见../component-wiring-check/references/component-wiring.md。component-wiring-check
Phase 4: Validate + push
阶段4:验证 + 推送
bash
undefinedbash
undefinedValidate the body locally against the branch. Exit 1 = validation found errors
针对分支本地验证内容。退出码1表示验证发现错误
(read validation_errors, fix body.json, re-run) — not a broken CLI. Do not push on exit 1.
(查看validation_errors,修复body.json后重新运行)——并非CLI故障。退出码1时请勿推送。
dxs configuration validate editor -b <branchId> -D body.json
dxs configuration validate editor -b <branchId> -D body.json
For a new editor
针对新编辑器
dxs configuration upsert editor -b <branchId> -D body.json
dxs configuration upsert editor -b <branchId> -D body.json
For modify-existing (round-trip — never skip the jq extract)
针对修改现有编辑器(往返操作 — 切勿跳过jq提取步骤)
dxs configuration get editor <configId> -b <branchId> -O envelope.json
jq .json envelope.json > body.json
dxs configuration get editor <configId> -b <branchId> -O envelope.json
jq .json envelope.json > body.json
... edit body.json ...
... 编辑body.json ...
dxs configuration upsert editor -b <branchId> -D body.json
Validation surfaces missing required fields, malformed parameter-descriptor shapes, `EditorFields` parity violations, and reference errors before push. It does **not** catch the `onInit`-vs-`onDataLoaded` flip, undeclared `$editor.vars.<id>` writes, or unwrapped TypeScript-expression slots — those are behavioral and only surface at runtime. Walk the [references/editors.md → Pre-Flight Checklist](references/editors.md#pre-flight-checklist) before push.dxs configuration upsert editor -b <branchId> -D body.json
验证会在推送前发现缺失的必填字段、格式错误的参数描述结构、EditorFields一致性违规和引用错误。但它**无法**检测`onInit`与`onDataLoaded`混淆、未声明的`$editor.vars.<id>`写入或未包裹的TypeScript表达式插槽——这些属于行为问题,仅在运行时暴露。推送前请浏览[references/editors.md → 预检查清单](references/editors.md#pre-flight-checklist)。Phase 5: Verify in Studio (optional)
阶段5:在Studio中验证(可选)
Open the editor as a dialog through its normal invocation path (a hub tab toolbar button, a grid row action, or a form that chains into it):
- Hydration succeeds — is populated when
$editor.entityruns; fields display the loaded values.onDataLoaded - Edit-mode toggle works — Edit button flips ; Save + Cancel appear; fields become editable.
edit_mode = true - Save commits — branches correctly on ; the wrapping CRUD action succeeds; the dialog closes or flips back to read-only.
$editor.entity.isNew - Cancel restores original values — pre-edit snapshot survives (or the datasource re-fetches cleanly).
- For create mode (), the embedded datasource synthesizes a blank entity; the save path takes the create branch.
isNew: true - Save button stays disabled until reports
onFormValidateFlowConfig.is_valid
If the running app isn't available, re-fetch the config (using the corrected extract pattern) and diff against to confirm the push landed.
jq .jsonbody.json通过正常调用路径(中心标签页工具栏按钮、表格行操作或链式表单)打开编辑器对话框:
- 加载成功 — 触发时
onDataLoaded已填充;字段显示加载的值。$editor.entity - 编辑模式切换正常 — 编辑按钮将设为
edit_mode;显示保存+取消按钮;字段变为可编辑。true - 保存提交生效 — 根据正确分支;包装的CRUD操作成功;对话框关闭或切换回只读模式。
$editor.entity.isNew - 取消恢复原始值 — 编辑前快照保留(或数据源重新获取干净数据)。
- 创建模式()下,嵌入式数据源生成空白实体;保存路径走创建分支。
isNew: true - 保存按钮在报告
onFormValidateFlowConfig前保持禁用。is_valid
若运行应用不可用,重新获取配置(使用正确的提取模式)并与对比,确认推送已生效。
jq .jsonbody.jsonPre-Flight Checklist
预检查清单
Before push, walk the full checklist in references/editors.md → Pre-Flight Checklist. The fast version:
- File basics. , suffix
configurationTypeId: 4,-editor.jsonendsreferenceName— plus the universal checks (../datex-studio-conventions/universal-checklist.md)._editor - Exactly one embedded datasource — ,
accessModifier: "private", single-result shape (type: "flows"populated;getFlow+getListFlownull;getByKeysFlow;resultIsCollection: false).outParams[0].isCollection: false - Entity shape mirrored — field-for-field matches
datasourceConfig.configOutParameters.result.objectTypeDef.datasources[0].outParams[0].objectTypeDefmatches the embedded datasource'sdatasourceKeyDefand the host'skeyDefshape.inParams - Init-hook split correct — does not read
onInitFlowConfig; entity-dependent defaults and pre-edit snapshots live in$editor.entity.onDataLoadedFlowConfig - Save branches on —
$editor.entity.isNewwhen new,crud_create_entitywhen existing. Neither branch hardcoded.crud_update_entity - gates
onFormValidateFlowConfigon field validity.$editor.toolbar.<save>.control.readOnly - declared — every var written in flow code (
$editor.vars, snapshots, in-progress arrays) is in top-leveledit_mode.vars[] - EditorFields parity — every entity-interface field has a binding (stub if UX isn't ready). Array-of-object sub-trees use the button +
removed: true+$editor.vars-merge pattern.set_config - Calling-tier compliance — editor code calls functions via ; the function wraps CRUD actions via
$flows.<Package>.<fn>; no direct action calls from the editor.$apis.<Package>.FootprintApi.extendedActions.<action_name>({...}) - TypeScript-expression strings wrapped correctly — display text in backticks; raw expressions unwrapped; plain literals quoted.
- slots
onCustomization*unless customization is intentional.null - No in
$types.<Package>.e_<enum>/vars/inParams— primitives only at the param layer; cast at usage.outParams - Host carries a full contract — every inParam the editor declares has an entry; unused ones use
configParameters. Audit viavalue: null.component-wiring-check
推送前,请浏览references/editors.md → 预检查清单完整内容。简化版本:
- 文件基础。、后缀
configurationTypeId: 4、-editor.json以referenceName结尾 — 加上通用检查项(../datex-studio-conventions/universal-checklist.md)。_editor - 恰好一个嵌入式数据源 — 、
accessModifier: "private"、单结果结构(type: "flows"已填充;getFlow+getListFlow为null;getByKeysFlow;resultIsCollection: false)。outParams[0].isCollection: false - 实体结构镜像 — 与
datasourceConfig.configOutParameters.result.objectTypeDef字段完全匹配。datasources[0].outParams[0].objectTypeDef与嵌入式数据源的datasourceKeyDef及宿主的keyDef结构一致。inParams - 初始化钩子区分正确 — 不读取
onInitFlowConfig;依赖实体的默认值和编辑前快照放在$editor.entity中。onDataLoadedFlowConfig - 根据分支处理保存逻辑 — 新建时调用
$editor.entity.isNew,现有时调用crud_create_entity。两者均未硬编码。crud_update_entity - 根据字段有效性控制
onFormValidateFlowConfig。$editor.toolbar.<save>.control.readOnly - 已声明 — 流程代码中写入的每个变量(
$editor.vars、快照、进行中的数组)都在顶层edit_mode中声明。vars[] - EditorFields一致性 — 实体接口的每个字段都有绑定(UX未就绪时可用占位)。对象数组子树使用按钮 +
removed: true+$editor.vars合并模式。set_config - 调用层合规 — 编辑器代码通过调用函数;函数通过
$flows.<Package>.<fn>包装CRUD操作;编辑器不直接调用操作。$apis.<Package>.FootprintApi.extendedActions.<action_name>({...}) - TypeScript表达式字符串包裹正确 — 显示文本用反引号;原始表达式无需包裹;纯字面量用引号。
- 插槽为
onCustomization*,除非有意进行自定义。null - /
vars/inParams中无outParams— 参数层仅使用原始类型;使用时在流程代码中进行类型转换。$types.<Package>.e_<enum> - 宿主携带完整合约 — 编辑器声明的每个inParam都有对应条目;未使用的条目设为
configParameters。通过value: null审核。component-wiring-check
Common Mistakes
常见错误
| Mistake | Fix |
|---|---|
Reading | Entity isn't hydrated yet — yields undefined. Move entity-derived defaults and pre-edit snapshots to |
Embedded datasource returns a collection ( | Editor can't hydrate |
| Editor reference breaks at runtime. They mirror each other — any entity-shape change touches both. |
Save path hardcoded to | Breaks the other mode. Branch on |
| Var is undeclared — write fails silently or runtime error. Declare every var. |
| Missing field binding for a new schema field | |
Mutating | Type error — |
| Array-of-object sub-tree authored as a flat field binding | |
| Editor code calls an action directly | UI-tier rule: editor calls functions only. The function wraps the action via |
Unwrapped declarative-string slot ( | Inlined verbatim into generated TS — bare tokens break the build. Backticks for display text; quotes for plain literals; raw expressions unwrapped. |
| Custom-enum FQN doesn't resolve at the param layer. Declare as primitive ( |
| It is an array of parameter descriptors mirroring the embedded datasource's |
Embedded datasource given a | An embedded (private) editor datasource carries no |
Embedded datasource missing | All three are required. |
Piping | Silently destroys config content. Always |
| SQL column limit — push will fail validation. Tighten. |
| Import / lookup breaks. Snake_case, |
| Cross-component reference rule — |
After your edit, invoke to surface description/JSON/schema violations. For a final review, invoke .
post-edit-verificationcomponent-validator| 错误 | 修复方案 |
|---|---|
在 | 实体尚未加载 — 返回undefined。将依赖实体的默认值和编辑前快照移至 |
嵌入式数据源返回集合( | 编辑器无法从列表中加载 |
| 运行时编辑器引用失效。两者需完全镜像 — 任何实体结构变更需同时修改两处。 |
保存路径硬编码为 | 破坏另一模式的功能。根据 |
流程代码中写入 | 变量未声明 — 写入操作静默失败或触发运行时错误。声明所有变量。 |
| 新增schema字段后缺少字段绑定 | |
实体为序列化配置包装器时直接修改 | 类型错误 — |
| 对象数组子树作为扁平字段绑定创作 | |
| 编辑器代码直接调用操作 | UI层规则:编辑器仅调用函数。函数通过 |
未包裹的声明式字符串插槽( | 直接内联到生成的TS中 — 裸标记导致构建失败。显示文本用反引号;纯字面量用引号;原始表达式无需包裹。 |
| 参数层无法解析自定义枚举FQN。声明为原始类型( |
| 它是参数描述数组,需与嵌入式数据源的 |
| 嵌入式(私有)编辑器数据源无 |
嵌入式数据源缺少 | 三者均为必填项。 |
将 | 静默破坏配置内容。编辑前始终执行 |
| SQL列限制 — 推送会验证失败。精简内容。 |
| 导入/查找失效。使用蛇形命名、 |
宿主引用的 | 跨组件引用规则 — |
编辑完成后,调用发现描述/JSON/schema违规。最终审核请调用。
post-edit-verificationcomponent-validator