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

3
import com.knowledgepixels.nanodash.component.menu.BaseDisplayMenu;
4
import org.apache.wicket.ajax.AjaxRequestTarget;
5
import org.apache.wicket.ajax.markup.html.AjaxLink;
6
import org.apache.wicket.markup.html.basic.Label;
7
import org.apache.wicket.markup.html.image.Image;
8
import org.apache.wicket.markup.html.link.ExternalLink;
9
import org.apache.wicket.markup.html.panel.Panel;
10
import org.apache.wicket.model.IModel;
11
import org.apache.wicket.request.resource.ContextRelativeResourceReference;
12
import org.eclipse.rdf4j.model.IRI;
13

14
/**
15
 * External link with Actions Panel that allows to copy the link and explore it through the Nanodash ExplorePage.
16
 */
17
public class ExternalLinkWithActionsPanel extends Panel {
18

19
    private final IModel<String> urlModel;
20
    private IModel<String> labelModel;
21
    private IRI sourceNanopub;
22
    private BaseDisplayMenu customMenu;
23

24
    public ExternalLinkWithActionsPanel(String id, IModel<String> urlModel) {
25
        super(id);
×
26
        this.urlModel = urlModel;
×
27
    }
×
28

29
    public ExternalLinkWithActionsPanel(String id, IModel<String> urlModel, IModel<String> labelModel) {
30
        this(id, urlModel);
×
31
        this.labelModel = labelModel;
×
32
    }
×
33

34
    public ExternalLinkWithActionsPanel(String id, IModel<String> urlModel, IModel<String> labelModel, IRI sourceNanopub) {
35
        this(id, urlModel, labelModel);
×
36
        this.sourceNanopub = sourceNanopub;
×
37
    }
×
38

39
    public ExternalLinkWithActionsPanel(String id, IModel<String> urlModel, IModel<String> labelModel, BaseDisplayMenu customMenu) {
40
        this(id, urlModel, labelModel);
×
41
        this.customMenu = customMenu;
×
42
    }
×
43

44
    @Override
45
    protected void onInitialize() {
46
        super.onInitialize();
×
47

48
        ExternalLink externalLink = new ExternalLink("externalLink", urlModel, urlModel);
×
49
        add(externalLink);
×
50

51
        AjaxLink<Void> copyLinkButton = new AjaxLink<>("copyLinkButton") {
×
52
            @Override
53
            public void onClick(AjaxRequestTarget target) {
54
                String url = urlModel.getObject();
×
55
                String escapedUrl = url.replace("'", "\\'");
×
56
                target.appendJavaScript(
×
57
                        "navigator.clipboard.writeText('" + escapedUrl + "')" +
58
                        ".then(function() { alert('Link copied to clipboard!'); })" +
59
                        ".catch(function(err) { console.error('Copy failed:', err); });"
60
                );
61
            }
×
62
        };
63
        copyLinkButton.add(new Image("copyIcon", new ContextRelativeResourceReference("images/copy-icon.svg", false)));
×
64
        add(copyLinkButton);
×
65

66
        // The "explore" action is now reachable via the resource's Explore tab,
67
        // so this panel no longer shows an explore button or an explore menu.
68
        // A custom menu (e.g. the space admin actions) is still shown when given.
69
        add(new Label("exploreButton", "").setVisible(false));
×
70
        if (customMenu != null) {
×
71
            add(customMenu);
×
72
        } else {
73
            add(new Label("np", "").setVisible(false));
×
74
        }
75
    }
×
76

77
    @Override
78
    protected void onDetach() {
79
        super.onDetach();
×
80
        urlModel.detach();
×
81
        if (labelModel != null) {
×
82
            labelModel.detach();
×
83
        }
84
    }
×
85

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