Introduce SpreadsheetDialogBase and localize remaining hardcoded strings

Every spreadsheet dialog re-injected DialogService and Localizer,
re-defined the L(key) helper, and re-implemented OnCancel. Extract
SpreadsheetDialogBase covering this boilerplate.

EditChartDialog and CustomSortDialog had hardcoded English chart-type
names, legend positions, series-name format, and column-name format
while the rest of the same files used L(...). Localize via new
RadzenStrings entries (Spreadsheet_ChartType_*, Spreadsheet_LegendPosition_*,
Spreadsheet_SeriesFormat) and reuse the existing Spreadsheet_ColumnFormat.

EditChartDialog's static readonly chart-type/legend-position lists
become instance fields built in OnInitialized since they now call L(...).
This commit is contained in:
Atanas Korchev
2026-05-27 15:13:24 +03:00
committed by Vladimir Enchev
parent 5ce7e12e6b
commit b6dcb2f34c
13 changed files with 141 additions and 108 deletions

View File

@@ -223,6 +223,21 @@ namespace Radzen.Blazor {
public static string Spreadsheet_ValueRange { get { return ResourceManager.GetString("Spreadsheet_ValueRange", resourceCulture); } }
public static string Spreadsheet_SeriesTitle { get { return ResourceManager.GetString("Spreadsheet_SeriesTitle", resourceCulture); } }
public static string Spreadsheet_AddSeries { get { return ResourceManager.GetString("Spreadsheet_AddSeries", resourceCulture); } }
public static string Spreadsheet_SeriesFormat { get { return ResourceManager.GetString("Spreadsheet_SeriesFormat", resourceCulture); } }
public static string Spreadsheet_ChartType_Column { get { return ResourceManager.GetString("Spreadsheet_ChartType_Column", resourceCulture); } }
public static string Spreadsheet_ChartType_Bar { get { return ResourceManager.GetString("Spreadsheet_ChartType_Bar", resourceCulture); } }
public static string Spreadsheet_ChartType_StackedColumn { get { return ResourceManager.GetString("Spreadsheet_ChartType_StackedColumn", resourceCulture); } }
public static string Spreadsheet_ChartType_StackedBar { get { return ResourceManager.GetString("Spreadsheet_ChartType_StackedBar", resourceCulture); } }
public static string Spreadsheet_ChartType_Line { get { return ResourceManager.GetString("Spreadsheet_ChartType_Line", resourceCulture); } }
public static string Spreadsheet_ChartType_Area { get { return ResourceManager.GetString("Spreadsheet_ChartType_Area", resourceCulture); } }
public static string Spreadsheet_ChartType_StackedArea { get { return ResourceManager.GetString("Spreadsheet_ChartType_StackedArea", resourceCulture); } }
public static string Spreadsheet_ChartType_Pie { get { return ResourceManager.GetString("Spreadsheet_ChartType_Pie", resourceCulture); } }
public static string Spreadsheet_ChartType_Donut { get { return ResourceManager.GetString("Spreadsheet_ChartType_Donut", resourceCulture); } }
public static string Spreadsheet_ChartType_Scatter { get { return ResourceManager.GetString("Spreadsheet_ChartType_Scatter", resourceCulture); } }
public static string Spreadsheet_LegendPosition_Right { get { return ResourceManager.GetString("Spreadsheet_LegendPosition_Right", resourceCulture); } }
public static string Spreadsheet_LegendPosition_Left { get { return ResourceManager.GetString("Spreadsheet_LegendPosition_Left", resourceCulture); } }
public static string Spreadsheet_LegendPosition_Top { get { return ResourceManager.GetString("Spreadsheet_LegendPosition_Top", resourceCulture); } }
public static string Spreadsheet_LegendPosition_Bottom { get { return ResourceManager.GetString("Spreadsheet_LegendPosition_Bottom", resourceCulture); } }
public static string Spreadsheet_InsertHyperlink { get { return ResourceManager.GetString("Spreadsheet_InsertHyperlink", resourceCulture); } }
public static string Spreadsheet_InsertImage { get { return ResourceManager.GetString("Spreadsheet_InsertImage", resourceCulture); } }
public static string Spreadsheet_InsertChart { get { return ResourceManager.GetString("Spreadsheet_InsertChart", resourceCulture); } }

View File

@@ -559,6 +559,51 @@
<data name="Spreadsheet_AddSeries" xml:space="preserve">
<value>Add Series</value>
</data>
<data name="Spreadsheet_SeriesFormat" xml:space="preserve">
<value>Series {0}</value>
</data>
<data name="Spreadsheet_ChartType_Column" xml:space="preserve">
<value>Column</value>
</data>
<data name="Spreadsheet_ChartType_Bar" xml:space="preserve">
<value>Bar</value>
</data>
<data name="Spreadsheet_ChartType_StackedColumn" xml:space="preserve">
<value>Stacked Column</value>
</data>
<data name="Spreadsheet_ChartType_StackedBar" xml:space="preserve">
<value>Stacked Bar</value>
</data>
<data name="Spreadsheet_ChartType_Line" xml:space="preserve">
<value>Line</value>
</data>
<data name="Spreadsheet_ChartType_Area" xml:space="preserve">
<value>Area</value>
</data>
<data name="Spreadsheet_ChartType_StackedArea" xml:space="preserve">
<value>Stacked Area</value>
</data>
<data name="Spreadsheet_ChartType_Pie" xml:space="preserve">
<value>Pie</value>
</data>
<data name="Spreadsheet_ChartType_Donut" xml:space="preserve">
<value>Donut</value>
</data>
<data name="Spreadsheet_ChartType_Scatter" xml:space="preserve">
<value>Scatter</value>
</data>
<data name="Spreadsheet_LegendPosition_Right" xml:space="preserve">
<value>Right</value>
</data>
<data name="Spreadsheet_LegendPosition_Left" xml:space="preserve">
<value>Left</value>
</data>
<data name="Spreadsheet_LegendPosition_Top" xml:space="preserve">
<value>Top</value>
</data>
<data name="Spreadsheet_LegendPosition_Bottom" xml:space="preserve">
<value>Bottom</value>
</data>
<!-- Spreadsheet: Insert tab tooltips -->
<data name="Spreadsheet_InsertHyperlink" xml:space="preserve">
<value>Insert Hyperlink</value>

View File

@@ -2,8 +2,7 @@
@using System.Linq
@using Radzen.Blazor
@using Radzen.Documents.Spreadsheet
@inject DialogService DialogService
@inject Localizer Localizer
@inherits SpreadsheetDialogBase
<RadzenStack Gap="1rem" Style="min-width:560px">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem">
@@ -100,8 +99,6 @@
/// <summary>The result returned via DialogService when the user clicks OK.</summary>
public sealed record Result(SortKey[] Keys, bool HasHeaders);
private string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
private sealed class Level
{
public int ColumnIndex { get; set; }
@@ -132,15 +129,18 @@
new(L(nameof(RadzenStrings.Spreadsheet_SortOrderDescending)), SortOrder.Descending),
];
private string FormatColumnName(int number) =>
string.Format(System.Globalization.CultureInfo.CurrentCulture, L(nameof(RadzenStrings.Spreadsheet_ColumnFormat)), number);
protected override void OnInitialized()
{
columnOptions = ColumnNames
.Select((n, i) => new ColumnOption(string.IsNullOrEmpty(n) ? $"Column {i + 1}" : n, i))
.Select((n, i) => new ColumnOption(string.IsNullOrEmpty(n) ? FormatColumnName(i + 1) : n, i))
.ToList();
if (columnOptions.Count == 0)
{
for (var i = 0; i < Math.Max(1, Range.Columns); i++)
columnOptions.Add(new ColumnOption($"Column {i + 1}", i));
columnOptions.Add(new ColumnOption(FormatColumnName(i + 1), i));
}
levels.Add(new Level { ColumnIndex = 0 });
}
@@ -174,6 +174,4 @@
DialogService.Close(new Result(keys, hasHeaders));
}
private void OnCancel() => DialogService.Close(null);
}

