• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

knowledgepixels / nanodash / 36019764968

24 Sep 2026 03:22PM UTC coverage: 50.524% (+0.002%) from 50.522%
36019764968

push

github

web-flow
Merge pull request #737 from knowledgepixels/fix/735-description-html

fix(views): let a view's description carry markup

5250 of 11191 branches covered (46.91%)

Branch coverage included in aggregate %.

9310 of 17627 relevant lines covered (52.82%)

8.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
src/main/java/com/knowledgepixels/nanodash/component/HeaderViewPanel.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.QueryResult;
4
import com.knowledgepixels.nanodash.SpaceMemberRole;
5
import com.knowledgepixels.nanodash.View;
6
import com.knowledgepixels.nanodash.ViewDisplay;
7
import com.knowledgepixels.nanodash.component.menu.ViewDisplayMenu;
8
import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile;
9
import com.knowledgepixels.nanodash.domain.MaintainedResource;
10
import com.knowledgepixels.nanodash.domain.Space;
11
import com.knowledgepixels.nanodash.page.PublishPage;
12
import com.knowledgepixels.nanodash.repository.MaintainedResourceRepository;
13
import com.knowledgepixels.nanodash.template.Template;
14
import org.apache.wicket.markup.html.basic.Label;
15
import org.apache.wicket.markup.html.panel.Panel;
16
import org.apache.wicket.request.mapper.parameter.PageParameters;
17
import org.eclipse.rdf4j.model.IRI;
18

19
import java.util.ArrayList;
20
import java.util.List;
21

22
/**
23
 * The body of a header view ({@code gen:HeaderView}, issue #572): a section header
24
 * at the view's structural position, showing the view's title, an optional
25
 * description text below it, and the view's result-level actions as top entries of
26
 * the view-display dropdown menu. Header views have no query, so this panel always
27
 * renders synchronously.
28
 */
29
public class HeaderViewPanel extends Panel {
30

31
    /**
32
     * @param markupId            the Wicket markup id
33
     * @param viewDisplay         the view display of the header view
34
     * @param resourceWithProfile the resource whose page the header is on (actions
35
     *                            need it for visibility gating; may be null)
36
     * @param id                  the resource or part id the view is shown for
37
     * @param contextId           the context id, or null
38
     * @param refRoot             the pinned ref's root nanopub, or null
39
     */
40
    public HeaderViewPanel(String markupId, ViewDisplay viewDisplay, AbstractResourceWithProfile resourceWithProfile, String id, String contextId, String refRoot) {
41
        super(markupId);
×
42
        View view = viewDisplay.getView();
×
43
        add(new Label("title", viewDisplay.getTitle()));
×
44
        // Through the display, so that it can override the view's own text (issue #735).
45
        String description = viewDisplay.getDescription();
×
46
        add(new Label("description", description)
×
47
                .setEscapeModelStrings(false)
×
48
                .setVisible(description != null && !description.isBlank()));
×
49

50
        // Result-level actions become the top entries of the view-display menu,
51
        // mirroring how the query-result components route their view-level actions.
52
        List<QueryResult.MenuAction> menuActions = new ArrayList<>();
×
53
        if (resourceWithProfile != null) {
×
54
            for (IRI actionIri : view.getViewResultActionList()) {
×
55
                if (!SpaceMemberRole.isViewerEntitled(view.getActionVisibleTo(actionIri), resourceWithProfile, refRoot)) continue;
×
56
                Template t = view.getTemplateForAction(actionIri);
×
57
                if (t == null) continue;
×
58
                String targetField = view.getTemplateTargetFieldForAction(actionIri);
×
59
                if (targetField == null) targetField = "resource";
×
60
                String label = view.getLabelForAction(actionIri);
×
61
                if (label == null) label = "action...";
×
62
                if (!label.endsWith("...")) label += "...";
×
63
                PageParameters params = new PageParameters().set("template", t.getId())
×
64
                        .set("param_" + targetField, id)
×
65
                        .set("context", contextId)
×
66
                        .set("template-version", "latest");
×
67
                if (id != null && contextId != null && !id.equals(contextId)) {
×
68
                    params.set("part", id);
×
69
                }
70
                String partField = view.getTemplatePartFieldForAction(actionIri);
×
71
                if (partField != null && contextId != null) {
×
72
                    // The part field pre-fills a namespaced child IRI (the user fills the suffix).
73
                    MaintainedResource r = MaintainedResourceRepository.get().findById(contextId);
×
74
                    String namespace = null;
×
75
                    if (r != null) {
×
76
                        namespace = r.getNamespace();
×
77
                    } else if (resourceWithProfile instanceof Space) {
×
78
                        // The Space-creation templates' `space` placeholder has a fixed
79
                        // `https://w3id.org/spaces/` prefix, so the pre-fill is relative to it.
80
                        namespace = contextId.replaceFirst("https://w3id.org/spaces/", "") + "/";
×
81
                    }
82
                    if (namespace != null) {
×
83
                        params.set("param_" + partField, namespace + "<SET-SUFFIX>");
×
84
                    }
85
                }
86
                if (contextId != null) params.set("refresh-upon-publish", contextId);
×
87
                menuActions.add(new QueryResult.MenuAction(label, PublishPage.class, params));
×
88
            }
×
89
        }
90
        if (viewDisplay.getNanopubId() != null || !menuActions.isEmpty()) {
×
91
            add(new ViewDisplayMenu("np", viewDisplay, null, resourceWithProfile, menuActions));
×
92
        } else {
93
            add(new Label("np").setVisible(false));
×
94
        }
95
    }
×
96

97
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc