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

knowledgepixels / nanodash / 27622721129

16 Jun 2026 01:55PM UTC coverage: 26.963% (+6.3%) from 20.697%
27622721129

Pull #483

github

web-flow
Merge 73a4d0fe1 into 663f14f46
Pull Request #483: Space/resource About pages, ref-aware spaces, and magic query params

1542 of 6717 branches covered (22.96%)

Branch coverage included in aggregate %.

3407 of 11638 relevant lines covered (29.27%)

4.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/component/ResourceTabs.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.page.ExplorePage;
4
import com.knowledgepixels.nanodash.page.MaintainedResourcePage;
5
import com.knowledgepixels.nanodash.page.ResourcePartPage;
6
import com.knowledgepixels.nanodash.page.SpacePage;
7
import com.knowledgepixels.nanodash.page.UserPage;
8
import org.apache.wicket.behavior.AttributeAppender;
9
import org.apache.wicket.markup.html.WebMarkupContainer;
10
import org.apache.wicket.markup.html.WebPage;
11
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
12
import org.apache.wicket.markup.html.panel.Panel;
13
import org.apache.wicket.request.mapper.parameter.PageParameters;
14

15
/**
16
 * Tab strip shown at the top of a resource's page, switching between the
17
 * <b>Content</b> tab (the rendered view displays), the <b>About</b> tab (the
18
 * listing of roles/presets/view displays), the <b>Explore</b> tab (the generic
19
 * exploration panels and references), and the <b>Raw</b> tab (the downloadable
20
 * RDF of all nanopubs on the page).
21
 *
22
 * <p>All tabs are the same page, selected via the {@code tab} query parameter
23
 * ({@code content} is the default and carries no parameter). Parts
24
 * ({@code type == "part"}) have no About tab.</p>
25
 */