View File

@@ -1,6 +1,7 @@
@using Radzen.Blazor
@using Radzen.Blazor.Spreadsheet
@using Radzen.Documents.Spreadsheet
@inherits SpreadsheetDialogBase
<RadzenStack Gap="0" Style="max-height: 70vh; display: flex; flex-direction: column">
<RadzenStack Gap="1rem" Style="padding: 1rem; overflow-y: auto; flex: 1">
@@ -28,7 +29,7 @@
var index = entry.Index;
var categoryFieldId = CategoryFieldId(index);
var valueFieldId = ValueFieldId(index);
<RadzenFieldset Text=@(entry.Name ?? $"Series {index + 1}")>
<RadzenFieldset Text=@(entry.Name ?? FormatSeriesName(index + 1))>
<RadzenStack Gap="0.5rem">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem">
<RadzenFormField Text=@L(nameof(RadzenStrings.Spreadsheet_SeriesTitle)) Style="flex: 1">
@@ -66,14 +67,6 @@
[Parameter] public EditChartDraft Draft { get; set; } = default!;
[Parameter] public string? FocusFieldId { get; set; }
[Inject]
DialogService DialogService { get; set; } = default!;
[Inject]
Localizer Localizer { get; set; } = default!;
string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
internal static string CategoryFieldId(int seriesIndex) => $"category_{seriesIndex}";
internal static string ValueFieldId(int seriesIndex) => $"value_{seriesIndex}";
@@ -82,34 +75,43 @@
DialogService.Close(new RangePickRequest(fieldId, value));
}
private static readonly List<object> chartTypes =
[
new { Text = "Column", Value = SpreadsheetChartType.Column },
new { Text = "Bar", Value = SpreadsheetChartType.Bar },
new { Text = "Stacked Column", Value = SpreadsheetChartType.StackedColumn },
new { Text = "Stacked Bar", Value = SpreadsheetChartType.StackedBar },
new { Text = "Line", Value = SpreadsheetChartType.Line },
new { Text = "Area", Value = SpreadsheetChartType.Area },
new { Text = "Stacked Area", Value = SpreadsheetChartType.StackedArea },
new { Text = "Pie", Value = SpreadsheetChartType.Pie },
new { Text = "Donut", Value = SpreadsheetChartType.Donut },
new { Text = "Scatter", Value = SpreadsheetChartType.Scatter },
];
private List<object> chartTypes = [];
private List<object> legendPositions = [];
private static readonly List<object> legendPositions =
[
new { Text = "Right", Value = ChartLegendPosition.Right },
new { Text = "Left", Value = ChartLegendPosition.Left },
new { Text = "Top", Value = ChartLegendPosition.Top },
new { Text = "Bottom", Value = ChartLegendPosition.Bottom },
];
private string FormatSeriesName(int number) =>
string.Format(System.Globalization.CultureInfo.CurrentCulture, L(nameof(RadzenStrings.Spreadsheet_SeriesFormat)), number);
protected override void OnInitialized()
{
chartTypes =
[
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Column)), Value = SpreadsheetChartType.Column },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Bar)), Value = SpreadsheetChartType.Bar },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_StackedColumn)), Value = SpreadsheetChartType.StackedColumn },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_StackedBar)), Value = SpreadsheetChartType.StackedBar },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Line)), Value = SpreadsheetChartType.Line },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Area)), Value = SpreadsheetChartType.Area },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_StackedArea)), Value = SpreadsheetChartType.StackedArea },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Pie)), Value = SpreadsheetChartType.Pie },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Donut)), Value = SpreadsheetChartType.Donut },
new { Text = L(nameof(RadzenStrings.Spreadsheet_ChartType_Scatter)), Value = SpreadsheetChartType.Scatter },
];
legendPositions =
[
new { Text = L(nameof(RadzenStrings.Spreadsheet_LegendPosition_Right)), Value = ChartLegendPosition.Right },
new { Text = L(nameof(RadzenStrings.Spreadsheet_LegendPosition_Left)), Value = ChartLegendPosition.Left },
new { Text = L(nameof(RadzenStrings.Spreadsheet_LegendPosition_Top)), Value = ChartLegendPosition.Top },
new { Text = L(nameof(RadzenStrings.Spreadsheet_LegendPosition_Bottom)), Value = ChartLegendPosition.Bottom },
];
}
private void OnAddSeries()
{
Draft.Series.Add(new EditChartSeriesDraft
{
Index = Draft.Series.Count,
Name = $"Series {Draft.Series.Count + 1}"
Name = FormatSeriesName(Draft.Series.Count + 1)
});
}
@@ -126,9 +128,4 @@
{
DialogService.Close(Draft);
}
private void OnCancel()
{
DialogService.Close(null);
}
}

