Skip to content

[API explorer] Replace raw x-state badges with applies_to popover#3026

Merged
szabosteve merged 8 commits into
mainfrom
szabosteve/api-exp-exp
Apr 24, 2026
Merged

[API explorer] Replace raw x-state badges with applies_to popover#3026
szabosteve merged 8 commits into
mainfrom
szabosteve/api-exp-exp

Conversation

@szabosteve
Copy link
Copy Markdown
Contributor

@szabosteve szabosteve commented Apr 2, 2026

Summary

Relates to https://github.com/elastic/docs-eng-team/issues/452

  • Replace raw x-state string badges (<span class="version-badge">) with structured <applies-to-popover> web component badges on API explorer endpoint pages
  • Parse x-state into lifecycle (GA, Preview, Beta, Deprecated, Removed) and version data using the same logic as OpenApiDocumentExporter
  • Badges now render consistently with the rest of the documentation site

Changes

  • New: AvailabilityBadgeHelper.cs -- parses x-state extensions and produces badge attributes for the <applies-to-popover> web component
  • Edit: OperationView.cshtml -- replaced version-badge span with applies-to-popover below the h1 title; removed leftover debug spans
  • Edit: _PropertyItem.cshtml -- same badge treatment for property-level x-state annotations
  • Edit: _UnionOptions.cshtml -- propagates VersionsConfiguration to child contexts
  • Edit: RenderContext.cs -- added optional VersionsConfiguration property to PropertyRenderContext and UnionVariantsContext

Notes

  • Serverless badges are not shown because the OpenAPI specs contain no serverless availability data in x-state
  • Popover detail panel is disabled (show-popover="false") -- can be enabled as a follow-up
  • No new project dependencies added; the helper is self-contained in Elastic.ApiExplorer

Made with Cursor

Parse x-state extension values into structured lifecycle and version
data, then render them using the existing applies-to-popover web
component instead of plain version-badge spans. This makes endpoint
availability badges consistent with the rest of the documentation site.

Made-with: Cursor
@szabosteve szabosteve requested a review from a team as a code owner April 2, 2026 14:01
@szabosteve szabosteve requested review from Mpdreamz and reakaleek April 2, 2026 14:01
@coderabbitai coderabbitai Bot added the feature label Apr 2, 2026
@szabosteve szabosteve changed the title API explorer: Replace raw x-state badges with applies_to popover [API explorer] Replace raw x-state badges with applies_to popover Apr 2, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds AvailabilityBadgeHelper and AvailabilityBadgeData to parse OpenAPI x-state extensions from operations and schemas and produce structured badge info or null. The helper normalizes lifecycle terms, extracts semantic versions, parses applies-to lifecycles, and uses VersionsConfiguration to decide lifecycle/version display and CSS class. PropertyRenderContext and UnionVariantsContext gain an optional VersionsConfiguration that is propagated into nested renders. Razor views and partials call the helper and render an applies-to-popover when badge data is returned.

Sequence Diagram(s)

