Group FAQs by a topic relation, ordered; drop unused FAQ teaser

This commit is contained in:
tleininger committed 2026-09-29 22:11:30 +02:00
1 parent 28944c155a
commit 2ea8856d65
14 files changed
+328 -128

No files matched your search

+21 -9
View File
@@ -70,15 +70,17 @@ public sealed class PocketBaseClient(HttpClient httpClient)
=> GetRecordsAsync<Event>("events", "start", token);
/// <summary>
/// Gets all public FAQ entries, ordered by <see cref="Faq.Topic"/>, then by
/// the editor's <c>order</c> within each topic.
/// Gets all public FAQ entries, grouped by topic: ordered by the topic's own
/// <c>order</c>, then by the entry's <c>order</c> within that topic. Each entry
/// carries its expanded <see cref="Faq.Topic"/>.
/// </summary>
/// <remarks>
/// The second sort key makes the order total: sorting by topic alone leaves
/// entries within a topic in an undefined order, so the same content could
/// render differently between requests. The per-topic <c>order</c> field lets
/// an editor arrange the questions within a topic and keeps that arrangement
/// stable between requests; the topic groups themselves stay alphabetical.
/// Sorting by <c>topic.order</c> first keeps all questions of a topic together
/// and lists the topic groups in the order an editor gave the topics; the
/// entry's own <c>order</c> then arranges the questions within each group. Both
/// keys together make the order total, so the same content renders the same way
/// between requests. The topic relation is expanded so the page can show each
/// group's heading without a second request.
/// </remarks>
/// <inheritdoc cref="GetPagesAsync" path="/param"/>
/// <returns>
@@ -86,7 +88,7 @@ public sealed class PocketBaseClient(HttpClient httpClient)
/// </returns>
/// <inheritdoc cref="GetPagesAsync" path="/exception"/>
public Task<IReadOnlyList<Faq>> GetFaqsAsync(CancellationToken token = default)
=> GetRecordsAsync<Faq>("faqs", "topic,order", token);
=> GetRecordsAsync<Faq>("faqs", "topic.order,order", token, expand: "topic");
/// <summary>
/// Gets all public records of a collection in a single request.
@@ -103,6 +105,10 @@ public sealed class PocketBaseClient(HttpClient httpClient)
/// <param name="token">
/// A token to cancel the request.
/// </param>
/// <param name="expand">
/// A PocketBase <c>expand</c> expression naming relations to resolve inline
/// (comma-separated, dot-nested), or <see langword="null"/> to expand none.
/// </param>
/// <returns>
/// The public records, or an empty list if there are none.
/// </returns>
@@ -115,7 +121,8 @@ public sealed class PocketBaseClient(HttpClient httpClient)
private async Task<IReadOnlyList<T>> GetRecordsAsync<T>(
string collection,
string sort,
CancellationToken token)
CancellationToken token,
string? expand = null)
{
// filter=public=true keeps drafts out; perPage is large enough to fetch
// every record in a single page given the small content volume.
@@ -123,6 +130,11 @@ public sealed class PocketBaseClient(HttpClient httpClient)
+ $"?perPage=500&filter={Uri.EscapeDataString("public=true")}"
+ $"&sort={Uri.EscapeDataString(sort)}";
// Add expand only when asked, so callers that need no relations send the
// leaner request they did before.
if (expand is not null)
url += $"&expand={Uri.EscapeDataString(expand)}";
try
{
var result = await httpClient.GetFromJsonAsync<RecordList<T>>(url, token);