From 5853c59f9f9001b809e707beacb9ac6ff06785a5 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 17 Sep 2025 14:54:54 +0200 Subject: [PATCH 01/11] Combine applies_to badges with the same key --- .../Myst/Components/ApplicabilityItem.cs | 22 ++++- .../Myst/Components/ApplicabilityMappings.cs | 1 + .../Myst/Components/ApplicabilityRenderer.cs | 87 ++++++++++++++++ .../Components/ApplicableToComponent.cshtml | 2 +- .../Myst/Components/ApplicableToViewModel.cs | 98 ++++++++++++++++--- .../Applicability/ApplicableToComponent.fs | 19 ++-- tests/authoring/Inline/AppliesToRole.fs | 21 ++-- 7 files changed, 210 insertions(+), 40 deletions(-) diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs index d5a71f78b..5bca967b0 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs @@ -8,6 +8,22 @@ namespace Elastic.Markdown.Myst.Components; public record ApplicabilityItem( string Key, - Applicability Applicability, - ApplicabilityRenderer.ApplicabilityRenderData RenderData -); + Applicability PrimaryApplicability, + IReadOnlyList AllApplicabilities, + ApplicabilityRenderer.ApplicabilityRenderData RenderData, + ApplicabilityMappings.ApplicabilityDefinition ApplicabilityDefinition +) +{ + public ApplicabilityItem(string key, Applicability applicability, ApplicabilityRenderer.ApplicabilityRenderData renderData) + : this(key, applicability, [applicability], renderData, GetDefaultDefinition(key)) { } + + public Applicability Applicability => PrimaryApplicability; + + private static ApplicabilityMappings.ApplicabilityDefinition GetDefaultDefinition(string key) => + key switch + { + "Stack" => ApplicabilityMappings.Stack, + "Serverless" => ApplicabilityMappings.Serverless, + _ => ApplicabilityMappings.Product + }; +} diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityMappings.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityMappings.cs index 138b04a0f..50aa3bbad 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityMappings.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityMappings.cs @@ -54,4 +54,5 @@ public record ApplicabilityDefinition(string Key, string DisplayName, Versioning // Generic product public static readonly ApplicabilityDefinition Product = new("", "", VersioningSystemId.All); + } diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs index 87a683c89..6fb621a1f 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs @@ -46,6 +46,93 @@ public ApplicabilityRenderData RenderApplicability( ); } + public ApplicabilityRenderData RenderCombinedApplicability( + IEnumerable applicabilities, + ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition, + VersioningSystem versioningSystem, + AppliesCollection allApplications) + { + var applicabilityList = applicabilities.ToList(); + var primaryApplicability = GetPrimaryApplicability(applicabilityList, versioningSystem); + + var primaryRenderData = RenderApplicability(primaryApplicability, applicabilityDefinition, versioningSystem, allApplications); + var combinedTooltip = BuildCombinedTooltipText(applicabilityList, applicabilityDefinition, versioningSystem); + + return primaryRenderData with { TooltipText = combinedTooltip }; + } + + private static Applicability GetPrimaryApplicability(List applicabilities, VersioningSystem versioningSystem) + { + var lifecycleOrder = new Dictionary + { + [ProductLifecycle.GenerallyAvailable] = 0, + [ProductLifecycle.Beta] = 1, + [ProductLifecycle.TechnicalPreview] = 2, + [ProductLifecycle.Planned] = 3, + [ProductLifecycle.Deprecated] = 4, + [ProductLifecycle.Removed] = 5, + [ProductLifecycle.Unavailable] = 6 + }; + + var availableApplicabilities = applicabilities + .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current) + .ToList(); + + if (availableApplicabilities.Count != 0) + { + return availableApplicabilities + .OrderByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) + .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) + .First(); + } + + var futureApplicabilities = applicabilities + .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > versioningSystem.Current) + .ToList(); + + if (futureApplicabilities.Count != 0) + { + return futureApplicabilities + .OrderBy(a => a.Version!.CompareTo(versioningSystem.Current)) + .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) + .First(); + } + + return applicabilities.First(); + } + + private static string BuildCombinedTooltipText( + List applicabilities, + ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition, + VersioningSystem versioningSystem) + { + var tooltipParts = new List(); + + // Order by the same logic as primary selection: available first (by version desc), then future (by version asc) + var orderedApplicabilities = applicabilities + .OrderByDescending(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current ? 1 : 0) + .ThenByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) + .ThenBy(a => a.Version ?? new SemVersion(0, 0, 0)); + + foreach (var applicability in orderedApplicabilities) + { + var realVersion = TryGetRealVersion(applicability, out var v) ? v : null; + var lifecycleFull = GetLifecycleFullText(applicability.Lifecycle); + var heading = CreateApplicabilityHeading(applicability, applicabilityDefinition, realVersion); + var tooltipText = BuildTooltipText(applicability, applicabilityDefinition, versioningSystem, realVersion, lifecycleFull); + tooltipParts.Add($"{heading}\n{tooltipText}"); + } + + return string.Join("\n\n", tooltipParts); + } + + private static string CreateApplicabilityHeading(Applicability applicability, ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition, SemVersion? realVersion) + { + var lifecycleName = applicability.GetLifeCycleName(); + var versionText = realVersion is not null ? $" {realVersion}" : ""; + return $"{applicabilityDefinition.DisplayName} {lifecycleName}{versionText}:"; + } + private static string GetLifecycleFullText(ProductLifecycle lifecycle) => lifecycle switch { ProductLifecycle.GenerallyAvailable => "Available", diff --git a/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml b/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml index f35d221e9..7f0d004f4 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml +++ b/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml @@ -12,7 +12,7 @@ @if (item.RenderData.ShowLifecycleName) { - @item.Applicability.GetLifeCycleName() + @item.PrimaryApplicability.GetLifeCycleName() } @if (item.RenderData.ShowVersion) { diff --git a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs index ef50735ab..1e4784eac 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs @@ -2,6 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using Elastic.Documentation; using Elastic.Documentation.AppliesTo; using Elastic.Documentation.Configuration.Versions; @@ -15,7 +16,6 @@ public class ApplicableToViewModel public required ApplicableTo AppliesTo { get; init; } public required VersionsConfiguration VersionsConfig { get; init; } - // Dictionary mapping property selectors to their applicability definitions private static readonly Dictionary, ApplicabilityMappings.ApplicabilityDefinition> DeploymentMappings = new() { [d => d.Ess] = ApplicabilityMappings.Ech, @@ -56,15 +56,14 @@ public class ApplicableToViewModel [p => p.ApmAgentRum] = ApplicabilityMappings.ApmAgentRum }; + public IEnumerable GetApplicabilityItems() { var items = new List(); - // Process Stack if (AppliesTo.Stack is not null) items.AddRange(ProcessSingleCollection(AppliesTo.Stack, ApplicabilityMappings.Stack)); - // Process Serverless if (AppliesTo.Serverless is not null) { items.AddRange(AppliesTo.Serverless.AllProjects is not null @@ -72,24 +71,18 @@ public IEnumerable GetApplicabilityItems() : ProcessMappedCollections(AppliesTo.Serverless, ServerlessMappings)); } - // Process Deployment if (AppliesTo.Deployment is not null) items.AddRange(ProcessMappedCollections(AppliesTo.Deployment, DeploymentMappings)); - // Process Product Applicability if (AppliesTo.ProductApplicability is not null) items.AddRange(ProcessMappedCollections(AppliesTo.ProductApplicability, ProductMappings)); - // Process Generic Product if (AppliesTo.Product is not null) items.AddRange(ProcessSingleCollection(AppliesTo.Product, ApplicabilityMappings.Product)); - return items; + return CombineItemsByKey(items); } - /// - /// Processes a single collection with its corresponding applicability definition - /// private IEnumerable ProcessSingleCollection(AppliesCollection collection, ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition) { var versioningSystem = VersionsConfig.GetVersioningSystem(applicabilityDefinition.VersioningSystemId); @@ -97,7 +90,7 @@ private IEnumerable ProcessSingleCollection(AppliesCollection } /// - /// Processes multiple collections using a mapping dictionary to eliminate repetitive code + /// Uses mapping dictionary to eliminate repetitive code when processing multiple collections /// private IEnumerable ProcessMappedCollections(T source, Dictionary, ApplicabilityMappings.ApplicabilityDefinition> mappings) { @@ -127,9 +120,88 @@ private IEnumerable ProcessApplicabilityCollection( return new ApplicabilityItem( Key: applicabilityDefinition.Key, - Applicability: applicability, - RenderData: renderData + PrimaryApplicability: applicability, + AllApplicabilities: [applicability], + RenderData: renderData, + ApplicabilityDefinition: applicabilityDefinition ); }); + /// + /// Combines multiple applicability items with the same key into a single item with combined tooltip + /// + private IEnumerable CombineItemsByKey(List items) => items + .GroupBy(item => item.Key) + .Select(group => + { + if (group.Count() == 1) + return group.First(); + + var firstItem = group.First(); + var allApplicabilities = group.Select(g => g.Applicability).ToList(); + var applicabilityDefinition = firstItem.ApplicabilityDefinition; + var versioningSystem = VersionsConfig.GetVersioningSystem(applicabilityDefinition.VersioningSystemId); + + var combinedRenderData = _applicabilityRenderer.RenderCombinedApplicability( + allApplicabilities, + applicabilityDefinition, + versioningSystem, + new AppliesCollection(allApplicabilities.ToArray())); + + // Select the closest version to current as the primary display + var primaryApplicability = GetPrimaryApplicability(allApplicabilities, versioningSystem); + + return new ApplicabilityItem( + Key: firstItem.Key, + PrimaryApplicability: primaryApplicability, + AllApplicabilities: allApplicabilities, + RenderData: combinedRenderData, + ApplicabilityDefinition: applicabilityDefinition + ); + }); + + + /// + /// Selects the most relevant applicability for display: available versions first (highest version), then closest future version + /// + private static Applicability GetPrimaryApplicability(List applicabilities, VersioningSystem versioningSystem) + { + var lifecycleOrder = new Dictionary + { + [ProductLifecycle.GenerallyAvailable] = 0, + [ProductLifecycle.Beta] = 1, + [ProductLifecycle.TechnicalPreview] = 2, + [ProductLifecycle.Planned] = 3, + [ProductLifecycle.Deprecated] = 4, + [ProductLifecycle.Removed] = 5, + [ProductLifecycle.Unavailable] = 6 + }; + + var availableApplicabilities = applicabilities + .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current) + .ToList(); + + if (availableApplicabilities.Count != 0) + { + return availableApplicabilities + .OrderByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) + .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) + .First(); + } + + var futureApplicabilities = applicabilities + .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > versioningSystem.Current) + .ToList(); + + if (futureApplicabilities.Count != 0) + { + return futureApplicabilities + .OrderBy(a => a.Version!.CompareTo(versioningSystem.Current)) + .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) + .First(); + } + + return applicabilities.First(); + } + } diff --git a/tests/authoring/Applicability/ApplicableToComponent.fs b/tests/authoring/Applicability/ApplicableToComponent.fs index fc6c07223..12f30772d 100644 --- a/tests/authoring/Applicability/ApplicableToComponent.fs +++ b/tests/authoring/Applicability/ApplicableToComponent.fs @@ -396,7 +396,7 @@ This functionality may be changed or removed in a future release. Elastic will w type ``mixed lifecycles with ga planned`` () = static let markdown = Setup.Markdown """ ```{applies_to} -stack: ga 8.8.0, preview 9.0.0 +stack: ga 8.8.0, preview 8.1.0 ``` """ @@ -404,18 +404,15 @@ stack: ga 8.8.0, preview 9.0.0 let ``renders GA planned when preview exists alongside GA`` () = markdown |> convertsToHtml """

- - Stack - - - Planned - - - +Elastic Stack Preview 8.1.0: +We plan to add this functionality in a future Elastic Stack update. Subject to change. + +This functionality may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features."> Stack diff --git a/tests/authoring/Inline/AppliesToRole.fs b/tests/authoring/Inline/AppliesToRole.fs index 9ecfb8193..2450d5af7 100644 --- a/tests/authoring/Inline/AppliesToRole.fs +++ b/tests/authoring/Inline/AppliesToRole.fs @@ -137,26 +137,23 @@ This is an inline {applies_to}`stack: preview 9.0, ga 9.1` element. )) [] - let ``validate HTML: generates link and alt attr`` () = + let ``validate HTML: generates single combined badge`` () = markdown |> convertsToHtml """

This is an inline - - Stack - - - GA planned - - - Stack - - Planned + + GA planned From 2a6afcb14094144af013fc21f4343ac48a56b024 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 17 Sep 2025 15:06:22 +0200 Subject: [PATCH 02/11] Simplify --- .../Myst/Components/ApplicabilityItem.cs | 12 ------------ .../Myst/Components/ApplicableToViewModel.cs | 2 -- 2 files changed, 14 deletions(-) diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs index 5bca967b0..348009ad3 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityItem.cs @@ -9,21 +9,9 @@ namespace Elastic.Markdown.Myst.Components; public record ApplicabilityItem( string Key, Applicability PrimaryApplicability, - IReadOnlyList AllApplicabilities, ApplicabilityRenderer.ApplicabilityRenderData RenderData, ApplicabilityMappings.ApplicabilityDefinition ApplicabilityDefinition ) { - public ApplicabilityItem(string key, Applicability applicability, ApplicabilityRenderer.ApplicabilityRenderData renderData) - : this(key, applicability, [applicability], renderData, GetDefaultDefinition(key)) { } - public Applicability Applicability => PrimaryApplicability; - - private static ApplicabilityMappings.ApplicabilityDefinition GetDefaultDefinition(string key) => - key switch - { - "Stack" => ApplicabilityMappings.Stack, - "Serverless" => ApplicabilityMappings.Serverless, - _ => ApplicabilityMappings.Product - }; } diff --git a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs index 1e4784eac..b4faeb0c0 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs @@ -121,7 +121,6 @@ private IEnumerable ProcessApplicabilityCollection( return new ApplicabilityItem( Key: applicabilityDefinition.Key, PrimaryApplicability: applicability, - AllApplicabilities: [applicability], RenderData: renderData, ApplicabilityDefinition: applicabilityDefinition ); @@ -154,7 +153,6 @@ private IEnumerable CombineItemsByKey(List return new ApplicabilityItem( Key: firstItem.Key, PrimaryApplicability: primaryApplicability, - AllApplicabilities: allApplicabilities, RenderData: combinedRenderData, ApplicabilityDefinition: applicabilityDefinition ); From 824dda257cd47462d70adee9c138d575dd92233e Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 18 Sep 2025 14:40:19 +0200 Subject: [PATCH 03/11] Extract duplicated GetPrimaryApplicability method to ApplicabilitySelector utility class - Created new ApplicabilitySelector class in Elastic.Documentation.AppliesTo namespace - Removed duplicated GetPrimaryApplicability method from ApplicabilityRenderer and ApplicableToViewModel - Updated both classes to use the new utility class - Improves code reusability and reduces duplication --- .../AppliesTo/ApplicabilitySelector.cs | 60 +++++++++++++++++++ .../Myst/Components/ApplicabilityRenderer.cs | 41 +------------ .../Myst/Components/ApplicableToViewModel.cs | 44 +------------- 3 files changed, 62 insertions(+), 83 deletions(-) create mode 100644 src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs diff --git a/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs b/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs new file mode 100644 index 000000000..f73543905 --- /dev/null +++ b/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs @@ -0,0 +1,60 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using Elastic.Documentation.Configuration.Versions; + +namespace Elastic.Documentation.AppliesTo; + +///

+/// Utility class for selecting the most relevant applicability from a collection of applicabilities. +/// +public static class ApplicabilitySelector +{ + /// + /// Selects the most relevant applicability for display: available versions first (highest version), then closest future version + /// + /// The collection of applicabilities to select from + /// The versioning system to use for comparison + /// The most relevant applicability for display + public static Applicability GetPrimaryApplicability(IEnumerable applicabilities, VersioningSystem versioningSystem) + { + var applicabilityList = applicabilities.ToList(); + var lifecycleOrder = new Dictionary + { + [ProductLifecycle.GenerallyAvailable] = 0, + [ProductLifecycle.Beta] = 1, + [ProductLifecycle.TechnicalPreview] = 2, + [ProductLifecycle.Planned] = 3, + [ProductLifecycle.Deprecated] = 4, + [ProductLifecycle.Removed] = 5, + [ProductLifecycle.Unavailable] = 6 + }; + + var availableApplicabilities = applicabilityList + .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current) + .ToList(); + + if (availableApplicabilities.Count != 0) + { + return availableApplicabilities + .OrderByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) + .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) + .First(); + } + + var futureApplicabilities = applicabilityList + .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > versioningSystem.Current) + .ToList(); + + if (futureApplicabilities.Count != 0) + { + return futureApplicabilities + .OrderBy(a => a.Version!.CompareTo(versioningSystem.Current)) + .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) + .First(); + } + + return applicabilityList.First(); + } +} diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs index 6fb621a1f..8f3ea65e3 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs @@ -53,7 +53,7 @@ public ApplicabilityRenderData RenderCombinedApplicability( AppliesCollection allApplications) { var applicabilityList = applicabilities.ToList(); - var primaryApplicability = GetPrimaryApplicability(applicabilityList, versioningSystem); + var primaryApplicability = ApplicabilitySelector.GetPrimaryApplicability(applicabilityList, versioningSystem); var primaryRenderData = RenderApplicability(primaryApplicability, applicabilityDefinition, versioningSystem, allApplications); var combinedTooltip = BuildCombinedTooltipText(applicabilityList, applicabilityDefinition, versioningSystem); @@ -61,45 +61,6 @@ public ApplicabilityRenderData RenderCombinedApplicability( return primaryRenderData with { TooltipText = combinedTooltip }; } - private static Applicability GetPrimaryApplicability(List applicabilities, VersioningSystem versioningSystem) - { - var lifecycleOrder = new Dictionary - { - [ProductLifecycle.GenerallyAvailable] = 0, - [ProductLifecycle.Beta] = 1, - [ProductLifecycle.TechnicalPreview] = 2, - [ProductLifecycle.Planned] = 3, - [ProductLifecycle.Deprecated] = 4, - [ProductLifecycle.Removed] = 5, - [ProductLifecycle.Unavailable] = 6 - }; - - var availableApplicabilities = applicabilities - .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current) - .ToList(); - - if (availableApplicabilities.Count != 0) - { - return availableApplicabilities - .OrderByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) - .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) - .First(); - } - - var futureApplicabilities = applicabilities - .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > versioningSystem.Current) - .ToList(); - - if (futureApplicabilities.Count != 0) - { - return futureApplicabilities - .OrderBy(a => a.Version!.CompareTo(versioningSystem.Current)) - .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) - .First(); - } - - return applicabilities.First(); - } private static string BuildCombinedTooltipText( List applicabilities, diff --git a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs index b4faeb0c0..e0a6e95a2 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs @@ -148,7 +148,7 @@ private IEnumerable CombineItemsByKey(List new AppliesCollection(allApplicabilities.ToArray())); // Select the closest version to current as the primary display - var primaryApplicability = GetPrimaryApplicability(allApplicabilities, versioningSystem); + var primaryApplicability = ApplicabilitySelector.GetPrimaryApplicability(allApplicabilities, versioningSystem); return new ApplicabilityItem( Key: firstItem.Key, @@ -159,47 +159,5 @@ private IEnumerable CombineItemsByKey(List }); - /// - /// Selects the most relevant applicability for display: available versions first (highest version), then closest future version - /// - private static Applicability GetPrimaryApplicability(List applicabilities, VersioningSystem versioningSystem) - { - var lifecycleOrder = new Dictionary - { - [ProductLifecycle.GenerallyAvailable] = 0, - [ProductLifecycle.Beta] = 1, - [ProductLifecycle.TechnicalPreview] = 2, - [ProductLifecycle.Planned] = 3, - [ProductLifecycle.Deprecated] = 4, - [ProductLifecycle.Removed] = 5, - [ProductLifecycle.Unavailable] = 6 - }; - - var availableApplicabilities = applicabilities - .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current) - .ToList(); - - if (availableApplicabilities.Count != 0) - { - return availableApplicabilities - .OrderByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) - .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) - .First(); - } - - var futureApplicabilities = applicabilities - .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > versioningSystem.Current) - .ToList(); - - if (futureApplicabilities.Count != 0) - { - return futureApplicabilities - .OrderBy(a => a.Version!.CompareTo(versioningSystem.Current)) - .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) - .First(); - } - - return applicabilities.First(); - } } From 79e954d1576e1c1265c235754967ec29f482c137 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 18 Sep 2025 14:42:20 +0200 Subject: [PATCH 04/11] Fix ApplicabilitySelector location and add missing using statements - Moved ApplicabilitySelector from Elastic.Documentation to Elastic.Markdown.Myst.Components - Added missing using statements for AllVersions and SemVersion - All tests now pass successfully --- .../Myst/Components}/ApplicabilitySelector.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename src/{Elastic.Documentation/AppliesTo => Elastic.Markdown/Myst/Components}/ApplicabilitySelector.cs (95%) diff --git a/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilitySelector.cs similarity index 95% rename from src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs rename to src/Elastic.Markdown/Myst/Components/ApplicabilitySelector.cs index f73543905..a54b7dad0 100644 --- a/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilitySelector.cs @@ -2,9 +2,11 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information +using Elastic.Documentation; +using Elastic.Documentation.AppliesTo; using Elastic.Documentation.Configuration.Versions; -namespace Elastic.Documentation.AppliesTo; +namespace Elastic.Markdown.Myst.Components; /// /// Utility class for selecting the most relevant applicability from a collection of applicabilities. From 02215c3723ad0ffa38c46981db79966ad8516c23 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Thu, 18 Sep 2025 14:45:36 +0200 Subject: [PATCH 05/11] Refactor ApplicabilitySelector to use SemVersion parameter and move to domain layer - Changed parameter from VersioningSystem to SemVersion currentVersion - Moved ApplicabilitySelector back to Elastic.Documentation.AppliesTo namespace - Updated callers to pass versioningSystem.Current - Simplified interface and improved domain separation - All tests pass successfully --- .../AppliesTo}/ApplicabilitySelector.cs | 16 ++++++---------- .../Myst/Components/ApplicabilityRenderer.cs | 2 +- .../Myst/Components/ApplicableToViewModel.cs | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) rename src/{Elastic.Markdown/Myst/Components => Elastic.Documentation/AppliesTo}/ApplicabilitySelector.cs (79%) diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilitySelector.cs b/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs similarity index 79% rename from src/Elastic.Markdown/Myst/Components/ApplicabilitySelector.cs rename to src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs index a54b7dad0..cb881fbf6 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilitySelector.cs +++ b/src/Elastic.Documentation/AppliesTo/ApplicabilitySelector.cs @@ -2,11 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information -using Elastic.Documentation; -using Elastic.Documentation.AppliesTo; -using Elastic.Documentation.Configuration.Versions; - -namespace Elastic.Markdown.Myst.Components; +namespace Elastic.Documentation.AppliesTo; /// /// Utility class for selecting the most relevant applicability from a collection of applicabilities. @@ -17,9 +13,9 @@ public static class ApplicabilitySelector /// Selects the most relevant applicability for display: available versions first (highest version), then closest future version /// /// The collection of applicabilities to select from - /// The versioning system to use for comparison + /// The current version to use for comparison /// The most relevant applicability for display - public static Applicability GetPrimaryApplicability(IEnumerable applicabilities, VersioningSystem versioningSystem) + public static Applicability GetPrimaryApplicability(IEnumerable applicabilities, SemVersion currentVersion) { var applicabilityList = applicabilities.ToList(); var lifecycleOrder = new Dictionary @@ -34,7 +30,7 @@ public static Applicability GetPrimaryApplicability(IEnumerable a }; var availableApplicabilities = applicabilityList - .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current) + .Where(a => a.Version is null || a.Version is AllVersions || a.Version <= currentVersion) .ToList(); if (availableApplicabilities.Count != 0) @@ -46,13 +42,13 @@ public static Applicability GetPrimaryApplicability(IEnumerable a } var futureApplicabilities = applicabilityList - .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > versioningSystem.Current) + .Where(a => a.Version is not null && a.Version is not AllVersions && a.Version > currentVersion) .ToList(); if (futureApplicabilities.Count != 0) { return futureApplicabilities - .OrderBy(a => a.Version!.CompareTo(versioningSystem.Current)) + .OrderBy(a => a.Version!.CompareTo(currentVersion)) .ThenBy(a => lifecycleOrder.GetValueOrDefault(a.Lifecycle, 999)) .First(); } diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs index 8f3ea65e3..aa3fa6d19 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs @@ -53,7 +53,7 @@ public ApplicabilityRenderData RenderCombinedApplicability( AppliesCollection allApplications) { var applicabilityList = applicabilities.ToList(); - var primaryApplicability = ApplicabilitySelector.GetPrimaryApplicability(applicabilityList, versioningSystem); + var primaryApplicability = ApplicabilitySelector.GetPrimaryApplicability(applicabilityList, versioningSystem.Current); var primaryRenderData = RenderApplicability(primaryApplicability, applicabilityDefinition, versioningSystem, allApplications); var combinedTooltip = BuildCombinedTooltipText(applicabilityList, applicabilityDefinition, versioningSystem); diff --git a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs index 0bc273b28..11e50c37a 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicableToViewModel.cs @@ -148,7 +148,7 @@ private IEnumerable CombineItemsByKey(List new AppliesCollection(allApplicabilities.ToArray())); // Select the closest version to current as the primary display - var primaryApplicability = ApplicabilitySelector.GetPrimaryApplicability(allApplicabilities, versioningSystem); + var primaryApplicability = ApplicabilitySelector.GetPrimaryApplicability(allApplicabilities, versioningSystem.Current); return new ApplicabilityItem( Key: firstItem.Key, From cf810dad5c7471d01c8d18784eefdc7abc806b88 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Fri, 19 Sep 2025 14:17:48 +0200 Subject: [PATCH 06/11] Style tooltip Bold heading and separator --- .../Assets/markdown/applies-to.css | 19 ++++++++ .../Assets/markdown/applies-to.ts | 45 ++++++++++++++----- .../Myst/Components/ApplicabilityRenderer.cs | 9 ++-- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css index a021fd476..1542f3c17 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css @@ -46,3 +46,22 @@ } } } + +.tippy-box[data-theme~='applies-to'] { + /*background-color: tomato;*/ + /*color: yellow;*/ + .tippy-content { + white-space: normal; + + strong { + display: block; + margin-bottom: calc(var(--spacing) * 1); + } + } + + .tippy-content > div:not(:last-child) { + border-bottom: 1px dotted var(--color-grey-50); + padding-bottom: calc(var(--spacing) * 3); + margin-bottom: calc(var(--spacing) * 3); + } +} diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts index d222c8448..57fa051cf 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts @@ -1,14 +1,39 @@ import tippy from 'tippy.js' +import { $$ } from 'select-dom' document.addEventListener('htmx:load', function () { - tippy( - [ - '.applies [data-tippy-content]:not([data-tippy-content=""])', - '.applies-inline [data-tippy-content]:not([data-tippy-content=""])', - ].join(', '), - { - delay: [400, 100], - hideOnClick: false, - } - ) + + const selector = [ + '.applies [data-tippy-content]:not([data-tippy-content=""])', + '.applies-inline [data-tippy-content]:not([data-tippy-content=""])', + ].join(', ') + + const appliesToBadgesWithTooltip = $$(selector) + appliesToBadgesWithTooltip.forEach(badge => { + const content = badge.getAttribute('data-tippy-content') + if (!content) + return + tippy( + badge, + { + content, + allowHTML: true, + delay: [400, 100], + hideOnClick: false, + ignoreAttributes: true, + theme: 'applies-to' + } + ) + }) + + // tippy( + // [ + // '.applies [data-tippy-content]:not([data-tippy-content=""])', + // '.applies-inline [data-tippy-content]:not([data-tippy-content=""])', + // ].join(', '), + // { + // delay: [400, 100], + // hideOnClick: false, + // } + // ) }) diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs index aa3fa6d19..5bc7d42f0 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs @@ -73,7 +73,8 @@ private static string BuildCombinedTooltipText( var orderedApplicabilities = applicabilities .OrderByDescending(a => a.Version is null || a.Version is AllVersions || a.Version <= versioningSystem.Current ? 1 : 0) .ThenByDescending(a => a.Version ?? new SemVersion(0, 0, 0)) - .ThenBy(a => a.Version ?? new SemVersion(0, 0, 0)); + .ThenBy(a => a.Version ?? new SemVersion(0, 0, 0)) + .ToList(); foreach (var applicability in orderedApplicabilities) { @@ -81,7 +82,8 @@ private static string BuildCombinedTooltipText( var lifecycleFull = GetLifecycleFullText(applicability.Lifecycle); var heading = CreateApplicabilityHeading(applicability, applicabilityDefinition, realVersion); var tooltipText = BuildTooltipText(applicability, applicabilityDefinition, versioningSystem, realVersion, lifecycleFull); - tooltipParts.Add($"{heading}\n{tooltipText}"); + // language=html + tooltipParts.Add($"
{heading}{tooltipText}
"); } return string.Join("\n\n", tooltipParts); @@ -91,7 +93,8 @@ private static string CreateApplicabilityHeading(Applicability applicability, Ap { var lifecycleName = applicability.GetLifeCycleName(); var versionText = realVersion is not null ? $" {realVersion}" : ""; - return $"{applicabilityDefinition.DisplayName} {lifecycleName}{versionText}:"; + // language=html + return $"""{applicabilityDefinition.DisplayName} {lifecycleName}{versionText}:"""; } private static string GetLifecycleFullText(ProductLifecycle lifecycle) => lifecycle switch From dee924fcb7a613116ca6bbd61a5bad1dd64f0cd6 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Mon, 22 Sep 2025 11:54:24 +0200 Subject: [PATCH 07/11] Add ellipsis if an applies_to key has multiple lifecycles --- .../Assets/markdown/applies-to.css | 12 +++++++++ .../Myst/Components/ApplicabilityRenderer.cs | 27 ++++++++++++++----- .../Components/ApplicableToComponent.cshtml | 8 ++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css index 1542f3c17..b59f13518 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css @@ -11,6 +11,10 @@ .applicable-info { @apply border-grey-20 inline-grid cursor-default grid-cols-[auto_1fr_auto] rounded-full border-[1px] bg-white pt-1.5 pr-3 pb-1.5 pl-3; } + + .applicable-meta { + @apply inline-flex gap-1.5; + } .applicable-name, .applicable-meta { @@ -45,6 +49,14 @@ font-size: 0.65em; } } + + .applicable-ellipsis { + @apply inline-flex gap-0.5 items-center rounded-md bg-grey-20 py-1 px-0.5 h-full; + } + + .applicable-ellipsis__dot { + @apply size-1 rounded-full bg-grey-50; + } } .tippy-box[data-theme~='applies-to'] { diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs index 5bc7d42f0..bcf87c9af 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs @@ -17,7 +17,8 @@ public record ApplicabilityRenderData( string TooltipText, string LifecycleClass, bool ShowLifecycleName, - bool ShowVersion + bool ShowVersion, + bool HasMultipleLifecycles = false ); public ApplicabilityRenderData RenderApplicability( @@ -58,7 +59,14 @@ public ApplicabilityRenderData RenderCombinedApplicability( var primaryRenderData = RenderApplicability(primaryApplicability, applicabilityDefinition, versioningSystem, allApplications); var combinedTooltip = BuildCombinedTooltipText(applicabilityList, applicabilityDefinition, versioningSystem); - return primaryRenderData with { TooltipText = combinedTooltip }; + // Check if there are multiple different lifecycles + var hasMultipleLifecycles = applicabilityList.Select(a => a.Lifecycle).Distinct().Count() > 1; + + return primaryRenderData with + { + TooltipText = combinedTooltip, + HasMultipleLifecycles = hasMultipleLifecycles + }; } @@ -89,7 +97,8 @@ private static string BuildCombinedTooltipText( return string.Join("\n\n", tooltipParts); } - private static string CreateApplicabilityHeading(Applicability applicability, ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition, SemVersion? realVersion) + private static string CreateApplicabilityHeading(Applicability applicability, ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition, + SemVersion? realVersion) { var lifecycleName = applicability.GetLifeCycleName(); var versionText = realVersion is not null ? $" {realVersion}" : ""; @@ -127,8 +136,10 @@ or ProductLifecycle.Beta or ProductLifecycle.TechnicalPreview or ProductLifecycle.Planned => $"We plan to add this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.", - ProductLifecycle.Deprecated => $"We plan to deprecate this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.", - ProductLifecycle.Removed => $"We plan to remove this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.", + ProductLifecycle.Deprecated => + $"We plan to deprecate this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.", + ProductLifecycle.Removed => + $"We plan to remove this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.", _ => tooltipText } : $"{lifecycleFull} on {applicabilityDefinition.DisplayName} unless otherwise specified."; @@ -142,8 +153,10 @@ or ProductLifecycle.TechnicalPreview private static string? GetDisclaimer(ProductLifecycle lifecycle, VersioningSystemId versioningSystemId) => lifecycle switch { - ProductLifecycle.Beta => "Beta features are subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features.", - ProductLifecycle.TechnicalPreview => "This functionality may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.", + ProductLifecycle.Beta => + "Beta features are subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features.", + ProductLifecycle.TechnicalPreview => + "This functionality may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.", ProductLifecycle.GenerallyAvailable => versioningSystemId is VersioningSystemId.Stack ? "If this functionality is unavailable or behaves differently when deployed on ECH, ECE, ECK, or a self-managed installation, it will be indicated on the page." : null, diff --git a/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml b/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml index 7f0d004f4..a4f7aa3d6 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml +++ b/src/Elastic.Markdown/Myst/Components/ApplicableToComponent.cshtml @@ -24,6 +24,14 @@ { @item.RenderData.BadgeLifecycleText } + @if (item.RenderData.HasMultipleLifecycles) + { + + + + + + } } From dc03b1184200c635006bacdefd9ad2ec3230ffb3 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Mon, 22 Sep 2025 12:15:04 +0200 Subject: [PATCH 08/11] Show GA lifecycle multi lifecycle state --- .../Myst/Components/ApplicabilityRenderer.cs | 3 +- .../Applicability/ApplicableToComponent.fs | 51 ++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs index bcf87c9af..8ffe34306 100644 --- a/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs +++ b/src/Elastic.Markdown/Myst/Components/ApplicabilityRenderer.cs @@ -65,7 +65,8 @@ public ApplicabilityRenderData RenderCombinedApplicability( return primaryRenderData with { TooltipText = combinedTooltip, - HasMultipleLifecycles = hasMultipleLifecycles + HasMultipleLifecycles = hasMultipleLifecycles, + ShowLifecycleName = primaryRenderData.ShowLifecycleName || (string.IsNullOrEmpty(primaryRenderData.BadgeLifecycleText) && hasMultipleLifecycles) }; } diff --git a/tests/authoring/Applicability/ApplicableToComponent.fs b/tests/authoring/Applicability/ApplicableToComponent.fs index 12f30772d..515e632d2 100644 --- a/tests/authoring/Applicability/ApplicableToComponent.fs +++ b/tests/authoring/Applicability/ApplicableToComponent.fs @@ -404,19 +404,22 @@ stack: ga 8.8.0, preview 8.1.0 let ``renders GA planned when preview exists alongside GA`` () = markdown |> convertsToHtml """

- +This functionality may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features."> Stack GA planned + + + + +

@@ -796,3 +799,39 @@ If this functionality is unavailable or behaves differently when deployed on ECH

""" + +// Test multiple lifecycles for same applicability key +type ``multiple lifecycles same key`` () = + static let markdown = Setup.Markdown """ +```{applies_to} +stack: ga 8.0.0, beta 8.1.0 +``` +""" + + [] + let ``renders multiple lifecycles with ellipsis and shows GA lifecycle`` () = + markdown |> convertsToHtml """ +

+ + Stack + + + GA + + 8.0.0 + + + + + + + + +

+""" From 4c6091e64c87e90c125ca4a92a5ab2bc81750f52 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Mon, 22 Sep 2025 12:36:18 +0200 Subject: [PATCH 09/11] Update src/Elastic.Documentation.Site/Assets/markdown/applies-to.css Co-authored-by: Martijn Laarman --- src/Elastic.Documentation.Site/Assets/markdown/applies-to.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css index b59f13518..5b5bdb988 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css @@ -60,8 +60,6 @@ } .tippy-box[data-theme~='applies-to'] { - /*background-color: tomato;*/ - /*color: yellow;*/ .tippy-content { white-space: normal; From 4b20c135ecb9dd16bb63a3ad9a6ebf88ddee632d Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Mon, 22 Sep 2025 12:36:28 +0200 Subject: [PATCH 10/11] Update src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts Co-authored-by: Martijn Laarman --- .../Assets/markdown/applies-to.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts index 57fa051cf..dd68ed51e 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts @@ -26,14 +26,4 @@ document.addEventListener('htmx:load', function () { ) }) - // tippy( - // [ - // '.applies [data-tippy-content]:not([data-tippy-content=""])', - // '.applies-inline [data-tippy-content]:not([data-tippy-content=""])', - // ].join(', '), - // { - // delay: [400, 100], - // hideOnClick: false, - // } - // ) }) From 6ee6ad0443ba470c76688fcf05d473a941b0ebd6 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Mon, 22 Sep 2025 12:37:01 +0200 Subject: [PATCH 11/11] Run prettier --- .../Assets/markdown/applies-to.css | 14 ++++----- .../Assets/markdown/applies-to.ts | 30 ++++++++----------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css index 5b5bdb988..312e4da4d 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.css @@ -11,7 +11,7 @@ .applicable-info { @apply border-grey-20 inline-grid cursor-default grid-cols-[auto_1fr_auto] rounded-full border-[1px] bg-white pt-1.5 pr-3 pb-1.5 pl-3; } - + .applicable-meta { @apply inline-flex gap-1.5; } @@ -49,26 +49,26 @@ font-size: 0.65em; } } - + .applicable-ellipsis { - @apply inline-flex gap-0.5 items-center rounded-md bg-grey-20 py-1 px-0.5 h-full; + @apply bg-grey-20 inline-flex h-full items-center gap-0.5 rounded-md px-0.5 py-1; } - + .applicable-ellipsis__dot { - @apply size-1 rounded-full bg-grey-50; + @apply bg-grey-50 size-1 rounded-full; } } .tippy-box[data-theme~='applies-to'] { .tippy-content { white-space: normal; - + strong { display: block; margin-bottom: calc(var(--spacing) * 1); } } - + .tippy-content > div:not(:last-child) { border-bottom: 1px dotted var(--color-grey-50); padding-bottom: calc(var(--spacing) * 3); diff --git a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts index dd68ed51e..df5ad9d66 100644 --- a/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts +++ b/src/Elastic.Documentation.Site/Assets/markdown/applies-to.ts @@ -1,29 +1,23 @@ -import tippy from 'tippy.js' import { $$ } from 'select-dom' +import tippy from 'tippy.js' document.addEventListener('htmx:load', function () { - const selector = [ '.applies [data-tippy-content]:not([data-tippy-content=""])', '.applies-inline [data-tippy-content]:not([data-tippy-content=""])', ].join(', ') - + const appliesToBadgesWithTooltip = $$(selector) - appliesToBadgesWithTooltip.forEach(badge => { + appliesToBadgesWithTooltip.forEach((badge) => { const content = badge.getAttribute('data-tippy-content') - if (!content) - return - tippy( - badge, - { - content, - allowHTML: true, - delay: [400, 100], - hideOnClick: false, - ignoreAttributes: true, - theme: 'applies-to' - } - ) + if (!content) return + tippy(badge, { + content, + allowHTML: true, + delay: [400, 100], + hideOnClick: false, + ignoreAttributes: true, + theme: 'applies-to', + }) }) - })