View File

@@ -2,6 +2,7 @@
@using Radzen.Blazor
@using Radzen.Blazor.Spreadsheet
@using Radzen.Documents.Spreadsheet
@inherits SpreadsheetDialogBase
<RadzenStack Orientation="Orientation.Vertical" Gap="20px">
<RadzenStack Orientation="Orientation.Horizontal" Gap="10px" AlignItems="AlignItems.Center">

View File

@@ -10,7 +10,7 @@ namespace Radzen.Blazor.Spreadsheet;
/// <summary>
/// Dialog for filtering data in a spreadsheet.
/// </summary>
public partial class FilterDialog : ComponentBase
public partial class FilterDialog : SpreadsheetDialogBase
{
enum FilterOperator
{
@@ -61,17 +61,6 @@ public partial class FilterDialog : ComponentBase
[Parameter]
public int Row { get; set; }
/// <summary>
/// The dialog service instance.
/// </summary>
[Inject]
public DialogService DialogService { get; set; } = default!;
[Inject]
Localizer Localizer { get; set; } = default!;
string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
/// <summary>
/// Optional existing filter criterion to populate default values.
/// </summary>
@@ -165,11 +154,6 @@ public partial class FilterDialog : ComponentBase
DialogService.Close(filter);
}
private void OnCancel()
{
DialogService.Close();
}
private SheetFilter? CreateFilter()
{
var dataTable = GetCurrentTable();

View File

@@ -2,6 +2,7 @@
@using Radzen.Blazor
@using Radzen.Blazor.Spreadsheet
@using Radzen.Documents.Spreadsheet
@inherits SpreadsheetDialogBase
<RadzenStack Orientation="Orientation.Horizontal" Gap="16px" Style="min-height: 320px">
<RadzenListBox @bind-Value=@selectedCategory Data=@categories TValue="NumberFormatCategory"

View File

@@ -12,7 +12,7 @@ namespace Radzen.Blazor.Spreadsheet;
/// <summary>
/// Dialog for formatting cells in a spreadsheet.
/// </summary>
public partial class FormatCellsDialog : ComponentBase
public partial class FormatCellsDialog : SpreadsheetDialogBase
{
/// <summary>
/// The current format of the selected cell.
@@ -32,17 +32,6 @@ public partial class FormatCellsDialog : ComponentBase
[Parameter]
public CellDataType ValueType { get; set; }
/// <summary>
/// The dialog service instance.
/// </summary>
[Inject]
public DialogService DialogService { get; set; } = default!;
[Inject]
Localizer Localizer { get; set; } = default!;
string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
private NumberFormatCategory selectedCategory = NumberFormatCategory.General;
private string customFormatCode = "General";
private int decimalPlaces = 2;
@@ -153,9 +142,4 @@ public partial class FormatCellsDialog : ComponentBase
{
DialogService.Close(customFormatCode);
}
private void OnCancel()
{
DialogService.Close();
}
}

View File

@@ -1,7 +1,6 @@
@using Radzen.Blazor
@using Radzen.Documents.Spreadsheet
@inject DialogService DialogService
@inject Localizer Localizer
@inherits SpreadsheetDialogBase
<RadzenStack Gap="1rem">
<RadzenStack Orientation="Orientation.Vertical" Gap="0.25rem">
@@ -38,8 +37,6 @@
[Parameter] public InsertTableDraft Draft { get; set; } = default!;
[Parameter] public string? FocusFieldId { get; set; }
private string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
private void OnNameChanged(string value) => Draft.Name = value ?? string.Empty;
private void OnHasHeadersChanged(bool value) => Draft.HasHeaders = value;
private void OnRangeFormulaChanged(string? value) => Draft.RangeFormula = value ?? string.Empty;
@@ -54,9 +51,4 @@
Draft.Name = Draft.Name.Trim();
DialogService.Close(Draft);
}
private void OnCancel()
{
DialogService.Close(null);
}
}