sequenceDiagram
    participant View as Operation/Property View
    participant OpenApi as OpenApiOperation/Schema
    participant Versions as VersionsConfiguration
    participant Helper as AvailabilityBadgeHelper
    participant Popover as applies-to-popover

    View->>OpenApi: pass operation/schema
    View->>Versions: pass VersionsConfiguration
    View->>Helper: FromOperation/FromSchema(OpenApi, Versions)
    Helper->>OpenApi: read "x-state" extension
    Helper->>Helper: normalize lifecycle, extract semver, parse applies-to
    Helper->>Versions: consult current stack/version (if needed)
    Helper-->>View: return AvailabilityBadgeData or null
    alt AvailabilityBadgeData present
        View->>Popover: render with BadgeKey, LifecycleText, Version, Flags
    else
        View-->>View: no popover rendered
    end
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: replacing raw x-state badges with applies-to-popover components throughout the API explorer.
Description check ✅ Passed The description is well-related to the changeset, clearly explaining the purpose, scope, and implementation details of replacing x-state badges with applies-to-popover components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch szabosteve/api-exp-exp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs`:
- Around line 83-103: GetCurrentStackVersion(versionsConfig) can return null and
current code treats that as "not released" causing all badges to show planned;
change the isReleased logic so a null currentVersion does not force "planned" —
set isReleased = currentVersion is null || version.Min <= currentVersion (or
equivalent) in the AvailabilityBadgeHelper flow so parsed lifecycle/version
(FormatVersion/versionDisplay, ProductLifecycle handling and the '+' TrimEnd)
are used when no stack config is available.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 724b49f4-1733-443d-9a38-018a4a843ba4

📥 Commits

Reviewing files that changed from the base of the PR and between b9765e5 and 72fdb2c.

📒 Files selected for processing (5)
  • src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs
  • src/Elastic.ApiExplorer/Operations/OperationView.cshtml
  • src/Elastic.ApiExplorer/Schema/RenderContext.cs
  • src/Elastic.ApiExplorer/Shared/_PropertyItem.cshtml
  • src/Elastic.ApiExplorer/Shared/_UnionOptions.cshtml

Comment thread src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs Outdated
Comment thread src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs
Broaden version regex from "Added in X.Y.Z" to any semver pattern so
deprecated/removed versions are also captured. Treat missing stack
version config as released rather than planned, so badges fall back
to the parsed lifecycle/version instead of mislabeling as "Planned".

Made-with: Cursor
@szabosteve szabosteve requested a review from lcawl April 15, 2026 16:17
@lcawl
Copy link
Copy Markdown
Contributor

lcawl commented Apr 16, 2026

I confirmed that the badges appear in a local test:

image

I couldn't find any at the parameter or property-level, however I didn't test exhaustively

Copy link
Copy Markdown
Member

@Mpdreamz Mpdreamz left a comment

Choose a reason for hiding this comment

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

I think it may be better to project x-state into the applies to yaml and using:

var applicableTo = YamlSerialization.Deserialize<ApplicableTo>(yaml, appliesToDirective.Build.ProductsConfiguration);

Could then continue to take on the load of parsing it properly.

… AppliesCollection

Address MPdreamz review: instead of custom ParseLifecycle/ParseVersion
methods, convert x-state strings to the lifecycle format ("ga 7.7.0",
"preview", etc.) and delegate parsing to AppliesCollection.TryParse.
This reuses the existing applies_to parsing infrastructure. A direct
reference to Elastic.Markdown is not possible (circular dependency),
so AppliesCollection from Elastic.Documentation is used directly.

Made-with: Cursor
@szabosteve szabosteve requested a review from Mpdreamz April 22, 2026 14:50
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs`:
- Around line 84-99: The current lifecycle detection collapses raw "preview" and
terminal states to GA because the "generally available" contains-check runs
before them; update the if/else order and checks in AvailabilityBadgeHelper.cs
so that explicit terminal states ("deprecated", "removed") and any "preview"
indicator are checked before "generally available", and make the GA check more
specific (e.g., match the exact phrase "generally available" rather than any
substring) to avoid historical text shadowing; keep the existing
SemVersionRegex().Match(xState) logic and return formatting but ensure the
variable lifecycle is set after the re-ordered and tightened checks (referencing
lifecycle, lower, xState, and SemVersionRegex()).
- Around line 57-62: The code currently calls
jsonNodeExtension.Node.GetValue<string>() which can throw if the node isn't a
JsonValue or isn't a string; change this to safely attempt extraction with
jsonNodeExtension.Node.TryGetValue<string>(out var stateValue) and return null
when TryGetValue returns false or when stateValue is null/empty; ensure you add
"using System.Text.Json.Nodes;" if it's not already present and update
references to the local variable name (stateValue) accordingly so the rest of
the method uses the safely obtained value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 67ee3c8f-0c71-4048-ab1b-3d9267902005

📥 Commits

Reviewing files that changed from the base of the PR and between e155b8b and dc78664.

📒 Files selected for processing (1)
  • src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs

Comment thread src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs
Comment thread src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs Outdated
szabosteve and others added 2 commits April 22, 2026 17:12
Use TryGetValue<string>() instead of GetValue<string>() to gracefully
handle malformed x-state data. Reorder lifecycle detection so terminal
states (removed, deprecated) and preview are checked before "generally
available" to prevent keyword shadowing. Also match "preview" without
requiring the "tech" prefix.

Made-with: Cursor
@Mpdreamz Mpdreamz enabled auto-merge (squash) April 24, 2026 09:59
@Mpdreamz Mpdreamz disabled auto-merge April 24, 2026 10:02
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs`:
- Around line 86-94: The switch that computes lifecycle in
AvailabilityBadgeHelper.cs should not default to "ga" for unrecognized strings;
change the default branch to yield null (or make lifecycle nullable) and then
update BuildBadgeData to return null when lifecycle is null and there is no
version (i.e., when there is nothing displayable). Specifically, modify the
switch that sets lifecycle (from the variable computed from lower) so _ => null
(or set lifecycle as string?), and ensure BuildBadgeData checks lifecycle ==
null && string.IsNullOrEmpty(version) and returns null per the method contract.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e7d3e321-b531-484b-960e-d904c64b64fc

📥 Commits

Reviewing files that changed from the base of the PR and between dc78664 and 518f274.

📒 Files selected for processing (1)
  • src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs

Comment thread src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs
Don't default to GA for strings that match no lifecycle keyword and
contain no version. Only assume GA when a version is present without
an explicit lifecycle (e.g. "Added in 7.7.0"). Unrecognized strings
with nothing displayable now produce no badge.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs (1)

147-156: ⚠️ Potential issue | 🟡 Minor

Still returns a non-null badge with nothing to render for bare "Generally available".

Tracing an x-state of "Generally available" (no semver):

  • ProjectToLifecycleFormat"ga"
  • AppliesCollection.TryParse("ga", …)GenerallyAvailable (Version = AllVersionsSpec.Instance)
  • The version is not null && version != AllVersionsSpec.Instance guard at line 122 is false, so the block is skipped
  • showLifecycleName = false (GA), showVersion = false, badgeLifecycleText = ""

Result: a badge record where every display flag is false and every text field is empty, yet the method still returns non-null, so the popover renders an empty shell. The XML summary explicitly promises "null when no displayable availability information exists."

Proposed fix
+		if (!showLifecycleName && !showVersion && string.IsNullOrEmpty(badgeLifecycleText))
+			return null;
+
 		return new AvailabilityBadgeData(
 			BadgeKey: "Stack",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs` around lines
147 - 156, The method currently returns an AvailabilityBadgeData even when there
is nothing to render (e.g., GA with AllVersionsSpec), so change the logic before
the final return to return null when no displayable info exists: check the
computed values (badgeLifecycleText, showLifecycleName, showVersion and any
versionDisplay text) and if badgeLifecycleText is empty/null and both
showLifecycleName and showVersion are false (i.e., nothing to show), return null
instead of constructing AvailabilityBadgeData; reference the local variables
badgeLifecycleText, showLifecycleName, showVersion, versionDisplay and the
AvailabilityBadgeData return to locate where to add this guard.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs`:
- Around line 147-156: The method currently returns an AvailabilityBadgeData
even when there is nothing to render (e.g., GA with AllVersionsSpec), so change
the logic before the final return to return null when no displayable info
exists: check the computed values (badgeLifecycleText, showLifecycleName,
showVersion and any versionDisplay text) and if badgeLifecycleText is empty/null
and both showLifecycleName and showVersion are false (i.e., nothing to show),
return null instead of constructing AvailabilityBadgeData; reference the local
variables badgeLifecycleText, showLifecycleName, showVersion, versionDisplay and
the AvailabilityBadgeData return to locate where to add this guard.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c0af1898-19a2-41eb-924f-da349f6ad650

📥 Commits

Reviewing files that changed from the base of the PR and between 518f274 and 0bba8d4.

📒 Files selected for processing (1)
  • src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs

@szabosteve szabosteve merged commit 7a0b6ae into main Apr 24, 2026
26 checks passed
@szabosteve szabosteve deleted the szabosteve/api-exp-exp branch April 24, 2026 12:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants