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

knowledgepixels / nanodash / 27811003513

19 Jun 2026 07:06AM UTC coverage: 26.612% (-0.4%) from 26.963%
27811003513

Pull #484

github

web-flow
Merge 2b4ad3339 into 0f6281554
Pull Request #484: Space-ref disambiguation: conflict notice, claimants overview, ref-pinned pages

1552 of 6853 branches covered (22.65%)

Branch coverage included in aggregate %.

3420 of 11830 relevant lines covered (28.91%)

4.26 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.menu.ViewDisplayMenu;
4
import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile;
5
import com.knowledgepixels.nanodash.page.NanodashPage;
6
import org.apache.wicket.markup.html.basic.Label;
7
import org.apache.wicket.markup.html.panel.Panel;
8
import org.apache.wicket.request.mapper.parameter.PageParameters;
9
import org.nanopub.extra.services.ApiResponse;
10
import org.nanopub.extra.services.QueryRef;
11

12
import java.io.Serializable;
13
import java.util.ArrayList;
14
import java.util.List;
15

16
/**
17
 * Abstract base class for displaying query results in different formats.
18
 */
19
public abstract class QueryResult extends Panel {
20

21
    /**
22
     * A view-level action, shown as a top entry of the view's dropdown menu.
23
     */
24
    public record MenuAction(String label, Class<? extends NanodashPage> pageClass, PageParameters params) implements Serializable {
×
25
    }
26

27
    protected final List<MenuAction> menuActions = new ArrayList<>();
×
28
    protected String contextId;
29
    protected String partId;
30
    protected String postPublishTab;
31
    // The ref (root definition) this view is pinned to (?root=), used to scope per-entry
32
    // action visibility to the claimant being viewed. Null = the resource's representative
33
    // ref. See docs/space-ref-identity.md.
34
    protected String refRoot;
35
    protected boolean finalized = false;
×
36
    protected final QueryRef queryRef;
37
    protected final ViewDisplay viewDisplay;
38
    protected final ApiResponse response;
39
    protected AbstractResourceWithProfile resourceWithProfile;
40
    protected AbstractResourceWithProfile pageResource;
41
    protected boolean showViewDisplayMenu = true;
×
42
    protected final GrlcQuery grlcQuery;
43

44
    /**
45
     * Constructor for QueryResult.
46
     *
47
     * @param markupId    the markup ID
48
     * @param queryRef    the query reference
49
     * @param response    the API response
50
     * @param viewDisplay the view display
51
     */
52
    public QueryResult(String markupId, QueryRef queryRef, ApiResponse response, ViewDisplay viewDisplay) {
53
        super(markupId);
×
54
        this.queryRef = queryRef;
×
55
        this.viewDisplay = viewDisplay;
×
56
        this.response = response;
×
57
        this.grlcQuery = GrlcQuery.get(queryRef);
×
58
    }
×
59

60
    @Override
61
    protected void onBeforeRender() {
62
        if (!finalized) {
×
63
            // View-level actions used to render as a button strip in the header here;
64
            // they now live as the top entries of the view's dropdown menu instead.
65
            add(new Label("buttons").setVisible(false));
×
66
            if (showViewDisplayMenu) {
×
67
                if (viewDisplay.getNanopubId() != null || !menuActions.isEmpty()) {
×
68
                    add(new ViewDisplayMenu("np", viewDisplay, queryRef, pageResource, menuActions));
×
69
                } else {
70
                    add(new Label("np").setVisible(false));
×
71
                }
72
            }
73
            finalized = true;
×
74
        }
75
        super.onBeforeRender();
×
76
    }
×
77

78
    /**
79
     * The view-level actions to render as top entries of the view's dropdown menu.
80
     *
81
     * @return the collected view-level menu actions
82
     */
83
    public List<MenuAction> getMenuActions() {
84
        return menuActions;
×
85
    }
86

87
    /**
88
     * Set the resource with profile for this component.
89
     *
90
     * @param resourceWithProfile The resource with profile to set.
91
     */
92
    public void setResourceWithProfile(AbstractResourceWithProfile resourceWithProfile) {
93
        this.resourceWithProfile = resourceWithProfile;
×
94
    }
×
95

96
    public void setPageResource(AbstractResourceWithProfile pageResource) {
97
        this.pageResource = pageResource;
×
98
    }
×
99

100
    /**
101
     * Set the context ID for this component.
102
     *
103
     * @param contextId The context ID to set.
104
     */
105
    public void setContextId(String contextId) {
106
        this.contextId = contextId;
×
107
    }
×
108

109
    /**
110
     * Set the part ID when this view is shown on a part page (e.g. paper collection).
111
     * Used for redirect-after-publish to return to the part page.
112
     *
113
     * @param partId The part ID to set, or null when on the main context page.
114
     */
115
    public void setPartId(String partId) {
116
        this.partId = partId;
×
117
    }
×
118

119
    /**
120
     * Set the tab to return to after publishing one of this view's action
121
     * buttons (e.g. {@code "about"} so a space's About-tab views send the user
122
     * back to About instead of the default Content tab). Null leaves the
123
     * post-publish redirect on its default tab.
124
     *
125
     * @param postPublishTab the tab name, or null for the default
126
     */
127
    public void setPostPublishTab(String postPublishTab) {
128
        this.postPublishTab = postPublishTab;
×
129
    }
×
130

131
    /**
132
     * Set the ref (root definition) this view is pinned to, so per-entry action visibility
133
     * is gated against that claimant's authority rather than the resource's representative
134
     * ref. Null = representative ref. See docs/space-ref-identity.md.
135
     *
136
     * @param refRoot the ref's root nanopub, or null
137
     */
138
    public void setRefRoot(String refRoot) {
139
        this.refRoot = refRoot;
×
140
    }
×
141

142
    /**
143
     * @return the tab to return to after publishing via an action button, or null for the default
144
     */
145
    public String getPostPublishTab() {
146
        return postPublishTab;
×
147
    }
148

149
    // A view-level action button; collected here and rendered as a top entry of the
150
    // view's dropdown menu (see ViewDisplayMenu).
151
    public void addButton(String label, Class<? extends NanodashPage> pageClass, PageParameters parameters) {
152
        if (parameters == null) {
×
153
            parameters = new PageParameters();
×
154
        }
155
        if (contextId != null) {
×
156
            parameters.set("context", contextId);
×
157
        }
158
        menuActions.add(new MenuAction(label, pageClass, parameters));
×
159
    }
×
160

161
    /**
162
     * Whether all result rows fit on the first page, so no pagination is needed
163
     * and the filter textfield can be hidden. Also true when the page size is
164
     * unlimited ({@code < 1}).
165
     *
166
     * @return true if all entries fit on the first page
167
     */
168
    protected boolean fitsOnFirstPage() {
169
        int pageSize = viewDisplay.getPageSize();
×
170
        return pageSize < 1 || response.getData().size() <= pageSize;
×
171
    }
172

173
    /**
174
     * Whether the empty state should point the viewer to the view-level actions:
175
     * the underlying response (not just a filtered view of it) has no rows, and
176
     * there is at least one action the viewer is entitled to.
177
     *
178
     * @return true if the empty-state call-to-action buttons should show
179
     */
180
    protected boolean hasEmptyStateActions() {
181
        return response.getData().isEmpty() && !menuActions.isEmpty();
×
182
    }
183

184
    /**
185
     * Populate the component with the query results.
186
     */
187
    protected abstract void populateComponent();
188

189
}
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