diff --git a/src/main/java/com/knowledgepixels/nanodash/QueryResult.java b/src/main/java/com/knowledgepixels/nanodash/QueryResult.java index ec0624fa..7cd8fdba 100644 --- a/src/main/java/com/knowledgepixels/nanodash/QueryResult.java +++ b/src/main/java/com/knowledgepixels/nanodash/QueryResult.java @@ -1,7 +1,7 @@ package com.knowledgepixels.nanodash; import com.knowledgepixels.nanodash.component.ButtonList; -import com.knowledgepixels.nanodash.component.ViewDisplayMenu; +import com.knowledgepixels.nanodash.component.menu.ViewDisplayMenu; import com.knowledgepixels.nanodash.domain.AbstractResourceWithProfile; import com.knowledgepixels.nanodash.page.NanodashPage; import org.apache.wicket.behavior.AttributeAppender; diff --git a/src/main/java/com/knowledgepixels/nanodash/component/ExternalLinkWithActionsPanel.html b/src/main/java/com/knowledgepixels/nanodash/component/ExternalLinkWithActionsPanel.html new file mode 100644 index 00000000..5e112cbe --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/ExternalLinkWithActionsPanel.html @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/knowledgepixels/nanodash/component/ExternalLinkWithActionsPanel.java b/src/main/java/com/knowledgepixels/nanodash/component/ExternalLinkWithActionsPanel.java new file mode 100644 index 00000000..9de225ef --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/ExternalLinkWithActionsPanel.java @@ -0,0 +1,90 @@ +package com.knowledgepixels.nanodash.component; + +import com.knowledgepixels.nanodash.component.menu.ExploreDisplayMenu; +import com.knowledgepixels.nanodash.page.ExplorePage; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.image.Image; +import org.apache.wicket.markup.html.link.ExternalLink; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.request.resource.ContextRelativeResourceReference; +import org.eclipse.rdf4j.model.IRI; + +/** + * External link with Actions Panel that allows to copy the link and explore it through the Nanodash ExplorePage. + */ +public class ExternalLinkWithActionsPanel extends Panel { + + private final IModel urlModel; + private IModel labelModel; + private IRI sourceNanopub; + + public ExternalLinkWithActionsPanel(String id, IModel urlModel) { + super(id); + this.urlModel = urlModel; + } + + public ExternalLinkWithActionsPanel(String id, IModel urlModel, IModel labelModel) { + this(id, urlModel); + this.labelModel = labelModel; + } + + public ExternalLinkWithActionsPanel(String id, IModel urlModel, IModel labelModel, IRI sourceNanopub) { + this(id, urlModel, labelModel); + this.sourceNanopub = sourceNanopub; + } + + @Override + protected void onInitialize() { + super.onInitialize(); + + ExternalLink externalLink = new ExternalLink("externalLink", urlModel, urlModel); + add(externalLink); + + AjaxLink copyLinkButton = new AjaxLink<>("copyLinkButton") { + @Override + public void onClick(AjaxRequestTarget target) { + String url = urlModel.getObject(); + String escapedUrl = url.replace("'", "\\'"); + target.appendJavaScript( + "navigator.clipboard.writeText('" + escapedUrl + "')" + + ".then(function() { alert('Link copied to clipboard!'); })" + + ".catch(function(err) { console.error('Copy failed:', err); });" + ); + } + }; + copyLinkButton.add(new Image("copyIcon", new ContextRelativeResourceReference("images/copy-icon.svg", false))); + add(copyLinkButton); + + if (sourceNanopub != null) { + add(new Label("exploreButton", "").setVisible(false)); + add(new ExploreDisplayMenu("np", urlModel.getObject(), labelModel.getObject(), sourceNanopub)); + } else { + add(new Label("np", "").setVisible(false)); + if (labelModel != null) { + AjaxLink exploreButton = new AjaxLink<>("exploreButton") { + @Override + public void onClick(AjaxRequestTarget target) { + setResponsePage(ExplorePage.class, new PageParameters().set("id", urlModel.getObject()).set("label", labelModel.getObject())); + } + }; + add(exploreButton); + } else { + add(new Label("exploreButton", "").setVisible(false)); + } + } + } + + @Override + protected void onDetach() { + super.onDetach(); + urlModel.detach(); + if (labelModel != null) { + labelModel.detach(); + } + } + +} diff --git a/src/main/java/com/knowledgepixels/nanodash/component/NanopubItem.java b/src/main/java/com/knowledgepixels/nanodash/component/NanopubItem.java index 81142828..d8aff387 100644 --- a/src/main/java/com/knowledgepixels/nanodash/component/NanopubItem.java +++ b/src/main/java/com/knowledgepixels/nanodash/component/NanopubItem.java @@ -3,6 +3,7 @@ import com.knowledgepixels.nanodash.*; import com.knowledgepixels.nanodash.action.NanopubAction; import com.knowledgepixels.nanodash.action.RetractionAction; +import com.knowledgepixels.nanodash.component.menu.ActionMenu; import com.knowledgepixels.nanodash.domain.User; import com.knowledgepixels.nanodash.page.ListPage; import com.knowledgepixels.nanodash.page.UserPage; diff --git a/src/main/java/com/knowledgepixels/nanodash/component/QueryResultNanopubSet.java b/src/main/java/com/knowledgepixels/nanodash/component/QueryResultNanopubSet.java index 71d9b182..953495c0 100644 --- a/src/main/java/com/knowledgepixels/nanodash/component/QueryResultNanopubSet.java +++ b/src/main/java/com/knowledgepixels/nanodash/component/QueryResultNanopubSet.java @@ -3,6 +3,7 @@ import com.knowledgepixels.nanodash.NanodashSession; import com.knowledgepixels.nanodash.QueryResult; import com.knowledgepixels.nanodash.ViewDisplay; +import com.knowledgepixels.nanodash.component.menu.ViewDisplayMenu; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.behavior.AttributeAppender; diff --git a/src/main/java/com/knowledgepixels/nanodash/component/ViewDisplayMenu.html b/src/main/java/com/knowledgepixels/nanodash/component/ViewDisplayMenu.html deleted file mode 100644 index b9af25fa..00000000 --- a/src/main/java/com/knowledgepixels/nanodash/component/ViewDisplayMenu.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - -show query -edit view display -show nanopub - - - - - - - diff --git a/src/main/java/com/knowledgepixels/nanodash/component/ActionMenu.html b/src/main/java/com/knowledgepixels/nanodash/component/menu/ActionMenu.html similarity index 70% rename from src/main/java/com/knowledgepixels/nanodash/component/ActionMenu.html rename to src/main/java/com/knowledgepixels/nanodash/component/menu/ActionMenu.html index 793dd9b5..27a85fc1 100644 --- a/src/main/java/com/knowledgepixels/nanodash/component/ActionMenu.html +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/ActionMenu.html @@ -2,7 +2,7 @@ - + diff --git a/src/main/java/com/knowledgepixels/nanodash/component/ActionMenu.java b/src/main/java/com/knowledgepixels/nanodash/component/menu/ActionMenu.java similarity index 98% rename from src/main/java/com/knowledgepixels/nanodash/component/ActionMenu.java rename to src/main/java/com/knowledgepixels/nanodash/component/menu/ActionMenu.java index 63130a45..3e15fc9d 100644 --- a/src/main/java/com/knowledgepixels/nanodash/component/ActionMenu.java +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/ActionMenu.java @@ -1,4 +1,4 @@ -package com.knowledgepixels.nanodash.component; +package com.knowledgepixels.nanodash.component.menu; import com.knowledgepixels.nanodash.*; import com.knowledgepixels.nanodash.action.NanopubAction; diff --git a/src/main/java/com/knowledgepixels/nanodash/component/menu/BaseDisplayMenu.html b/src/main/java/com/knowledgepixels/nanodash/component/menu/BaseDisplayMenu.html new file mode 100644 index 00000000..d97c8726 --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/BaseDisplayMenu.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/main/java/com/knowledgepixels/nanodash/component/menu/BaseDisplayMenu.java b/src/main/java/com/knowledgepixels/nanodash/component/menu/BaseDisplayMenu.java new file mode 100644 index 00000000..0a96f441 --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/BaseDisplayMenu.java @@ -0,0 +1,32 @@ +package com.knowledgepixels.nanodash.component.menu; + +import org.apache.wicket.Component; +import org.apache.wicket.markup.html.panel.Panel; + +import java.util.ArrayList; +import java.util.List; + +public class BaseDisplayMenu extends Panel { + + public record Entry(String wicketId, Component component) { + } + + private final List entries = new ArrayList<>(); + + public BaseDisplayMenu(String id) { + super(id); + } + + protected void addEntry(String wicketId, Component component) { + entries.add(new Entry(wicketId, component)); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + for (Entry entry : entries) { + add(entry.component()); + } + } + +} diff --git a/src/main/java/com/knowledgepixels/nanodash/component/menu/ExploreDisplayMenu.html b/src/main/java/com/knowledgepixels/nanodash/component/menu/ExploreDisplayMenu.html new file mode 100644 index 00000000..0c9a1d9e --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/ExploreDisplayMenu.html @@ -0,0 +1,17 @@ + + + + + + + + + + explore + see declaration + + + + + diff --git a/src/main/java/com/knowledgepixels/nanodash/component/menu/ExploreDisplayMenu.java b/src/main/java/com/knowledgepixels/nanodash/component/menu/ExploreDisplayMenu.java new file mode 100644 index 00000000..5d880d79 --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/ExploreDisplayMenu.java @@ -0,0 +1,25 @@ +package com.knowledgepixels.nanodash.component.menu; + +import com.knowledgepixels.nanodash.page.ExplorePage; +import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.eclipse.rdf4j.model.IRI; + +public class ExploreDisplayMenu extends BaseDisplayMenu { + + /** + * Constructs a ExploreDisplayMenu. + * + * @param id the Wicket component ID + * @param exploreUri the URI of the resource to explore + * @param exploreLabel the label of the resource to be rendered in the explore page + * @param sourceUri the uri of the source nanopublication defining the resource + */ + public ExploreDisplayMenu(String id, String exploreUri, String exploreLabel, IRI sourceUri) { + super(id); + + addEntry("explore", new BookmarkablePageLink("explore", ExplorePage.class, new PageParameters().set("id", exploreUri).set("label", exploreLabel))); + addEntry("viewDeclaration", new BookmarkablePageLink("viewDeclaration", ExplorePage.class, new PageParameters().set("id", sourceUri))); + } + +} diff --git a/src/main/java/com/knowledgepixels/nanodash/component/menu/ViewDisplayMenu.html b/src/main/java/com/knowledgepixels/nanodash/component/menu/ViewDisplayMenu.html new file mode 100644 index 00000000..362617cb --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/ViewDisplayMenu.html @@ -0,0 +1,18 @@ + + + + + + + + + + show query + edit view display + show nanopub + + + + + diff --git a/src/main/java/com/knowledgepixels/nanodash/component/ViewDisplayMenu.java b/src/main/java/com/knowledgepixels/nanodash/component/menu/ViewDisplayMenu.java similarity index 91% rename from src/main/java/com/knowledgepixels/nanodash/component/ViewDisplayMenu.java rename to src/main/java/com/knowledgepixels/nanodash/component/menu/ViewDisplayMenu.java index 094d9f59..1cc15f0a 100644 --- a/src/main/java/com/knowledgepixels/nanodash/component/ViewDisplayMenu.java +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/ViewDisplayMenu.java @@ -1,4 +1,4 @@ -package com.knowledgepixels.nanodash.component; +package com.knowledgepixels.nanodash.component.menu; import com.knowledgepixels.nanodash.NanodashSession; import com.knowledgepixels.nanodash.NanopubElement; @@ -13,7 +13,6 @@ import com.knowledgepixels.nanodash.template.TemplateData; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.link.ExternalLink; -import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.eclipse.rdf4j.model.IRI; import org.nanopub.extra.services.QueryRef; @@ -22,7 +21,7 @@ * A dropdown menu panel for view displays, replacing the "^" source link. * Provides options to show the query, adjust the view display, and see its declaration. */ -public class ViewDisplayMenu extends Panel { +public class ViewDisplayMenu extends BaseDisplayMenu { /** * Constructs a ViewDisplayMenu. @@ -39,7 +38,7 @@ public ViewDisplayMenu(String id, ViewDisplay viewDisplay, QueryRef queryRef, Ab for (var entry : queryRef.getParams().entries()) { showQueryParams.add("queryparam_" + entry.getKey(), entry.getValue()); } - add(new BookmarkablePageLink("showQuery", QueryPage.class, showQueryParams)); + addEntry("showQuery", new BookmarkablePageLink("showQuery", QueryPage.class, showQueryParams)); IRI nanopubId = viewDisplay.getNanopubId(); @@ -73,9 +72,9 @@ public ViewDisplayMenu(String id, ViewDisplay viewDisplay, QueryRef queryRef, Ab + "&template-version=latest"; ExternalLink adjustLink = new ExternalLink("adjust", adjustUrl, "edit view display"); adjustLink.setVisible(showAdjust); - add(adjustLink); + addEntry("adjust", adjustLink); - add(new BookmarkablePageLink("viewDeclaration", ExplorePage.class, + addEntry("viewDeclaration", new BookmarkablePageLink("viewDeclaration", ExplorePage.class, new PageParameters().set("id", nanopubId))); } diff --git a/src/main/java/com/knowledgepixels/nanodash/component/menu/package-info.java b/src/main/java/com/knowledgepixels/nanodash/component/menu/package-info.java new file mode 100644 index 00000000..f37f0335 --- /dev/null +++ b/src/main/java/com/knowledgepixels/nanodash/component/menu/package-info.java @@ -0,0 +1,4 @@ +/** + * This package contains the menu components. + */ +package com.knowledgepixels.nanodash.component.menu; \ No newline at end of file diff --git a/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.html b/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.html index 395f4250..97a4ad6d 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.html +++ b/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.html @@ -26,7 +26,7 @@

-

Full identifier:

+

back to context diff --git a/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.java b/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.java index 242344a5..98b4d0d6 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.java +++ b/src/main/java/com/knowledgepixels/nanodash/page/ExplorePage.java @@ -261,7 +261,10 @@ private void initPage() { } add(new Label("pagetitle", shortName + " (explore) | nanodash")); add(new Label("termname", shortName)); - add(new ExternalLink("urilink", ref, ref)); + + //add(new ExternalLink("urilink", ref, ref)); + add(new ExternalLinkWithActionsPanel("urilink", Model.of(ref))); + if (publishedNanopub != null) { add(new Label("statusline", "

Status

Successfully published.

").setEscapeModelStrings(false)); } else if (isNanopubId && SignatureUtils.seemsToHaveSignature(np)) { diff --git a/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.html b/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.html index 50b532b3..d31de627 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.html +++ b/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.html @@ -19,7 +19,7 @@

Resource ABC

-

https://... [np]

+

Namespace:

diff --git a/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.java b/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.java index 83294a19..9c07c779 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.java +++ b/src/main/java/com/knowledgepixels/nanodash/page/MaintainedResourcePage.java @@ -59,8 +59,7 @@ public MaintainedResourcePage(final PageParameters parameters) { add(new Label("pagetitle", resource.getLabel() + " (resource) | nanodash")); add(new Label("resourcename", resource.getLabel())); - add(new BookmarkablePageLink("id", ExplorePage.class, parameters.set("label", resource.getLabel())).setBody(Model.of(resource.getId()))); - add(new SourceNanopub("np", Values.iri(resource.getNanopubId()))); + add(new ExternalLinkWithActionsPanel("id", Model.of(resource.getId()), Model.of(resource.getLabel()), Values.iri(resource.getNanopubId()))); String namespaceUri = resource.getNamespace() == null ? "" : resource.getNamespace(); add(new BookmarkablePageLink("namespace", ExplorePage.class, new PageParameters().set("id", namespaceUri)).setBody(Model.of(namespaceUri))); diff --git a/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.html b/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.html index 75f04bfd..64a098e3 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.html +++ b/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.html @@ -18,7 +18,7 @@

ABC

-

https://... [np]

+

Description...

diff --git a/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.java b/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.java index 8033f7fd..9429cf1f 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.java +++ b/src/main/java/com/knowledgepixels/nanodash/page/ResourcePartPage.java @@ -143,8 +143,7 @@ public ResourcePartPage(final PageParameters parameters) { add(new Label("pagetitle", label + " (resource part) | nanodash")); add(new Label("name", label)); - add(new BookmarkablePageLink("id", ExplorePage.class, parameters.set("label", label)).setBody(Model.of(id))); - add(new SourceNanopub("np", nanopubId == null ? Values.iri(id) : Values.iri(nanopubId))); + add(new ExternalLinkWithActionsPanel("id", Model.of(id), Model.of(label), nanopubId == null ? Values.iri(id) : Values.iri(nanopubId))); // TODO Improve this code, e.g. make Space a subclass of MaintainedResource or otherwise refactor: // we now use the ProfileResource abstraction, but the code still has to be imprved diff --git a/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.html b/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.html index 6cc5ea3c..f142cad0 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.html +++ b/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.html @@ -20,7 +20,7 @@

Space ABC

Space type

-

https://...[np]

+

...
diff --git a/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.java b/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.java index fd3bc84b..3229298e 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.java +++ b/src/main/java/com/knowledgepixels/nanodash/page/SpacePage.java @@ -87,8 +87,7 @@ public SpacePage(final PageParameters parameters) { add(new Label("pagetitle", space.getLabel() + " (space) | nanodash")); add(new Label("spacename", space.getLabel())); add(new Label("spacetype", space.getTypeLabel())); - add(new BookmarkablePageLink("id", ExplorePage.class, parameters.set("label", space.getLabel())).setBody(Model.of(space.getId()))); - add(new SourceNanopub("np", np.getUri())); + add(new ExternalLinkWithActionsPanel("id", Model.of(space.getId()), Model.of(space.getLabel()), np.getUri())); add(new ItemListPanel( "altids", diff --git a/src/main/java/com/knowledgepixels/nanodash/page/UserPage.html b/src/main/java/com/knowledgepixels/nanodash/page/UserPage.html index 5b216516..3508a162 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/UserPage.html +++ b/src/main/java/com/knowledgepixels/nanodash/page/UserPage.html @@ -17,7 +17,7 @@

User Name

-

https://orcid.org/xxxx-xxxx-xxxx-xxxx

+

See Your Profile Details Show Full Channel diff --git a/src/main/java/com/knowledgepixels/nanodash/page/UserPage.java b/src/main/java/com/knowledgepixels/nanodash/page/UserPage.java index 4295b3f6..b82aaf71 100644 --- a/src/main/java/com/knowledgepixels/nanodash/page/UserPage.java +++ b/src/main/java/com/knowledgepixels/nanodash/page/UserPage.java @@ -81,8 +81,7 @@ public UserPage(final PageParameters parameters) { add(userIcon); add(new Label("username", displayName)); - add(new BookmarkablePageLink("fullid", ExplorePage.class, parameters.set("label", displayName)).setBody(Model.of(userIriString))); - + add(new ExternalLinkWithActionsPanel("fullid", Model.of(userIriString), Model.of(displayName))); add(new BookmarkablePageLink("showprofile", ProfilePage.class).setVisible(userIri.equals(NanodashSession.get().getUserIri()))); add(new BookmarkablePageLink("showchannel", ListPage.class, new PageParameters().add("userid", userIriString))); diff --git a/src/main/webapp/images/copy-icon.svg b/src/main/webapp/images/copy-icon.svg new file mode 100644 index 00000000..cb543a71 --- /dev/null +++ b/src/main/webapp/images/copy-icon.svg @@ -0,0 +1,7 @@ + + + + diff --git a/src/main/webapp/style.css b/src/main/webapp/style.css index fa8ca3a3..49274602 100644 --- a/src/main/webapp/style.css +++ b/src/main/webapp/style.css @@ -2208,4 +2208,38 @@ a.source:hover { .mode-advanced .mode-toggle-arrow { transform: scale(1, -1); +} + +.link-actions-panel { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: sans-serif; +} + +.link-actions-panel > a:first-child { + margin-right: 8px; +} + +.link-actions-panel > a:not(:first-child) { + align-self: stretch; + display: inline-flex; + align-items: center; +} + +.copy-link-btn { + display: inline-flex; + align-items: center; + justify-content: center; + background: none; + border-radius: 4px; + padding: 4px; + cursor: pointer; + color: #555; + transition: background 0.15s, color 0.15s; +} + +.copy-link-btn:hover { + background: #f0f0f0; + color: #1a73e8; } \ No newline at end of file