embed-creator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Embed Creator

Embed 组件创建工具

Author or modify a Datex Studio embed (configurationTypeId=20) on a branch — a thin UI component whose entire surface is a single
<iframe>
. 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
$shell.open<referenceName>Dialog(...)
(prefixed with the embed's package when it's registered under a module).
在分支上创作或修改Datex Studio embed(configurationTypeId=20)——这是一个轻量UI组件,其整个界面就是单个
<iframe>
。Embed可渲染外部URL(托管的地图、仪表盘、文档查看器)或内存中的HTML字符串(生成的邮件/报告预览),几乎总是通过
$shell.open<referenceName>Dialog(...)
以对话框形式打开(当embed在模块下注册时,需添加其包名前缀)。

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
    data:
    URI HTML-string pattern, dialog wiring, the print pattern, CSP caveats, pre-flight checklist
  • ../datex-studio-conventions/file-format.md
    configurationTypeId
    table and the TypeScript-expression encoding rule (applies to
    iframeConfig.href
    )
  • ../datex-studio-conventions/naming-conventions.md
    _embed
    /
    -embed
    suffix, filename-stem matching, display-name rule
  • ../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,
    moduleId
    rule for the component that opens the embed
  • ../datex-studio-shared/branch-setup.md — 分支/连接选择(所有技能共享)
  • references/embeds.md — 权威的Embed创作参考:文件结构、最小有效骨架、仅iframe规则、
    data:
    URI HTML字符串模式、对话框连接方式、打印模式、CSP注意事项、预检查清单
  • ../datex-studio-conventions/file-format.md
    configurationTypeId
    表格和TypeScript表达式编码规则(适用于
    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

依赖技能

  • requirements-gathering
    skill — invoked to produce a requirements brief if one doesn't already exist in the conversation context
  • form-creator
    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)
  • component-wiring-check
    skill — invoked to audit the
    configParameters
    inParams
    contract on the component that opens the embed before push
  • requirements-gathering
    技能 — 如果对话上下文不存在需求简报,将调用该技能生成需求简报
  • form-creator
    技能 — 当需求需要在内容旁添加字段控件或工具栏时调用(embed仅包含iframe;无按钮界面)
  • component-wiring-check
    技能 — 在推送前调用,审核打开embed的组件上的
    configParameters
    inParams
    约定

CLI Lifecycle

CLI 生命周期

Embed authoring goes through
dxs configuration
— the generic CRUD primitive over every platform configuration type. There is no
dxs embed
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
embed
(lowercase), mapping to
configurationTypeId: 20
.
Create a new embed:
bash
undefined
Embed创作通过
dxs configuration
完成——这是针对所有平台配置类型的通用CRUD原语。没有
dxs embed
子命令,也不支持字段级补丁;你需要构建(或获取并提取)完整的JSON体,编辑后再完整推送回去。CLI中的类型标识符为**
embed
**(小写),对应
configurationTypeId: 20
创建新的embed:
bash
undefined

1. 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:**

```bash
dxs configuration upsert embed -b <branchId> -D body.json

**编辑现有embed:**

```bash

1. 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
undefined
dxs configuration upsert embed -b <branchId> -D body.json
undefined

Round-trip rule (critical)

往返操作规则(关键)

When editing an existing config, never pipe the envelope.json directly into
dxs configuration upsert
— it silently destroys configuration content. Always
jq .json envelope.json > body.json
before editing. See ../datex-studio-shared/configuration-roundtrip.md for the canonical round-trip and the underlying bug.
编辑现有配置时,切勿直接将envelope.json通过管道传递给
dxs configuration upsert
——这会静默销毁配置内容。编辑前务必执行
jq .json envelope.json > body.json
。有关标准往返流程及潜在bug,请参阅../datex-studio-shared/configuration-roundtrip.md

Workflow

工作流程

[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.href
is the only content channel. There is no
srcdoc
and no inline-HTML embed type — for this skill
type
is always
iframe
(the enum's other member,
powerBi
, is unsupported by codegen and restricted in the Studio UI; see Common Mistakes). So:
  • External URL — compute or hardcode the URL into the href var in
    on_init
    . Build query params from
    $embed.inParams
    .
  • In-memory HTML string — convert the string to a
    data:
    URI in
    on_init
    :
    ts
    $embed.vars.ref_url = "data:text/html;charset=utf-8," + encodeURIComponent($embed.inParams.html);
    and point
    iframeConfig.href
    at
    "$embed.vars.ref_url"
    . 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.
iframeConfig.href
是唯一的内容通道。不支持
srcdoc
,也不支持内联HTML embed类型——对于本技能,
type
始终为
iframe
(枚举中的另一个成员
powerBi
不被代码生成支持,且在Studio UI中受限;请参阅常见错误)。因此:
  • 外部URL — 在
    on_init
    中计算或硬编码URL到href变量。从
    $embed.inParams
    构建查询参数。
  • 内存中的HTML字符串 — 在
    on_init
    中将字符串转换为
    data:
    URI:
    ts
    $embed.vars.ref_url = "data:text/html;charset=utf-8," + encodeURIComponent($embed.inParams.html);
    并将
    iframeConfig.href
    指向
    "$embed.vars.ref_url"
    。这是在对话框中渲染生成的HTML(邮件预览、报告样稿)的标准方式。请参阅references/embeds.md → 渲染HTML字符串

Phase 4: Author embed body

阶段4:编写embed JSON体

Build
body.json
from references/embeds.md → Minimal Valid Skeleton. Key points:
  1. File basics.
    configurationTypeId: 20
    , suffix
    -embed.json
    ,
    referenceName
    ends
    _embed
    and matches the filename stem. Plus the universal checks (../datex-studio-conventions/universal-checklist.md) —
    description
    non-null and ≤100 chars.
  2. type: "iframe"
    .
    The only codegen-supported
    EEmbedDesignerType
    . The enum also defines
    powerBi
    , but it is not fully supported by codegen and is restricted in the Studio UI — never author it. Non-member values (
    html
    ,
    script
    ,
    content
    ,
    code
    ) fail validation outright.
  3. iframeConfig.href
    is required and is a TypeScript expression.
    A bare
    $embed.vars.ref_url
    is a raw expression (unwrapped). A literal URL must be a TS string literal (
    "'https://example.com'"
    ) — but prefer computing it in
    on_init
    and binding the var, as the URL almost always depends on
    inParams
    . See ../datex-studio-conventions/file-format.md → Declarative String Values Are TypeScript Expressions.
  4. Declare every
    $embed.vars.<id>
    you write.
    The href var (and any other) must appear in top-level
    vars[]
    , or the write fails. Same rule as editors/forms.
  5. on_init
    computes the href.
    The
    onInitFlowConfig
    flow (a
    configurationTypeId: 9
    embedded flow) is where you read
    $embed.inParams
    , build the URL or
    data:
    URI, and assign the href var.
根据references/embeds.md → 最小有效骨架构建
body.json
。关键点:
  1. 文件基础
    configurationTypeId: 20
    ,后缀为
    -embed.json
    referenceName
    _embed
    结尾且与文件名主干匹配。加上通用检查项(../datex-studio-conventions/universal-checklist.md)——
    description
    非空且长度≤100字符。
  2. type: "iframe"
    。唯一受代码生成支持的
    EEmbedDesignerType
    。枚举中还定义了
    powerBi
    ,但它不受代码生成完全支持且在Studio UI中受限——切勿使用。非枚举成员值(
    html
    script
    content
    code
    )会直接验证失败。
  3. iframeConfig.href
    是必填项,且为TypeScript表达式
    。裸写的
    $embed.vars.ref_url
    是原始表达式(无需包裹)。字面URL必须是TypeScript字符串字面量(
    "'https://example.com'"
    )——但更推荐在
    on_init
    中计算并绑定变量,因为URL几乎总是依赖
    inParams
    。请参阅../datex-studio-conventions/file-format.md → 声明式字符串值为TypeScript表达式
  4. 声明所有写入的
    $embed.vars.<id>
    。href变量(及其他变量)必须出现在顶层
    vars[]
    中,否则写入会失败。与编辑器/表单规则相同。
  5. on_init
    计算href
    onInitFlowConfig
    流程(
    configurationTypeId: 9
    的嵌入式流程)是读取
    $embed.inParams
    、构建URL或
    data:
    URI并分配href变量的地方。

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
open
+ the embed's
referenceName
+
Dialog
(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
$shell.open<referenceName>Dialog(...)
with no segment. When there is a package,
<Package>
is the embed's own module, not the caller's. The inParam object is generated from the embed's
inParams
; the host must carry a full
configParameters
contract for those inParams (and, for a packaged embed, set
moduleId
to the embed's package) — audit with
component-wiring-check
.
Verify 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);
方法命名规则为
open
+ embed的
referenceName
+
Dialog
(保留蛇形命名)。仅当embed在包/模块下注册时,才会包含包段——顶层应用embed通过
$shell.open<referenceName>Dialog(...)
打开,无需包段。存在包时,
<Package>
embed自身的模块,而非调用者的模块。入参对象由embed的
inParams
生成;宿主必须为这些入参声明完整的
configParameters
约定(对于打包的embed,需将
moduleId
设置为embed的包)——通过
component-wiring-check
进行审核。
在Studio中验证:iframe渲染URL/HTML;对于HTML预览,确认文档内的打印按钮仅打印嵌入内容(请参阅打印模式及其注意事项)。

Pre-Flight Checklist

预检查清单

Walk the full checklist in references/embeds.md → Pre-Flight Checklist. The fast version:
  1. File basics.
    configurationTypeId: 20
    , suffix
    -embed.json
    ,
    referenceName
    ends in
    _embed
    and matches the filename stem,
    title
    a distinct sentence-case display name — plus the universal checks (../datex-studio-conventions/universal-checklist.md).
  2. type: "iframe"
    — the only codegen-supported type; never author
    powerBi
    (defined but unsupported).
  3. iframeConfig.href
    present
    — omitting it fails with
    HREF is required
    .
  4. Href var declared in top-level
    vars[]
    and assigned in
    on_init
    .
  5. HTML-string embeds build the
    data:text/html;charset=utf-8,
    +
    encodeURIComponent(...)
    URI; they do not rely on
    srcdoc
    .
  6. Print button (if a preview) lives inside the HTML (
    onclick="window.print()"
    ), hidden via
    @media print
    — never assume the parent can call into the iframe.
  7. Opener contract — the host declares a
    configParameters
    entry for every embed
    inParam
    ; audit via
    component-wiring-check
    .
  8. description
    non-null, non-empty, ≤100 chars.
请遵循references/embeds.md → 预检查清单中的完整清单。简化版本:
  1. 文件基础
    configurationTypeId: 20
    ,后缀为
    -embed.json
    referenceName
    _embed
    结尾且与文件名主干匹配,
    title
    为独特的句首大写显示名称——加上通用检查项(../datex-studio-conventions/universal-checklist.md)。
  2. type: "iframe"
    — 唯一受代码生成支持的类型;切勿使用
    powerBi
    (已定义但不支持)。
  3. 存在
    iframeConfig.href
    — 省略此项会因“HREF是必填项”验证失败;这是唯一的内容通道。
  4. Href变量已声明 在顶层
    vars[]
    中,并在
    on_init
    中赋值。
  5. HTML字符串类型的embed 构建
    data:text/html;charset=utf-8,
    +
    encodeURIComponent(...)
    URI;不依赖
    srcdoc
  6. 打印按钮(如果是预览) 位于HTML内部(
    onclick="window.print()"
    ),通过
    @media print
    隐藏——切勿假设父级可以调用iframe内部的方法。
  7. 打开方约定 — 宿主为每个embed的
    inParam
    声明
    configParameters
    条目;通过
    component-wiring-check
    审核。
  8. description
    非空、非空白,长度≤100字符。

Common Mistakes

常见错误

The authoritative symptom → cause → fix table is in references/embeds.md → Common Failure Modes. The gotchas that bite most often when authoring:
  • srcdoc
    , or a non-
    iframe
    type
    (
    html
    /
    script
    /
    content
    ), to inject markup inline
    — none are supported; render the HTML through a
    data:text/html
    URI on
    href
    .
  • Omitting
    iframeConfig.href
    — fails validation with
    HREF is required
    ; it is the only content channel.
  • Writing
    $embed.vars.<id>
    without declaring it in
    vars[]
    — the write fails.
  • Hardcoding a literal URL unwrapped in
    href
    href
    is a TS expression; TS-quote it (
    "'https://...'"
    ) or compute it in
    on_init
    .
  • Upserting the envelope instead of the inner
    .json
    — silently destroys config content;
    jq .json envelope.json > body.json
    first.
After your edit, invoke
post-edit-verification
to surface description/JSON/schema violations. For a final review, invoke
component-validator
.
权威的症状→原因→修复表格位于references/embeds.md → 常见故障模式。创作时最常遇到的陷阱:
  • 使用
    srcdoc
    或非
    iframe
    类型(
    html
    /
    script
    /
    content
    )内联注入标记
    — 均不支持;通过
    href
    上的
    data:text/html
    URI渲染HTML。
  • 省略
    iframeConfig.href
    — 验证失败,提示“HREF是必填项”;这是唯一的内容通道。
  • 写入
    $embed.vars.<id>
    但未在
    vars[]
    中声明
    — 写入操作失败。
  • href
    中未包裹硬编码的字面URL
    href
    是TypeScript表达式;需用TS引号包裹(
    "'https://...'"
    )或在
    on_init
    中计算。
  • 直接upsert信封而非内部
    .json
    — 静默销毁配置内容;先执行
    jq .json envelope.json > body.json
编辑完成后,调用
post-edit-verification
以发现描述/JSON/架构违规。最终审核请调用
component-validator
",