Skip to content
Closed
122 changes: 110 additions & 12 deletions Dashboard/Controls/FinOpsContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -783,54 +783,152 @@
SelectionMode="Extended"
RowStyle="{StaticResource DefaultRowStyle}">
<DataGrid.Columns>
<DataGridTextColumn Header="Database" Binding="{Binding DatabaseName}" Width="160"/>
<DataGridTextColumn Header="File Type" Binding="{Binding FileTypeDesc}" Width="80"/>
<DataGridTextColumn Header="File Name" Binding="{Binding FileName}" Width="160"/>
<DataGridTextColumn Header="Total Size MB" Binding="{Binding TotalSizeMb, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn Binding="{Binding DatabaseName}" Width="160">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="DatabaseName" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Database" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding FileTypeDesc}" Width="80">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="FileTypeDesc" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="File Type" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding FileName}" Width="160">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="FileName" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="File Name" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding TotalSizeMb, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="TotalSizeMb" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Total Size MB" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Used Size MB" Binding="{Binding UsedSizeMb, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn Binding="{Binding UsedSizeMb, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="UsedSizeMb" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Used Size MB" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Free Space MB" Binding="{Binding FreeSpaceMb, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn Binding="{Binding FreeSpaceMb, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="FreeSpaceMb" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Free Space MB" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Used %" Binding="{Binding UsedPct, StringFormat='{}{0:N1}'}" Width="70">
<DataGridTextColumn Binding="{Binding UsedPct, StringFormat='{}{0:N1}'}" Width="70">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="UsedPct" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Used %" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Volume" Binding="{Binding VolumeMountPoint}" Width="80"/>
<DataGridTextColumn Header="Volume Total MB" Binding="{Binding VolumeTotalMb, StringFormat='{}{0:N0}'}" Width="120">
<DataGridTextColumn Binding="{Binding VolumeMountPoint}" Width="80">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="VolumeMountPoint" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Volume" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding VolumeTotalMb, StringFormat='{}{0:N0}'}" Width="120">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="VolumeTotalMb" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Volume Total MB" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Volume Free MB" Binding="{Binding VolumeFreeMb, StringFormat='{}{0:N0}'}" Width="120">
<DataGridTextColumn Binding="{Binding VolumeFreeMb, StringFormat='{}{0:N0}'}" Width="120">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="VolumeFreeMb" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Volume Free MB" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Recovery Model" Binding="{Binding RecoveryModelDesc}" Width="120"/>
<DataGridTextColumn Header="Monthly Cost ($)" Binding="{Binding MonthlyCostShare, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn Binding="{Binding RecoveryModelDesc}" Width="120">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="RecoveryModelDesc" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Recovery Model" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding GrowthDisplay}" Width="110" SortMemberPath="AutoGrowthSort">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="GrowthDisplay" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Auto Growth" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding VlfCountDisplay}" Width="80" SortMemberPath="VlfCountSort">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="VlfCountDisplay" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="VLF Count" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding MonthlyCostShare, StringFormat='{}{0:N2}'}" Width="110">
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<Button Style="{DynamicResource ColumnFilterButtonStyle}" Tag="MonthlyCostShare" Click="DatabaseSizesFilter_Click" Margin="0,0,4,0"/>
<TextBlock Text="Monthly Cost ($)" FontWeight="Bold" VerticalAlignment="Center"/>
</StackPanel>
</DataGridTextColumn.Header>
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Right"/>
Expand Down
59 changes: 56 additions & 3 deletions Dashboard/Controls/FinOpsContent.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using Microsoft.Win32;
Expand All @@ -32,6 +33,10 @@ public partial class FinOpsContent : UserControl
private DateTime _serverInventoryCacheTime;
private decimal _currentServerMonthlyCost;

private DataGridFilterManager<FinOpsDatabaseSizeStats>? _dbSizesFilterMgr;
private Popup? _dbSizeFilterPopup;
private ColumnFilterPopup? _dbSizeFilterPopupContent;

public FinOpsContent()
{
InitializeComponent();
Expand Down Expand Up @@ -69,6 +74,8 @@ private void OnLoaded(object sender, RoutedEventArgs e)
TabHelpers.FreezeColumns(ExpensiveQueriesDataGrid, 1);
TabHelpers.FreezeColumns(IndexAnalysisDetailGrid, 1);
TabHelpers.FreezeColumns(HighImpactDataGrid, 1);

_dbSizesFilterMgr = new DataGridFilterManager<FinOpsDatabaseSizeStats>(DatabaseSizesDataGrid);
}

/// <summary>
Expand Down Expand Up @@ -623,16 +630,62 @@ private async Task LoadDatabaseSizesAsync()
}
}

DatabaseSizesDataGrid.ItemsSource = data;
DatabaseSizesNoDataMessage.Visibility = data.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
DbSizeCountIndicator.Text = data.Count > 0 ? $"{data.Count} file(s)" : "";
_dbSizesFilterMgr!.UpdateData(data);
UpdateDbSizeCountUI();
}
catch (Exception ex)
{
Logger.Error($"Error loading database sizes: {ex.Message}", ex);
}
}

private void UpdateDbSizeCountUI()
{
var list = DatabaseSizesDataGrid.ItemsSource as System.Collections.IList;
int count = list?.Count ?? 0;
DatabaseSizesNoDataMessage.Visibility = count == 0 ? Visibility.Visible : Visibility.Collapsed;
DbSizeCountIndicator.Text = count > 0 ? $"{count} file(s)" : "";
}

private void DatabaseSizesFilter_Click(object sender, RoutedEventArgs e)
{
if (sender is not Button button || button.Tag is not string columnName) return;

if (_dbSizeFilterPopup == null)
{
_dbSizeFilterPopupContent = new ColumnFilterPopup();
_dbSizeFilterPopupContent.FilterApplied += FilterPopup_DbSizeFilterApplied;
_dbSizeFilterPopupContent.FilterCleared += FilterPopup_DbSizeFilterCleared;
_dbSizeFilterPopup = new Popup
{
Child = _dbSizeFilterPopupContent,
StaysOpen = false,
Placement = PlacementMode.Bottom,
AllowsTransparency = true
};
}

_dbSizesFilterMgr!.Filters.TryGetValue(columnName, out var existingFilter);
_dbSizeFilterPopupContent!.Initialize(columnName, existingFilter);
_dbSizeFilterPopup.PlacementTarget = button;
_dbSizeFilterPopup.IsOpen = true;
}

private void FilterPopup_DbSizeFilterApplied(object? sender, FilterAppliedEventArgs e)
{
if (_dbSizeFilterPopup != null)
_dbSizeFilterPopup.IsOpen = false;

_dbSizesFilterMgr!.SetFilter(e.FilterState);
UpdateDbSizeCountUI();
}

private void FilterPopup_DbSizeFilterCleared(object? sender, EventArgs e)
{
if (_dbSizeFilterPopup != null)
_dbSizeFilterPopup.IsOpen = false;
}

// ============================================
// Application Connections Tab
// ============================================
Expand Down
Loading