View File

@@ -1,5 +1,6 @@
@using Microsoft.AspNetCore.Components
@using Radzen.Blazor
@inherits SpreadsheetDialogBase
<RadzenStack Orientation="Orientation.Vertical" Gap="16px">
<RadzenTextBox @bind-Value=@Name Style="width: 100%" />

View File

@@ -10,7 +10,7 @@ namespace Radzen.Blazor.Spreadsheet;
/// <summary>
/// Dialog for renaming a sheet in a spreadsheet.
/// </summary>
public partial class RenameSheetDialog : ComponentBase
public partial class RenameSheetDialog : SpreadsheetDialogBase
{
/// <summary>
/// The current name of the sheet.
@@ -24,17 +24,6 @@ public partial class RenameSheetDialog : ComponentBase
[Parameter]
public IReadOnlyList<string> ExistingNames { get; set; } = [];
/// <summary>
/// The dialog service instance.
/// </summary>
[Inject]
public DialogService DialogService { get; set; } = default!;
[Inject]
Localizer Localizer { get; set; } = default!;
string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
private string? error;
private void OnOk()
@@ -56,9 +45,4 @@ public partial class RenameSheetDialog : ComponentBase
DialogService.Close(Name);
}
private void OnCancel()
{
DialogService.Close();
}
}

