using Invercargill; using Statum; namespace UsmWeb { /** * Server-side search: filters the {@link PackagesState.SLOT_TYPE} PAGE * slot's package table by the `query` form field (case-insensitive * substring over name and summary). * * Collection-typed slot fields cannot be read back from held state, so * the filtered rows are rebuilt from the repository (the documented * rebuild-from-source pattern) and written as one slot update keyed by * the held slot's key. */ public class SearchPackagesAction : StatumAction { protected RepositoryService repositories = Inversion.inject(); protected UsmWebConfig config = Inversion.inject(); protected Astralis.HttpContext http_context = Inversion.inject(); public override async DirectiveBuilder handle() throws GLib.Error { string query = ""; if (request.form != null) { query = (request.form.get_field("query") ?? "").strip(); } HeldSlot held; if (!request.held.try_get(PackagesState.SLOT_TYPE, out held) || held == null) { return directives().error("No \"packages\" slot held — reload the page"); } var base_uri = DerivedBase.derive(http_context.request, config); State state; try { state = PackagesState.build(repositories, config, action_registry, base_uri, query); } catch (Error e) { return directives().notify("error", @"Repository load failed: $(e.message)"); } return directives().update(((!)held).key, state); } } }