• 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/page/MaintainedResourcePage.java
1
package com.knowledgepixels.nanodash.page;
2

3
import com.knowledgepixels.nanodash.NanodashPageRef;
4
import com.knowledgepixels.nanodash.SpaceMemberRole;
5
import com.knowledgepixels.nanodash.component.*;
6
import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile;
7
import com.knowledgepixels.nanodash.domain.MaintainedResource;
8
import com.knowledgepixels.nanodash.domain.Space;
9
import com.knowledgepixels.nanodash.repository.MaintainedResourceRepository;
10
import org.apache.wicket.Component;
11
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
12
import org.apache.wicket.markup.html.WebMarkupContainer;
13
import org.apache.wicket.markup.html.basic.Label;
14
import org.apache.wicket.markup.html.panel.EmptyPanel;
15
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
16
import org.apache.wicket.model.IModel;
17
import org.apache.wicket.model.LoadableDetachableModel;
18
import org.apache.wicket.model.Model;
19
import org.apache.wicket.request.mapper.parameter.PageParameters;
20
import org.eclipse.rdf4j.model.util.Values;
21

22
import java.util.List;
23

24
/**
25
 * This class represents a page for a maintained resource.
26
 */
27
public class MaintainedResourcePage extends NanodashPage {
28

29
    /**
30
     * The mount path for this page.
31
     */
32
    public static final String MOUNT_PATH = "/resource";
33

34
    /**
35
     * {@inheritDoc}
36
     */
37
    @Override
38
    public String getMountPath() {
39
        return MOUNT_PATH;
×
40
    }
41

42
    /**
43
     * Id of the maintained resource shown on this page. Only the id is held in
44
     * the page state; the {@link MaintainedResource} itself is re-fetched from
45
     * the repository on every render via {@link #resourceModel}, so the page
46
     * tree never carries a serialized snapshot of singleton data.
47
     */
48
    private final String resourceId;
49

50
    /**
51
     * LDM that resolves {@link #resourceId} to the live {@link MaintainedResource} singleton.
52
     */
53
    private final IModel<MaintainedResource> resourceModel;
54

55
    public MaintainedResourcePage(final PageParameters parameters) {
56
        super(parameters);
×
57

58
        MaintainedResource resource = MaintainedResourceRepository.get().findById(parameters.get("id").toString());
×
59
        resourceId = resource.getId();
×
60
        resourceModel = new LoadableDetachableModel<MaintainedResource>() {
×
61
            @Override
62
            protected MaintainedResource load() {
63
                return MaintainedResourceRepository.get().findById(resourceId);
×
64
            }
65
        };
66
        resource.triggerDataUpdate();
×
67

68
        ResourceTabs.Tab activeTab = ResourceTabs.activeFromParam(parameters);
×
69

70
        List<AbstractResourceWithProfile> superSpaces = resource.getAllSuperSpacesUntilRoot();
×
71
        superSpaces.add(resource.getSpace());
×
72
        superSpaces.add(resource);
×
73
        add(new TitleBar("titlebar", this, null,
×
74
                superSpaces.stream().map(ss -> new NanodashPageRef(SpacePage.class, new PageParameters().add("id", ss.getId()), ss.getLabel())).toArray(NanodashPageRef[]::new)
×
75
        ).setTabs(new ResourceTabs("tabs", "resource", resource.getId(), activeTab)));
×
76

77
        add(new JustPublishedMessagePanel("justPublishedMessage", parameters));
×
78

79
        add(new Label("pagetitle", resource.getLabel() + " (resource) | nanodash"));
×
80
        add(new Label("resourcename", resource.getLabel()));
×
81
        add(new Label("titlesuffix", ResourceTabs.titleSuffix(activeTab)));
×
82
        add(new ExternalLinkWithActionsPanel("id", Model.of(resource.getId()), Model.of(resource.getLabel()), Values.iri(resource.getNanopubId())));
×
83

84
        String namespaceUri = resource.getNamespace() == null ? "" : resource.getNamespace();
×
85
        add(new BookmarkablePageLink<Void>("namespace", ExplorePage.class, new PageParameters().set("id", namespaceUri)).setBody(Model.of(namespaceUri)));
×
86

87

88
        WebMarkupContainer contentContainer = new WebMarkupContainer("contentContainer");
×
89
        add(contentContainer);
×
90
        if (activeTab == ResourceTabs.Tab.CONTENT) {
×
91
            add(new EmptyPanel("otherTab").setVisible(false));
×
92
            if (resource.isDataInitialized()) {
×
93
                contentContainer.add(new ViewList("views", resource));
×
94
            } else {
95
                contentContainer.add(new AjaxLazyLoadPanel<Component>("views") {
×
96

97
                    @Override
98
                    public Component getLazyLoadComponent(String markupId) {
99
                        return new ViewList(markupId, resourceModel.getObject());
×
100
                    }
101

102
                    @Override
103
                    protected boolean isContentReady() {
104
                        return resourceModel.getObject().isDataInitialized();
×
105
                    }
106

107
                    @Override
108
                    public Component getLoadingComponent(String id) {
109
                        return new Label(id, "<div class=\"row-section\"><div class=\"col-12\">" + ResultComponent.getWaitIconHtml() + "</div></div>").setEscapeModelStrings(false);
×
110
                    }
111

112
                });
113
            }
114
        } else {
115
            contentContainer.setVisible(false);
×
116
            if (activeTab == ResourceTabs.Tab.ABOUT) {
×
117
                add(new AboutResourcePanel("otherTab", resource));
×
118
            } else if (activeTab == ResourceTabs.Tab.EXPLORE) {
×
119
                add(new ExplorePanel("otherTab", resource.getId()));
×
120
            } else {
121
                add(new DownloadRdfLinks("otherTab", "resource", resource.getId()));
×
122
            }
123
        }
124
    }
×
125

126
    /**
127
     * Checks if auto-refresh is enabled for this page.
128
     *
129
     * @return true if auto-refresh is enabled, false otherwise
130
     */
131
    protected boolean hasAutoRefreshEnabled() {
132
        return true;
×
133
    }
134

135
    /**
136
     * {@inheritDoc}
137
     */
138
    @Override
139
    protected void onDetach() {
140
        resourceModel.detach();
×
141
        super.onDetach();
×
142
    }
×
143

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