View File

@@ -0,0 +1,35 @@
using System.Globalization;
using Microsoft.AspNetCore.Components;
namespace Radzen.Blazor.Spreadsheet;
#nullable enable
/// <summary>
/// Base class for spreadsheet dialogs that provides shared <see cref="DialogService"/> injection,
/// a localizer, and a default cancel handler.
/// </summary>
public abstract class SpreadsheetDialogBase : ComponentBase
{
/// <summary>
/// Gets or sets the dialog service used to close the dialog.
/// </summary>
[Inject]
protected DialogService DialogService { get; set; } = default!;
/// <summary>
/// Gets or sets the localizer used to resolve resource strings.
/// </summary>
[Inject]
internal Localizer Localizer { get; set; } = default!;
/// <summary>
/// Returns the localized string for the specified resource key in the current UI culture.
/// </summary>
protected string L(string key) => Localizer.Get(key, CultureInfo.CurrentUICulture);
/// <summary>
/// Closes the dialog without returning a result.
/// </summary>
protected virtual void OnCancel() => DialogService.Close();
}

View File

@@ -1,7 +1,6 @@
@using Radzen.Blazor
@using Radzen.Documents.Spreadsheet
@inject DialogService DialogService
@inject Localizer Localizer
@inherits SpreadsheetDialogBase
<RadzenStack Gap="1rem" Style="min-width:320px">
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem">
@@ -29,8 +28,6 @@
/// <summary>Result returned by the dialog.</summary>
public sealed record Result(int Count, bool Percent, bool Bottom);
private string L(string key) => Localizer.Get(key, System.Globalization.CultureInfo.CurrentUICulture);
private bool bottom; // false = top, true = bottom
private bool percent; // false = items, true = percent
private int count = 10;
@@ -48,5 +45,4 @@
];
private void OnOk() => DialogService.Close(new Result(count, percent, bottom));
private void OnCancel() => DialogService.Close(null);
}