Skip to content

Commit 91868f2

Browse files
committed
Refactor QueryTableComponentBase: streamline query state handling and improve initialization logic.
1 parent c63be8a commit 91868f2

File tree

1 file changed

+61
-83
lines changed

1 file changed

+61
-83
lines changed
Lines changed: 61 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
1-
using Elsa.Studio.Components;
1+
using Elsa.Studio.Components;
22
using Microsoft.AspNetCore.Components;
33
using Microsoft.AspNetCore.WebUtilities;
44
using Microsoft.Extensions.Logging;
55
using MudBlazor;
6-
namespace Elsa.Studio.Workflows.Components;
7-
8-
/// <summary>
9-
/// Base component that provides common URL query parsing and update logic for
10-
/// table components that want to reflect state in the query string.
11-
/// Derived components must implement ApplyQueryParameters and BuildQueryFromState.
12-
/// </summary>
13-
public abstract class QueryTableComponentBase : StudioComponentBase
6+
namespace Elsa.Studio.Workflows.Components
147
{
15-
protected bool _initializedFromQuery;
16-
17-
[Inject] protected NavigationManager NavigationManager { get; set; } = default!;
18-
[Inject] protected ILogger<QueryTableComponentBase>? Logger { get; set; }
19-
208
/// <summary>
21-
/// Specifies the initial page index used when starting pagination operations.
9+
/// Base component that provides common URL query parsing and update logic for
10+
/// table components that want to reflect state in the query string.
11+
/// Derived components must implement ApplyQueryParameters and BuildQueryFromState.
2212
/// </summary>
2313
public abstract class QueryTableComponentBase : StudioComponentBase
2414
{
@@ -37,8 +27,6 @@ public abstract class QueryTableComponentBase : StudioComponentBase
3727
/// </summary>
3828
protected int InitialPage { get; set; } = 0;
3929

40-
{
41-
if (firstRender)
4230
/// <summary>
4331
/// Specifies the initial number of items to display per page.
4432
/// </summary>
@@ -54,18 +42,15 @@ public abstract class QueryTableComponentBase : StudioComponentBase
5442
/// <inheritdoc/>
5543
protected override async Task OnAfterRenderAsync(bool firstRender)
5644
{
57-
await ParseQueryParameters();
58-
StateHasChanged();
59-
}
45+
if (firstRender)
46+
{
47+
await ParseQueryParameters();
48+
StateHasChanged();
49+
}
6050

51+
await base.OnAfterRenderAsync(firstRender);
52+
}
6153

62-
/// <summary>
63-
/// Parses the current URI's query string and delegates to <see cref="ApplyQueryParameters"/>.
64-
/// Only runs once unless you reset <see cref="InitializedFromQuery"/> or call ParseQueryParameters(force: true).
65-
/// </summary>
66-
private async Task ParseQueryParameters(bool force = false)
67-
{
68-
if (InitializedFromQuery && !force) return;
6954
/// <summary>
7055
/// Parses the current URI's query string and delegates to <see cref="ApplyQueryParameters"/>.
7156
/// Only runs once unless you reset <see cref="InitializedFromQuery"/> or call ParseQueryParameters(force: true).
@@ -74,44 +59,36 @@ private async Task ParseQueryParameters(bool force = false)
7459
{
7560
if (InitializedFromQuery && !force) return;
7661

77-
/// <summary>
78-
/// Parses the current URI's query string and delegates to <see cref="ApplyQueryParameters"/>.
79-
/// Only runs once unless you clear _initializedFromQuery or call ParseQueryParameters(force: true).
80-
/// </summary>
81-
protected async Task ParseQueryParameters(bool force = false)
82-
{
83-
if (_initializedFromQuery && !force) return;
62+
try
63+
{
64+
var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
65+
var query = QueryHelpers.ParseQuery(uri.Query);
8466

85-
try
86-
{
87-
var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
88-
var query = QueryHelpers.ParseQuery(uri.Query);
67+
// Convert StringValues to single string values
68+
var dict = query.ToDictionary(k => k.Key, kv => kv.Value.ToString(), StringComparer.OrdinalIgnoreCase);
8969

90-
// Convert StringValues to single string values
91-
var dict = query.ToDictionary(k => k.Key, kv => kv.Value.ToString(), StringComparer.OrdinalIgnoreCase);
70+
try
71+
{
72+
await ApplyQueryParameters(dict);
73+
}
74+
catch (Exception ex)
75+
{
76+
Logger?.LogDebug(ex, "Error while applying query parameters in derived component.");
77+
}
9278

9379
InitializedFromQuery = true;
9480
}
9581
catch (Exception ex)
9682
{
97-
Logger?.LogDebug(ex, "Error while applying query parameters in derived component.");
83+
Logger?.LogWarning(ex, "Failed parsing query parameters.");
9884
}
99-
100-
_initializedFromQuery = true;
101-
}
102-
catch (Exception ex)
103-
{
104-
Logger?.LogWarning(ex, "Failed parsing query parameters.");
10585
}
106-
}
10786

108-
/// <summary>
109-
/// Build and navigate to an updated URI that reflects the provided table state.
110-
/// Delegates construction of the query dictionary to <see cref="BuildQueryFromState"/>.
111-
/// </summary>
112-
protected void TryUpdateUrlFromState(TableState state)
113-
{
114-
try
87+
/// <summary>
88+
/// Build and navigate to an updated URI that reflects the provided table state.
89+
/// Delegates construction of the query dictionary to <see cref="BuildQueryFromState"/>.
90+
/// </summary>
91+
protected void TryUpdateUrlFromState(TableState state)
11592
{
11693
try
11794
{
@@ -124,37 +101,38 @@ protected void TryUpdateUrlFromState(TableState state)
124101
var dict = query.Where(kv => !string.IsNullOrEmpty(kv.Value)).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase);
125102
var newUri = QueryHelpers.AddQueryString(baseUri, dict);
126103

127-
if (!string.Equals(NavigationManager.Uri, newUri, StringComparison.Ordinal))
128-
NavigationManager.NavigateTo(newUri, replace: true);
129-
}
130-
catch (Exception ex)
131-
{
132-
Logger?.LogWarning(ex, "Failed to update URL with table state.");
104+
if (!string.Equals(NavigationManager.Uri, newUri, StringComparison.Ordinal))
105+
NavigationManager.NavigateTo(newUri, replace: true);
106+
}
107+
catch (Exception ex)
108+
{
109+
Logger?.LogWarning(ex, "Failed to update URL with table state.");
110+
}
133111
}
134-
}
135112

136-
/// <summary>
137-
/// Derived components must map parsed key/value pairs (from the query string)
138-
/// to their local component state in this method.
139-
/// </summary>
140-
/// <param name="query">Key -> string value dictionary (single values only).</param>
141-
//protected abstract void ApplyQueryParameters(IDictionary<string, string> query);
142-
protected abstract Task ApplyQueryParameters(IDictionary<string, string> query);
113+
/// <summary>
114+
/// Derived components must map parsed key/value pairs (from the query string)
115+
/// to their local component state in this method.
116+
/// </summary>
117+
/// <param name="query">Key -> string value dictionary (single values only).</param>
118+
//protected abstract void ApplyQueryParameters(IDictionary<string, string> query);
119+
protected abstract Task ApplyQueryParameters(IDictionary<string, string> query);
143120

144-
/// <summary>
145-
/// Derived components must return the query dictionary to represent the current state
146-
/// (keys -> values). Values that are null or empty will be excluded before navigation.
147-
/// </summary>
148-
protected abstract Dictionary<string, string?> BuildQueryFromState(TableState state);
121+
/// <summary>
122+
/// Derived components must return the query dictionary to represent the current state
123+
/// (keys -> values). Values that are null or empty will be excluded before navigation.
124+
/// </summary>
125+
protected abstract Dictionary<string, string?> BuildQueryFromState(TableState state);
149126

150-
/// <summary>
151-
/// Convenience helper used by components that need the timestamp filter encoding.
152-
/// </summary>
153-
protected static string EncodeTimestampFiltersToBase64Json<T>(IEnumerable<T> filters)
154-
{
155-
var opts = new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.Web) { WriteIndented = false };
156-
var json = System.Text.Json.JsonSerializer.Serialize(filters, opts);
157-
var bytes = System.Text.Encoding.UTF8.GetBytes(json);
158-
return Convert.ToBase64String(bytes);
127+
/// <summary>
128+
/// Convenience helper used by components that need the timestamp filter encoding.
129+
/// </summary>
130+
protected static string EncodeTimestampFiltersToBase64Json<T>(IEnumerable<T> filters)
131+
{
132+
var opts = new System.Text.Json.JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults.Web) { WriteIndented = false };
133+
var json = System.Text.Json.JsonSerializer.Serialize(filters, opts);
134+
var bytes = System.Text.Encoding.UTF8.GetBytes(json);
135+
return Convert.ToBase64String(bytes);
136+
}
159137
}
160138
}

0 commit comments

Comments
 (0)