26
public class ResourceTabs extends Panel {
27

28
    /**
29
     * Which tab is currently shown (rendered as the selected tab).
30
     */
31
    public enum Tab {CONTENT, ABOUT, EXPLORE, RAW}
×
32

33
    /**
34
     * Maps the {@code tab} query parameter to a {@link Tab} (defaulting to
35
     * {@link Tab#CONTENT}). Used by the resource pages to pick which tab body to
36
     * render and which tab to mark active.
37
     *
38
     * @param parameters the page parameters
39
     * @return the selected tab
40
     */
41
    public static Tab activeFromParam(PageParameters parameters) {
42
        switch (parameters.get("tab").toString("content")) {
×
43
            case "about":
44
                return Tab.ABOUT;
×
45
            case "explore":
46
                return Tab.EXPLORE;
×
47
            case "raw":
48
                return Tab.RAW;
×
49
            default:
50
                return Tab.CONTENT;
×
51
        }
52
    }
53

54
    /**
55
     * Constructs the tab strip for a top-level resource (space, user, resource).
56
     *
57
     * @param id         the Wicket markup id
58
     * @param type       the resource kind: {@code "space"}, {@code "user"}, or {@code "resource"}
59
     * @param resourceId the resource IRI
60
     * @param active     the tab to mark as selected
61
     */
62
    public ResourceTabs(String id, String type, String resourceId, Tab active) {
63
        this(id, type, resourceId, null, active);
×
64
    }
×
65

66
    /**
67
     * Constructs the tab strip, optionally for a part (which carries a context).
68
     *
69
     * @param id         the Wicket markup id
70
     * @param type       the resource kind: {@code "space"}, {@code "user"}, {@code "resource"}, or {@code "part"}
71
     * @param resourceId the resource (or part) IRI
72
     * @param contextId  the context resource IRI (for parts), or {@code null}
73
     * @param active     the tab to mark as selected
74
     */
75
    public ResourceTabs(String id, String type, String resourceId, String contextId, Tab active) {
76
        super(id);
×
77

78
        Class<? extends WebPage> pageClass;
79
        boolean hasAbout;
80
        switch (type) {
×
81
            case "space":
82
                pageClass = SpacePage.class;
×
83
                hasAbout = true;
×
84
                break;
×
85
            case "user":
86
                pageClass = UserPage.class;
×
87
                hasAbout = true;
×
88
                break;
×
89
            case "resource":
90
                pageClass = MaintainedResourcePage.class;
×
91
                hasAbout = true;
×
92
                break;
×
93
            case "part":
94
                pageClass = ResourcePartPage.class;
×
95
                hasAbout = true;
×
96
                break;
×
97
            default:
98
                throw new IllegalArgumentException("Unknown resource type: " + type);
×
99
        }
100

101
        add(tabLink("content-tab", pageClass, params(resourceId, contextId, null), active == Tab.CONTENT));
×
102
        if (hasAbout) {
×
103
            add(tabLink("about-tab", pageClass, params(resourceId, contextId, "about"), active == Tab.ABOUT));
×
104
        } else {
105
            add(new WebMarkupContainer("about-tab").setVisible(false));
×
106
        }
107
        add(tabLink("explore-tab", pageClass, params(resourceId, contextId, "explore"), active == Tab.EXPLORE));
×
108
        add(tabLink("raw-tab", pageClass, params(resourceId, contextId, "raw"), active == Tab.RAW));
×
109
    }
×
110

111
    /**
112
     * Constructs a two-tab strip (<b>Content</b> | <b>Explore</b>) for the
113
     * standalone {@link ExplorePage}. Unlike the resource variants this carries
114
     * the page's full parameter set (minus {@code tab}) across tab switches so
115
     * the resolved id, context and label are preserved, and it has neither an
116
     * About nor a Raw tab.
117
     *
118
     * @param id         the Wicket markup id
119
     * @param baseParams the explore page's parameters to preserve across tabs
120
     * @param active     the tab to mark as selected
121
     */
122
    public ResourceTabs(String id, PageParameters baseParams, Tab active) {
123
        super(id);
×
124

125
        PageParameters contentParams = new PageParameters(baseParams);
×
126
        contentParams.remove("tab");
×
127
        PageParameters exploreParams = new PageParameters(contentParams);
×
128
        exploreParams.set("tab", "explore");
×
129

130
        add(tabLink("content-tab", ExplorePage.class, contentParams, active == Tab.CONTENT));
×
131
        add(new WebMarkupContainer("about-tab").setVisible(false));
×
132
        add(tabLink("explore-tab", ExplorePage.class, exploreParams, active == Tab.EXPLORE));
×
133
        add(new WebMarkupContainer("raw-tab").setVisible(false));
×
134
    }
×
135

136
    /**
137
     * The gray-italic title suffix shown after the resource name on non-content
138
     * tabs (e.g. " – About"); empty for the content tab.
139
     *
140
     * @param tab the active tab
141
     * @return the suffix string (possibly empty)
142
     */
143
    public static String titleSuffix(Tab tab) {
144
        switch (tab) {
×
145
            case ABOUT:
146
                return " – About";
×
147
            case EXPLORE:
148
                return " – Explore";
×
149
            case RAW:
150
                return " – Raw";
×
151
            default:
152
                return "";
×
153
        }
154
    }
155

156
    private PageParameters params(String resourceId, String contextId, String tab) {
157
        PageParameters p = new PageParameters().set("id", resourceId);
×
158
        if (contextId != null) p.set("context", contextId);
×
159
        if (tab != null) p.set("tab", tab);
×
160
        return p;
×
161
    }
162

163
    private BookmarkablePageLink<Void> tabLink(String id, Class<? extends WebPage> pageClass, PageParameters params, boolean selected) {
164
        BookmarkablePageLink<Void> link = new BookmarkablePageLink<>(id, pageClass, params);
×
165
        if (selected) {
×
166
            link.add(new AttributeAppender("class", " selected"));
×
167
        }
168
        return link;
×
169
    }
170

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