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

knowledgepixels / nanodash / 27145358627

08 Jun 2026 02:39PM UTC coverage: 20.682% (-0.3%) from 20.947%
27145358627

push

github

web-flow
Merge pull request #479 from knowledgepixels/feat/about-pages-478

Resource-page tabs, presets, and role-gated view actions (#478, #302)

1052 of 6429 branches covered (16.36%)

Branch coverage included in aggregate %.

2642 of 11432 relevant lines covered (23.11%)

3.31 hits per line

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

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

3
import com.knowledgepixels.nanodash.component.ButtonList;
4
import com.knowledgepixels.nanodash.component.menu.ViewDisplayMenu;
5
import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile;
6
import com.knowledgepixels.nanodash.domain.IndividualAgent;
7
import com.knowledgepixels.nanodash.page.NanodashPage;
8
import org.apache.wicket.markup.html.basic.Label;
9
import org.apache.wicket.markup.html.link.AbstractLink;
10
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
11
import org.apache.wicket.markup.html.panel.Panel;
12
import org.apache.wicket.model.Model;
13
import org.apache.wicket.request.mapper.parameter.PageParameters;
14
import org.nanopub.extra.services.ApiResponse;
15
import org.nanopub.extra.services.QueryRef;
16

17
import java.util.ArrayList;
18
import java.util.List;
19

20
/**
21
 * Abstract base class for displaying query results in different formats.
22
 */
23
public abstract class QueryResult extends Panel {
24

25
    protected final List<AbstractLink> buttons = new ArrayList<>();
×
26
    protected String contextId;
27
    protected String partId;
28
    protected boolean finalized = false;
×
29
    protected final QueryRef queryRef;
30
    protected final ViewDisplay viewDisplay;
31
    protected final ApiResponse response;
32
    protected AbstractResourceWithProfile resourceWithProfile;
33
    protected AbstractResourceWithProfile pageResource;
34
    protected boolean showViewDisplayMenu = true;
×
35
    protected final GrlcQuery grlcQuery;
36

37
    /**
38
     * Constructor for QueryResult.
39
     *
40
     * @param markupId    the markup ID
41
     * @param queryRef    the query reference
42
     * @param response    the API response
43
     * @param viewDisplay the view display
44
     */
45
    public QueryResult(String markupId, QueryRef queryRef, ApiResponse response, ViewDisplay viewDisplay) {
46
        super(markupId);
×
47
        this.queryRef = queryRef;
×
48
        this.viewDisplay = viewDisplay;
×
49
        this.response = response;
×
50
        this.grlcQuery = GrlcQuery.get(queryRef);
×
51
    }
×
52

53
    @Override
54
    protected void onBeforeRender() {
55
        if (!finalized) {
×
56
            if (!buttons.isEmpty()) {
×
57
                // TODO: Add more flexible ways to restrict button visibility (e.g. per-view or per-action permissions)
58
                if (resourceWithProfile instanceof IndividualAgent) {
×
59
                    add(new ButtonList("buttons", resourceWithProfile, null, null, buttons));
×
60
                } else {
61
                    add(new ButtonList("buttons", resourceWithProfile, buttons, null, null));
×
62
                }
63
            } else {
64
                add(new Label("buttons").setVisible(false));
×
65
            }
66
            if (showViewDisplayMenu) {
×
67
                if (viewDisplay.getNanopubId() != null) {
×
68
                    add(new ViewDisplayMenu("np", viewDisplay, queryRef, pageResource));
×
69
                } else {
70
                    add(new Label("np").setVisible(false));
×
71
                }
72
            }
73
            finalized = true;
×
74
        }
75
        super.onBeforeRender();
×
76
    }
×
77

78
    /**
79
     * Set the resource with profile for this component.
80
     *
81
     * @param resourceWithProfile The resource with profile to set.
82
     */
83
    public void setResourceWithProfile(AbstractResourceWithProfile resourceWithProfile) {
84
        this.resourceWithProfile = resourceWithProfile;
×
85
    }
×
86

87
    public void setPageResource(AbstractResourceWithProfile pageResource) {
88
        this.pageResource = pageResource;
×
89
    }
×
90

91
    /**
92
     * Set the context ID for this component.
93
     *
94
     * @param contextId The context ID to set.
95
     */
96
    public void setContextId(String contextId) {
97
        this.contextId = contextId;
×
98
    }
×
99

100
    /**
101
     * Set the part ID when this view is shown on a part page (e.g. paper collection).
102
     * Used for redirect-after-publish to return to the part page.
103
     *
104
     * @param partId The part ID to set, or null when on the main context page.
105
     */
106
    public void setPartId(String partId) {
107
        this.partId = partId;
×
108
    }
×
109

110
    // TODO button adding method copied and adjusted from ItemListPanel
111
    // TODO Improve this (member/admin) button handling:
112
    public void addButton(String label, Class<? extends NanodashPage> pageClass, PageParameters parameters) {
113
        if (parameters == null) {
×
114
            parameters = new PageParameters();
×
115
        }
116
        if (contextId != null) {
×
117
            parameters.set("context", contextId);
×
118
        }
119
        AbstractLink button = new BookmarkablePageLink<NanodashPage>("button", pageClass, parameters);
×
120
        button.setBody(Model.of(label));
×
121
        buttons.add(button);
×
122
    }
×
123

124
    /**
125
     * Whether all result rows fit on the first page, so no pagination is needed
126
     * and the filter textfield can be hidden. Also true when the page size is
127
     * unlimited ({@code < 1}).
128
     *
129
     * @return true if all entries fit on the first page
130
     */
131
    protected boolean fitsOnFirstPage() {
132
        int pageSize = viewDisplay.getPageSize();
×
133
        return pageSize < 1 || response.getData().size() <= pageSize;
×
134
    }
135

136
    /**
137
     * Populate the component with the query results.
138
     */
139
    protected abstract void populateComponent();
140

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

© 2026 Coveralls, Inc