embed-creator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEmbed Creator
Embed 组件创建工具
Author or modify a Datex Studio embed (configurationTypeId=20) on a branch — a thin UI component whose entire surface is a single . An embed renders either an external URL (a hosted map, dashboard, document viewer) or an in-memory HTML string (a generated email/report preview) and is almost always opened as a dialog via (prefixed with the embed's package when it's registered under a module).
<iframe>$shell.open<referenceName>Dialog(...)在分支上创作或修改Datex Studio embed(configurationTypeId=20)——这是一个轻量UI组件,其整个界面就是单个。Embed可渲染外部URL(托管的地图、仪表盘、文档查看器)或内存中的HTML字符串(生成的邮件/报告预览),几乎总是通过以对话框形式打开(当embed在模块下注册时,需添加其包名前缀)。
<iframe>$shell.open<referenceName>Dialog(...)References
参考文档
- ../datex-studio-shared/branch-setup.md — Branch/connection selection (shared across skills)
- references/embeds.md — Authoritative embed authoring reference: file shape, minimal-valid skeleton, the iframe-only rule, the URI HTML-string pattern, dialog wiring, the print pattern, CSP caveats, pre-flight checklist
data: - ../datex-studio-conventions/file-format.md — table and the TypeScript-expression encoding rule (applies to
configurationTypeId)iframeConfig.href - ../datex-studio-conventions/naming-conventions.md — /
_embedsuffix, filename-stem matching, display-name rule-embed - ../datex-studio-runtime/runtime-globals.md — platform-injected globals available in embed code (,
$embed,$shell,$datasources, ...)$utils - ../form-creator/references/forms.md — sibling component; pick a form when you need field controls/buttons alongside the content (the form-vs-embed decision)
- ../component-wiring-check/references/component-wiring.md — host reference contracts, vars-must-be-declared rule, rule for the component that opens the embed
moduleId
- ../datex-studio-shared/branch-setup.md — 分支/连接选择(所有技能共享)
- references/embeds.md — 权威的Embed创作参考:文件结构、最小有效骨架、仅iframe规则、URI HTML字符串模式、对话框连接方式、打印模式、CSP注意事项、预检查清单
data: - ../datex-studio-conventions/file-format.md — 表格和TypeScript表达式编码规则(适用于
configurationTypeId)iframeConfig.href - ../datex-studio-conventions/naming-conventions.md — /
_embed后缀、文件名主干匹配规则、显示名称规则-embed - ../datex-studio-runtime/runtime-globals.md — 平台注入到embed代码中的全局变量(、
$embed、$shell、$datasources等)$utils - ../form-creator/references/forms.md — 同级组件;当需要在内容旁添加字段控件/按钮时,请选择表单(表单与embed的选择决策)
- ../component-wiring-check/references/component-wiring.md — 宿主参考约定、变量必须声明规则、打开embed的组件的规则
moduleId
Dependencies
依赖技能
- skill — invoked to produce a requirements brief if one doesn't already exist in the conversation context
requirements-gathering - skill — invoked when the requirement actually needs field controls or a toolbar next to the content (an embed is iframe-only; it has no button surface)
form-creator - skill — invoked to audit the
component-wiring-check↔configParameterscontract on the component that opens the embed before pushinParams
- 技能 — 如果对话上下文不存在需求简报,将调用该技能生成需求简报
requirements-gathering - 技能 — 当需求需要在内容旁添加字段控件或工具栏时调用(embed仅包含iframe;无按钮界面)
form-creator - 技能 — 在推送前调用,审核打开embed的组件上的
component-wiring-check↔configParameters约定inParams
CLI Lifecycle
CLI 生命周期
Embed 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), mapping to .
dxs configurationdxs embedembedconfigurationTypeId: 20Create a new embed:
bash
undefinedEmbed创作通过完成——这是针对所有平台配置类型的通用CRUD原语。没有子命令,也不支持字段级补丁;你需要构建(或获取并提取)完整的JSON体,编辑后再完整推送回去。CLI中的类型标识符为****(小写),对应。
dxs configurationdxs embedembedconfigurationTypeId: 20创建新的embed:
bash
undefined1. Build body.json from scratch (see references/embeds.md → Minimal Valid Skeleton)
1. 从头构建body.json(参考references/embeds.md → 最小有效骨架)
2. Validate — gates the push; exit 1 = errors found, not a broken CLI. Catches the "HREF is required" failure before push
2. 验证 — 作为推送的前置检查;退出码1表示发现错误,非CLI故障。在推送前捕获“HREF是必填项”错误
dxs configuration validate embed -b <branchId> -D body.json
dxs configuration validate embed -b <branchId> -D body.json
3. Create (upsert creates or updates by referenceName)
3. 创建(upsert会根据referenceName创建或更新)
dxs configuration upsert embed -b <branchId> -D body.json
**Edit an existing embed:**
```bashdxs configuration upsert embed -b <branchId> -D body.json
**编辑现有embed:**
```bash1. Fetch — note the envelope wrapper
1. 获取 — 注意信封包装
dxs configuration get embed <configId> -b <branchId> -O envelope.json
dxs configuration get embed <configId> -b <branchId> -O envelope.json
2. EXTRACT THE INNER BODY (round-trip footgun guard)
2. 提取内部JSON体(防止往返操作陷阱)
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 embed -b <branchId> -D body.json
dxs configuration validate embed -b <branchId> -D body.json
5. Push
5. 推送
dxs configuration upsert embed -b <branchId> -D body.json
undefineddxs configuration upsert embed -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. Always before editing. See ../datex-studio-shared/configuration-roundtrip.md for the canonical round-trip and the underlying bug.
dxs configuration upsertjq .json envelope.json > body.json编辑现有配置时,切勿直接将envelope.json通过管道传递给——这会静默销毁配置内容。编辑前务必执行。有关标准往返流程及潜在bug,请参阅../datex-studio-shared/configuration-roundtrip.md。
dxs configuration upsertjq .json envelope.json > body.jsonWorkflow
工作流程
[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection
|
[requirements brief in context?] ── NO ─> invoke `requirements-gathering`
|
[Phase 2: Embed vs Form decision]
Consult references/embeds.md → "Purpose & When to Use":
- render a URL or an HTML blob, no controls needed -> embed
- needs field inputs, a toolbar, or a Print button
that lives outside the rendered content -> form (or put the
control inside the HTML)
If field controls/toolbar are required -> invoke `form-creator` and stop here.
|
[Phase 3: Pick the source — URL or HTML string]
URL -> iframeConfig.href points at the URL (directly or via a var
computed in on_init). Example: a hosted map.
HTML string -> on_init sets a var to a data:text/html URI built from the
HTML; iframeConfig.href points at that var.
|
[Phase 4: Author embed body]
Build body.json from references/embeds.md → Minimal Valid Skeleton:
- type: "iframe" (the only supported designer type)
- iframeConfig.href (REQUIRED — a TS expression, usually $embed.vars.<url>)
- inParams[] (the URL / HTML / id the host passes in)
- vars[] (the computed href var)
- onInitFlowConfig -> on_init flow that computes the href var
|
[Phase 5: Validate + push]
dxs configuration validate embed -b <branchId> -D body.json
dxs configuration upsert embed -b <branchId> -D body.json
|
[Phase 6: Wire the opener + verify]
Caller opens it: $shell.open<referenceName>Dialog(inParamsObj, 'flyout', EModalSize.Xlarge) (+ <Package>. segment if the embed is in a module)
Verify in Studio: iframe renders; if HTML preview, the in-document Print button works
|
[invoke `post-edit-verification`; then `component-validator`][Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection
|
[requirements brief in context?] ── NO ─> invoke `requirements-gathering`
|
[Phase 2: Embed vs Form decision]
Consult references/embeds.md → "Purpose & When to Use":
- render a URL or an HTML blob, no controls needed -> embed
- needs field inputs, a toolbar, or a Print button
that lives outside the rendered content -> form (or put the
control inside the HTML)
If field controls/toolbar are required -> invoke `form-creator` and stop here.
|
[Phase 3: Pick the source — URL or HTML string]
URL -> iframeConfig.href points at the URL (directly or via a var
computed in on_init). Example: a hosted map.
HTML string -> on_init sets a var to a data:text/html URI built from the
HTML; iframeConfig.href points at that var.
|
[Phase 4: Author embed body]
Build body.json from references/embeds.md → Minimal Valid Skeleton:
- type: "iframe" (the only supported designer type)
- iframeConfig.href (REQUIRED — a TS expression, usually $embed.vars.<url>)
- inParams[] (the URL / HTML / id the host passes in)
- vars[] (the computed href var)
- onInitFlowConfig -> on_init flow that computes the href var
|
[Phase 5: Validate + push]
dxs configuration validate embed -b <branchId> -D body.json
dxs configuration upsert embed -b <branchId> -D body.json
|
[Phase 6: Wire the opener + verify]
Caller opens it: $shell.open<referenceName>Dialog(inParamsObj, 'flyout', EModalSize.Xlarge) (+ <Package>. segment if the embed is in a module)
Verify in Studio: iframe renders; if HTML preview, the in-document Print button works
|
[invoke `post-edit-verification`; then `component-validator`]Phase Details
阶段详情
Phase 2: Embed vs Form decision
阶段2:Embed与表单的决策
An embed's entire visible surface is the iframe — it has no field controls, no toolbar, and no button surface. Pick an embed when the requirement is purely "render this URL/HTML in a dialog or panel." Pick a form instead when the dialog needs inputs, a validate-then-confirm flow, or chrome (a header, a toolbar) around the content. If you need a button and rendered HTML, the pragmatic move is to put the button inside the HTML (see the Print pattern) rather than reaching for a form — a form cannot host an iframe (there is no iframe field control).
Embed的整个可见界面就是iframe——它没有字段控件、工具栏或按钮区域。当需求仅为“在对话框或面板中渲染此URL/HTML”时,选择embed。当对话框需要输入框、验证确认流程或内容周围的框架(页眉、工具栏)时,选择表单。如果需要按钮+渲染的HTML,实用的做法是将按钮放在HTML内部(请参阅打印模式),而非使用表单——表单无法承载iframe(没有iframe字段控件)。
Phase 3: Pick the source — URL or HTML string
阶段3:选择数据源 — URL或HTML字符串
iframeConfig.hrefsrcdoctypeiframepowerBi-
External URL — compute or hardcode the URL into the href var in. Build query params from
on_init.$embed.inParams -
In-memory HTML string — convert the string to aURI in
data::on_initts$embed.vars.ref_url = "data:text/html;charset=utf-8," + encodeURIComponent($embed.inParams.html);and pointatiframeConfig.href. This is the canonical way to render generated HTML (an email preview, a report proof) in a dialog. See references/embeds.md → Rendering an HTML String."$embed.vars.ref_url"
iframeConfig.hrefsrcdoctypeiframepowerBi-
外部URL — 在中计算或硬编码URL到href变量。从
on_init构建查询参数。$embed.inParams -
内存中的HTML字符串 — 在中将字符串转换为
on_initURI:data:ts$embed.vars.ref_url = "data:text/html;charset=utf-8," + encodeURIComponent($embed.inParams.html);并将指向iframeConfig.href。这是在对话框中渲染生成的HTML(邮件预览、报告样稿)的标准方式。请参阅references/embeds.md → 渲染HTML字符串。"$embed.vars.ref_url"
Phase 4: Author embed body
阶段4:编写embed JSON体
Build from references/embeds.md → Minimal Valid Skeleton. Key points:
body.json- File basics. , suffix
configurationTypeId: 20,-embed.jsonendsreferenceNameand matches the filename stem. Plus the universal checks (../datex-studio-conventions/universal-checklist.md) —_embednon-null and ≤100 chars.description - . The only codegen-supported
type: "iframe". The enum also definesEEmbedDesignerType, but it is not fully supported by codegen and is restricted in the Studio UI — never author it. Non-member values (powerBi,html,script,content) fail validation outright.code - is required and is a TypeScript expression. A bare
iframeConfig.hrefis a raw expression (unwrapped). A literal URL must be a TS string literal ($embed.vars.ref_url) — but prefer computing it in"'https://example.com'"and binding the var, as the URL almost always depends onon_init. See ../datex-studio-conventions/file-format.md → Declarative String Values Are TypeScript Expressions.inParams - Declare every you write. The href var (and any other) must appear in top-level
$embed.vars.<id>, or the write fails. Same rule as editors/forms.vars[] - computes the href. The
on_initflow (aonInitFlowConfigembedded flow) is where you readconfigurationTypeId: 9, build the URL or$embed.inParamsURI, and assign the href var.data:
根据references/embeds.md → 最小有效骨架构建。关键点:
body.json- 文件基础。,后缀为
configurationTypeId: 20,-embed.json以referenceName结尾且与文件名主干匹配。加上通用检查项(../datex-studio-conventions/universal-checklist.md)——_embed非空且长度≤100字符。description - 。唯一受代码生成支持的
type: "iframe"。枚举中还定义了EEmbedDesignerType,但它不受代码生成完全支持且在Studio UI中受限——切勿使用。非枚举成员值(powerBi、html、script、content)会直接验证失败。code - 是必填项,且为TypeScript表达式。裸写的
iframeConfig.href是原始表达式(无需包裹)。字面URL必须是TypeScript字符串字面量($embed.vars.ref_url)——但更推荐在"'https://example.com'"中计算并绑定变量,因为URL几乎总是依赖on_init。请参阅../datex-studio-conventions/file-format.md → 声明式字符串值为TypeScript表达式。inParams - 声明所有写入的。href变量(及其他变量)必须出现在顶层
$embed.vars.<id>中,否则写入会失败。与编辑器/表单规则相同。vars[] - 计算href。
on_init流程(onInitFlowConfig的嵌入式流程)是读取configurationTypeId: 9、构建URL或$embed.inParamsURI并分配href变量的地方。data:
Phase 6: Wire the opener + verify
阶段6:配置打开方 + 验证
The component that opens the embed (an editor flow, a hub toolbar button, a grid row action) calls the auto-generated shell method:
ts
// top-level embed (no package):
await $shell.opencustom_email_preview_embedDialog({ html: previewHtml }, 'flyout', EModalSize.Xlarge);
// embed registered under a package:
await $shell.<Package>.opencustom_email_preview_embedDialog({ html: previewHtml }, 'flyout', EModalSize.Xlarge);The method is + the embed's + (snake_case preserved). It carries a package segment only when the embed is registered under a package/module — a top-level application embed is opened as with no segment. When there is a package, is the embed's own module, not the caller's. The inParam object is generated from the embed's ; the host must carry a full contract for those inParams (and, for a packaged embed, set to the embed's package) — audit with .
openreferenceNameDialog$shell.open<referenceName>Dialog(...)<Package>inParamsconfigParametersmoduleIdcomponent-wiring-checkVerify in Studio: the iframe renders the URL/HTML; for an HTML preview, confirm the in-document Print button prints just the embedded content (see the Print pattern and its caveats).
打开embed的组件(编辑器流程、中心工具栏按钮、网格行操作)调用自动生成的shell方法:
ts
// 顶层embed(无包):
await $shell.opencustom_email_preview_embedDialog({ html: previewHtml }, 'flyout', EModalSize.Xlarge);
// 在包下注册的embed:
await $shell.<Package>.opencustom_email_preview_embedDialog({ html: previewHtml }, 'flyout', EModalSize.Xlarge);方法命名规则为 + embed的 + (保留蛇形命名)。仅当embed在包/模块下注册时,才会包含包段——顶层应用embed通过打开,无需包段。存在包时,是embed自身的模块,而非调用者的模块。入参对象由embed的生成;宿主必须为这些入参声明完整的约定(对于打包的embed,需将设置为embed的包)——通过进行审核。
openreferenceNameDialog$shell.open<referenceName>Dialog(...)<Package>inParamsconfigParametersmoduleIdcomponent-wiring-check在Studio中验证:iframe渲染URL/HTML;对于HTML预览,确认文档内的打印按钮仅打印嵌入内容(请参阅打印模式及其注意事项)。
Pre-Flight Checklist
预检查清单
Walk the full checklist in references/embeds.md → Pre-Flight Checklist. The fast version:
- File basics. , suffix
configurationTypeId: 20,-embed.jsonends inreferenceNameand matches the filename stem,_embeda distinct sentence-case display name — plus the universal checks (../datex-studio-conventions/universal-checklist.md).title - — the only codegen-supported type; never author
type: "iframe"(defined but unsupported).powerBi - present — omitting it fails with
iframeConfig.href.HREF is required - Href var declared in top-level and assigned in
vars[].on_init - HTML-string embeds build the +
data:text/html;charset=utf-8,URI; they do not rely onencodeURIComponent(...).srcdoc - Print button (if a preview) lives inside the HTML (), hidden via
onclick="window.print()"— never assume the parent can call into the iframe.@media print - Opener contract — the host declares a entry for every embed
configParameters; audit viainParam.component-wiring-check - non-null, non-empty, ≤100 chars.
description
请遵循references/embeds.md → 预检查清单中的完整清单。简化版本:
- 文件基础。,后缀为
configurationTypeId: 20,-embed.json以referenceName结尾且与文件名主干匹配,_embed为独特的句首大写显示名称——加上通用检查项(../datex-studio-conventions/universal-checklist.md)。title - — 唯一受代码生成支持的类型;切勿使用
type: "iframe"(已定义但不支持)。powerBi - 存在— 省略此项会因“HREF是必填项”验证失败;这是唯一的内容通道。
iframeConfig.href - Href变量已声明 在顶层中,并在
vars[]中赋值。on_init - HTML字符串类型的embed 构建+
data:text/html;charset=utf-8,URI;不依赖encodeURIComponent(...)。srcdoc - 打印按钮(如果是预览) 位于HTML内部(),通过
onclick="window.print()"隐藏——切勿假设父级可以调用iframe内部的方法。@media print - 打开方约定 — 宿主为每个embed的声明
inParam条目;通过configParameters审核。component-wiring-check - 非空、非空白,长度≤100字符。
description
Common Mistakes
常见错误
The authoritative symptom → cause → fix table is in references/embeds.md → Common Failure Modes. The gotchas that bite most often when authoring:
- , or a non-
srcdociframe(type/html/script), to inject markup inline — none are supported; render the HTML through acontentURI ondata:text/html.href - Omitting — fails validation with
iframeConfig.href; it is the only content channel.HREF is required - Writing without declaring it in
$embed.vars.<id>— the write fails.vars[] - Hardcoding a literal URL unwrapped in —
hrefis a TS expression; TS-quote it (href) or compute it in"'https://...'".on_init - Upserting the envelope instead of the inner — silently destroys config content;
.jsonfirst.jq .json envelope.json > body.json
After your edit, invoke to surface description/JSON/schema violations. For a final review, invoke .
post-edit-verificationcomponent-validator权威的症状→原因→修复表格位于references/embeds.md → 常见故障模式。创作时最常遇到的陷阱:
- 使用或非
srcdoc类型(iframe/html/script)内联注入标记 — 均不支持;通过content上的hrefURI渲染HTML。data:text/html - 省略— 验证失败,提示“HREF是必填项”;这是唯一的内容通道。
iframeConfig.href - 写入但未在
$embed.vars.<id>中声明 — 写入操作失败。vars[] - 在中未包裹硬编码的字面URL —
href是TypeScript表达式;需用TS引号包裹(href)或在"'https://...'"中计算。on_init - 直接upsert信封而非内部— 静默销毁配置内容;先执行
.json。jq .json envelope.json > body.json
编辑完成后,调用以发现描述/JSON/架构违规。最终审核请调用。",
post-edit-verificationcomponent-validator