[API explorer] Replace raw x-state badges with applies_to popover#3026
Conversation
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
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds AvailabilityBadgeHelper and AvailabilityBadgeData to parse OpenAPI 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
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (5)
src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cssrc/Elastic.ApiExplorer/Operations/OperationView.cshtmlsrc/Elastic.ApiExplorer/Schema/RenderContext.cssrc/Elastic.ApiExplorer/Shared/_PropertyItem.cshtmlsrc/Elastic.ApiExplorer/Shared/_UnionOptions.cshtml
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
Mpdreamz
left a comment
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs
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
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
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
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs (1)
147-156:⚠️ Potential issue | 🟡 MinorStill 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.Instanceguard at line 122 is false, so the block is skippedshowLifecycleName = 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
📒 Files selected for processing (1)
src/Elastic.ApiExplorer/Operations/AvailabilityBadgeHelper.cs
Made-with: Cursor

Summary
Relates to https://github.com/elastic/docs-eng-team/issues/452
x-statestring badges (<span class="version-badge">) with structured<applies-to-popover>web component badges on API explorer endpoint pagesx-stateinto lifecycle (GA, Preview, Beta, Deprecated, Removed) and version data using the same logic asOpenApiDocumentExporterChanges
AvailabilityBadgeHelper.cs-- parsesx-stateextensions and produces badge attributes for the<applies-to-popover>web componentOperationView.cshtml-- replacedversion-badgespan withapplies-to-popoverbelow the h1 title; removed leftover debug spans_PropertyItem.cshtml-- same badge treatment for property-levelx-stateannotations_UnionOptions.cshtml-- propagatesVersionsConfigurationto child contextsRenderContext.cs-- added optionalVersionsConfigurationproperty toPropertyRenderContextandUnionVariantsContextNotes
x-stateshow-popover="false") -- can be enabled as a follow-upElastic.ApiExplorerMade with Cursor