Skip to content

Fix HITL operator body losing line breaks in the approval form - #74366

Closed
Mola-maker wants to merge 4 commits into
apache:mainfrom
Mola-maker:fix-hitl-body-line-breaks
Closed

Mola-maker wants to merge 4 commits into
apache:mainfrom
Mola-maker:fix-hitl-body-line-breaks

Conversation

@Mola-maker

Copy link
Copy Markdown
Contributor

Why

The HITL (human-in-the-loop) approval form renders hitlDetail.body as Markdown via FlexibleForm's flexFormDescription. A single \n in the body is a Markdown soft break, which collapses to a space when rendered — so multi-line bodies (e.g. a dry-run result pushed through {{ ti.xcom_pull(...) }}) display as one long line, even though the Rendered Template tab shows them correctly.

This PR covers the HITL body part of #74018. The XCom tab part of the same issue is already handled separately by #74112, so this uses related: rather than closes:.

What changed

  • src/components/ReactMarkdown.tsx
    • Callers can now pass extra remarkPlugins; they are merged with the built-in remark-gfm instead of being silently overridden (previously a passed remarkPlugins prop was discarded).
    • Adds an exported, dependency-free remark plugin remarkSoftBreaks that splits text nodes on single line breaks (\n / \r\n) into explicit break nodes, which render as <br />.
  • src/components/FlexibleForm/FlexibleForm.tsx
    • Renders flexFormDescription with remarkSoftBreaks enabled. flexFormDescription is only used for the HITL operator body, so Dag docs, notes, param descriptions and all other Markdown rendering are unaffected and keep the previous soft-break behavior.
  • src/components/ReactMarkdown.test.tsx
    • New tests: single line breaks render as <br> with the plugin enabled, and keep collapsing to a space without it (default behavior unchanged).

Verification

  • pnpm vitest run src/components/FlexibleForm src/components/ReactMarkdown.test.tsx — 7 files / 50 tests pass, including the 2 new tests.
  • tsc --p tsconfig.app.json — clean.

related: #74018


Was generative AI tooling used to co-author this PR?
  • Yes — Kimi (Moonshot AI coding assistant), for implementation and tests; changes reviewed locally with the UI test suite and type checker

Generated-by: Kimi (Moonshot AI) following the guidelines

@bbovenzi

bbovenzi commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Please provide a before/after screenshot

Mola-maker added a commit to Mola-maker/airflow that referenced this pull request Oct 7, 2026
@Mola-maker

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Here are the before/after screenshots, rendered from the actual FlexibleForm/ReactMarkdown components in the repo's vitest setup, using a HITL body with a multi-line plain-text payload (the "before" shot is from main, the "after" shot from this PR branch):

Before — single line breaks collapse, the multi-line body wraps into one paragraph:

Before

After — each line of the body is preserved with remarkSoftBreaks:

After

(Test body: "[Dry-Run Ergebnis]\nDelete: /mnt/x/y/z/data/test.gdb\n...test2...test3...test4.gdb" — 5 lines; the rendered output goes from 0 <br> elements to 4.)

@bbovenzi bbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one nit

@@ -195,7 +195,48 @@ const createMarkdownComponents = (style: SyntaxTheme): Components => ({
ul: UlComponent,
});

const ReactMarkdown = ({ children, components: componentOverrides, ...restProps }: Options) => {
type MdastNode = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type MdastNode = {
type MarkdownNode = {

Nit. A more readable name here would help.

@bbovenzi

bbovenzi commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Also let's fix the CI

@Mola-maker
Mola-maker requested a review from bbovenzi October 8, 2026 02:25
@Zhnz

Zhnz commented Oct 8, 2026 •

Copy link
Copy Markdown

I just want to hint to my comment on the main issue. If the HITLOperator body actually renders Markdown, then the current behaviour would be correct, wouldn't it? The issue I had in this case then is not realizing, that the body is rendered in Markdown, which is mentioned nowhere on the HITLOperator tutorial. Implementing this PR would therefore break the Markdown support, which is actually mentioned here.

@bbovenzi

bbovenzi commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

I just want to hint to my comment on the main issue. If the HITLOperator body actually renders Markdown, then the current behaviour would be correct, wouldn't it? The issue I had in this case then is not realizing, that the body is rendered in Markdown, which is mentioned nowhere on the HITLOperator tutorial. Implementing this PR would therefore break the Markdown support, which is actually mentioned here.

Good point. Let's update the docs first.

@bbovenzi bbovenzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's update docs before all of this remarkSoftBreaks

@pierrejeambrun

Copy link
Copy Markdown
Member

Can't reproduce on main, #66809 fixed it.

Closing as stale we just need to update the doc:

@Mola-maker

Copy link
Copy Markdown
Contributor Author

well,ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UI Related to UI/UX. For Frontend Developers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants