Skip to content

feat(views): pre-fill a result action's form from a fill query (#690) - #693

Merged
tkuhn merged 2 commits into
masterfrom
feat/690-action-fill-query
Sep 8, 2026
Merged

feat(views): pre-fill a result action's form from a fill query (#690)#693
tkuhn merged 2 commits into
masterfrom
feat/690-action-fill-query

Conversation

@tkuhn

@tkuhn tkuhn commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Closes #690.

What

A view's result action (the "add…" button) could pre-fill only the target field. It can now carry its own query, bound to the target resource, whose first result row pre-fills the form:

sub:addAction a gen:ViewResultAction ;
    gen:hasActionTemplate <…/presentation-template> ;
    gen:hasActionTemplateTargetField "event" ;
    gen:hasActionFillQuery <…/get-event-defaults> ;
    gen:hasActionFillQueryTargetField "event" ;          # optional, default "resource"
    gen:hasActionFillQueryMapping "startDate:startDate location:!location" .
  • The button carries the bound reference as fill-query / fill-query-mapping; PublishForm runs it when the form opens (cold cache blocks once, warm serves at once) and applies the first row only — these are defaults for single-valued fields, so no __i suffixes.
  • col:!field fills and locks the field, as entry actions already can (Locking pre-filled content #678). Blank values are skipped and left unlocked.
  • Precedence: fill query → listing values → explicit param_. An action can carry both a fill query and a listing mapping.
  • Magic parameters are bound at consumption, on the publishing user's request.
  • The fill mappings are kept apart from the listing mappings in View, so their columns are never hidden from the view's own table.

Doc: new section in docs/magic-query-params.md.

Also in here

  • Refactor (own commit): the result-action button block existed in four copies; the list, SVG and plain-paragraph builders now call ViewActionMappings.addResultActions. Two divergences resolved toward the shared version (null-guarded param_<target>/context; Space-namespace fallback for the part field); the paragraph builder's dead space field removed.
  • Fix: a result action with several listing mappings in one literal was passed raw and split on the first colon by the form ("a:b c:d" → target "b c", nothing filled). Not a regression — the result-action path never got the phase-2 multi-mapping support, and every multi-mapping in docs/queries/ is on an entry action. View.ActionMapping is now the one col:target parser for all three consumers.
  • A query the API fails on now costs the pre-fill rather than 500-ing the form.

Compatibility

  • Existing views render identically: no fill triples → no fill params; single listing mappings produce the same URL as before; "void" is dropped as before.
  • Old Nanodash ignores the new predicates (button without fill) — deploy before publishing views that use them.
  • View is persisted in the API cache snapshot with no serialVersionUID, so the first restart after deploy discards the snapshot and starts cold, by design (ApiCachePersistence.load); the per-entry store still serves query responses.

Verified

  • Full suite: 1340 tests, 0 failures. New: ViewFillQueryTest, ViewActionMappingsFillQueryTest (incl. the multi-mapping regression), PublishFormQueryFillTest (11 cases), fixture np-fill-query-view.trig.
  • Live demo on https://w3id.org/spaces/test/group: view RAqsB5Zk7p…/qa-fill-demo-view, fill query RA1MUappxs…/get-question-defaults, display RAcRiqiS1n…. On a local build, "❓ ask a question…" opens with the question text pre-filled from the space's label (editable) and the evidence pre-filled with the space's definition nanopub and locked (readonly + locked-value).

Follow-up (not in this PR)

The view-creation template needs three optional members for the new predicates so the form can express them; the target-field placeholder must carry no default. Tracked on #690.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LpQe4aJzdBr1epP8XSGYiY

tkuhn and others added 2 commits September 8, 2026 09:50
The block that turns a view's result actions into "add..." buttons existed
in four copies: ViewActionMappings.addResultActions and near-identical
copies in the list, SVG and plain-paragraph builders. Adding a parameter to
that block meant adding it four times. The three builders now call
addResultActions.

Two divergences of the copies are resolved deliberately, both in favour of
the shared version: param_<target> and context are only set when there is
a target (the SVG copy set them unguarded), and the part field falls back
to a Space's namespace where no maintained resource is found (the SVG and
paragraph copies only knew maintained resources). The paragraph builder's
`space` field, which had no setter and was therefore never non-null, is
removed along with the line that read it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpQe4aJzdBr1epP8XSGYiY
A view's result action could pre-fill only the target field with the page
resource's IRI. gen:hasActionTemplateQueryMapping reads the listing's rows,
which is the wrong source for a default inherited from the target: with no
rows it fills nothing, and with n rows it fills the same value n times as
field, field__1, ... on a field that is not repeatable.

An action can now carry its own query, bound to the target:

  gen:hasActionFillQuery            the query
  gen:hasActionFillQueryTargetField the placeholder the target's IRI is
                                    bound to (optional, default "resource")
  gen:hasActionFillQueryMapping     "col:field" mappings; "col:!field" also
                                    locks the field (docs/locked-prefilled-values.md)

The button carries the bound reference as fill-query / fill-query-mapping;
the publish form runs it when it opens and applies the FIRST row only, as
these are defaults for single-valued fields. Blank values are skipped and
left unlocked. Order of precedence is fill query, then listing values, then
explicit param_ parameters. Magic parameters are bound at consumption, so a
fill query sees the user opening the form. The fill mappings live in their
own map in View, so their columns never count as mapping-source columns of
the view's own query.

Also fixed on the way: a result action with several listing mappings in one
literal was passed raw and split on its first colon by the form, so
"a:b c:d" became a target of "b c" and filled nothing. Every multi-mapping
in docs/queries/ is on an entry action, which is why it went unnoticed. The
form now applies every mapping, and View.ActionMapping is the one parser
for "col:target" in all three places it is read. A query the API fails on
now costs the pre-fill rather than the form.

Verified live on https://w3id.org/spaces/test/group with a demo view whose
"ask a question" action pre-fills the question text from the space's label
and locks the evidence to the space's definition nanopub.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpQe4aJzdBr1epP8XSGYiY
@tkuhn
tkuhn merged commit d9e17dd into master Sep 8, 2026
8 checks passed
@tkuhn
tkuhn deleted the feat/690-action-fill-query branch September 8, 2026 08:35
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 5.14.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Let a view's result action pre-fill fields from properties of the target resource

1 participant