diff --git a/src/Aspire.Dashboard/Components/Pages/Resources.razor b/src/Aspire.Dashboard/Components/Pages/Resources.razor
index d89e90e7c55..381f42cd069 100644
--- a/src/Aspire.Dashboard/Components/Pages/Resources.razor
+++ b/src/Aspire.Dashboard/Components/Pages/Resources.razor
@@ -115,9 +115,14 @@
Label="@ControlsStringsLoc[nameof(ControlsStrings.ChartContainerGraphTab)]"
Icon="@(new Icons.Regular.Size24.ShareAndroid())">
+
+
}
-
+
GetFilteredResources()
private ValueTask> GetData(GridItemsProviderRequest request)
{
// Get filtered and ordered resources.
- var filteredResources = GetFilteredResources()
+ var filteredResourcesList = GetFilteredResources().ToList();
+
+ // Group parameters under a synthetic "Parameters" parent resource
+ var resourcesWithParametersGrouped = GroupParametersUnderParent(filteredResourcesList);
+
+ var filteredResources = resourcesWithParametersGrouped
.Select(r => new ResourceGridViewModel { Resource = r })
.AsQueryable();
filteredResources = request.ApplySorting(filteredResources);
@@ -460,6 +484,92 @@ private ValueTask> GetData(GridIt
return ValueTask.FromResult(GridItemsProviderResult.From(query, orderedResources.Count));
}
+ private const string ParametersGroupName = "Parameters";
+
+ private List GroupParametersUnderParent(List resources)
+ {
+ var parameters = resources.Where(r => StringComparers.ResourceType.Equals(r.ResourceType, KnownResourceTypes.Parameter)).ToList();
+
+ if (parameters.Count == 0)
+ {
+ return resources;
+ }
+
+ // Create synthetic "Parameters" parent resource
+ var parametersParent = new ResourceViewModel
+ {
+ Name = ParametersGroupName,
+ ResourceType = "ParameterGroup",
+ DisplayName = ParametersGroupName,
+ Uid = ParametersGroupName,
+ State = null,
+ StateStyle = null,
+ CreationTimeStamp = null,
+ StartTimeStamp = null,
+ StopTimeStamp = null,
+ Environment = ImmutableArray.Empty,
+ Urls = ImmutableArray.Empty,
+ Volumes = ImmutableArray.Empty,
+ Relationships = ImmutableArray.Empty,
+ Properties = System.Collections.Immutable.ImmutableDictionary.Empty,
+ Commands = ImmutableArray.Empty,
+ HealthReports = ImmutableArray.Empty
+ };
+
+ // Set synthetic parent to be collapsed by default
+ if (!_collapsedResourceNames.Contains(ParametersGroupName))
+ {
+ _collapsedResourceNames.Add(ParametersGroupName);
+ }
+
+ // Create new list with parameters having the parent set
+ var result = new List { parametersParent };
+
+ foreach (var resource in resources)
+ {
+ if (StringComparers.ResourceType.Equals(resource.ResourceType, KnownResourceTypes.Parameter))
+ {
+ // Update parameter to have Parameters as parent
+ var parentProperty = new ResourcePropertyViewModel(
+ KnownProperties.Resource.ParentName,
+ Google.Protobuf.WellKnownTypes.Value.ForString(ParametersGroupName),
+ isValueSensitive: false,
+ knownProperty: null,
+ priority: 0);
+
+ var updatedProperties = resource.Properties.SetItem(KnownProperties.Resource.ParentName, parentProperty);
+
+ var updatedParameter = new ResourceViewModel
+ {
+ Name = resource.Name,
+ ResourceType = resource.ResourceType,
+ DisplayName = resource.DisplayName,
+ Uid = resource.Uid,
+ State = resource.State,
+ StateStyle = resource.StateStyle,
+ CreationTimeStamp = resource.CreationTimeStamp,
+ StartTimeStamp = resource.StartTimeStamp,
+ StopTimeStamp = resource.StopTimeStamp,
+ Environment = resource.Environment,
+ Urls = resource.Urls,
+ Volumes = resource.Volumes,
+ Relationships = resource.Relationships,
+ Properties = updatedProperties,
+ Commands = resource.Commands,
+ HealthReports = resource.HealthReports
+ };
+
+ result.Add(updatedParameter);
+ }
+ else
+ {
+ result.Add(resource);
+ }
+ }
+
+ return result;
+ }
+
private void UpdateMenuButtons()
{
_resourcesMenuItems.Clear();
@@ -876,7 +986,8 @@ public class ResourcesPageState
public enum ResourceViewKind
{
Table,
- Graph
+ Graph,
+ Parameters
}
public Task UpdateViewModelFromQueryAsync(ResourcesViewModel viewModel)
diff --git a/src/Aspire.Dashboard/Resources/Resources.Designer.cs b/src/Aspire.Dashboard/Resources/Resources.Designer.cs
index a47d582246d..96f2dce3ab1 100644
--- a/src/Aspire.Dashboard/Resources/Resources.Designer.cs
+++ b/src/Aspire.Dashboard/Resources/Resources.Designer.cs
@@ -599,5 +599,32 @@ public static string WaitingHealthDataStatusMessage {
return ResourceManager.GetString("WaitingHealthDataStatusMessage", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Parameters.
+ ///
+ public static string ParametersHeader {
+ get {
+ return ResourceManager.GetString("ParametersHeader", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to {0} parameters.
+ ///
+ public static string ParametersPageTitle {
+ get {
+ return ResourceManager.GetString("ParametersPageTitle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Parameters.
+ ///
+ public static string ResourcesParametersTab {
+ get {
+ return ResourceManager.GetString("ResourcesParametersTab", resourceCulture);
+ }
+ }
}
}
diff --git a/src/Aspire.Dashboard/Resources/Resources.resx b/src/Aspire.Dashboard/Resources/Resources.resx
index 68ec2c9a96f..cc7be07f646 100644
--- a/src/Aspire.Dashboard/Resources/Resources.resx
+++ b/src/Aspire.Dashboard/Resources/Resources.resx
@@ -309,4 +309,14 @@
URLs
+
+ {0} parameters
+ {0} is an application name
+
+
+ Parameters
+
+
+ Parameters
+
\ No newline at end of file
diff --git a/src/Aspire.Dashboard/Resources/xlf/Resources.cs.xlf b/src/Aspire.Dashboard/Resources/xlf/Resources.cs.xlf
index 2eb19aa23e2..ae4ca9f854b 100644
--- a/src/Aspire.Dashboard/Resources/xlf/Resources.cs.xlf
+++ b/src/Aspire.Dashboard/Resources/xlf/Resources.cs.xlf
@@ -17,6 +17,16 @@
{0} (naposledy spuštěno v {1})
{0} is the health status like "Unhealthy", {1} is the local time when the health check ran
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Příkazy
@@ -227,6 +237,11 @@
Žádné filtry
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Befehle
@@ -227,6 +237,11 @@
Keine Filter
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Comandos
@@ -227,6 +237,11 @@
No hay ningún filtro
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Commandes
@@ -227,6 +237,11 @@
Aucun filtre
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Comandi
@@ -227,6 +237,11 @@
Nessun filtro
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
コマンド
@@ -227,6 +237,11 @@
フィルターなし
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
명령
@@ -227,6 +237,11 @@
필터 없음
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Polecenia
@@ -227,6 +237,11 @@
Brak filtrów
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Comandos
@@ -227,6 +237,11 @@
Sem filtros
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Команды
@@ -227,6 +237,11 @@
Нет фильтров
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
Komutlar
@@ -227,6 +237,11 @@
Filtre mevcut değil
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
命令
@@ -227,6 +237,11 @@
无筛选器
+
+ Parameters
+ Parameters
+
+
+
+
+ {0} parameters
+ {0} parameters
+ {0} is an application name
+
Commands
命令
@@ -227,6 +237,11 @@
沒有篩選
+
+ Parameters
+ Parameters
+
+