diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseNotificationsTabs.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseNotificationsTabs.java new file mode 100644 index 0000000000..a9c9a172a7 --- /dev/null +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/BrowseNotificationsTabs.java @@ -0,0 +1,20 @@ +package org.roda.wui.client.browse.tabs; + +import com.google.gwt.safehtml.shared.SafeHtmlUtils; +import com.google.gwt.user.client.ui.Widget; +import org.roda.core.data.v2.notifications.Notification; + +/** + * + * @author Eduardo Teixeira + */ +public class BrowseNotificationsTabs extends Tabs { + public void init(Notification notification) { + createAndAddTab(SafeHtmlUtils.fromSafeConstant(messages.detailsTab()), new TabContentBuilder() { + @Override + public Widget buildTabWidget() { + return new DetailsTab(notification); + } + }); + } +} diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/DetailsTab.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/DetailsTab.java index ac18d8a148..c6f11dcb8b 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/DetailsTab.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/DetailsTab.java @@ -11,9 +11,11 @@ import org.roda.core.data.v2.ip.IndexedFile; import org.roda.core.data.v2.ip.TransferredResource; +import org.roda.core.data.v2.notifications.Notification; import org.roda.core.data.v2.log.LogEntry; import org.roda.wui.client.common.model.BrowseAIPResponse; import org.roda.wui.client.common.model.BrowseRepresentationResponse; +import org.roda.wui.client.management.DetailsPanelNotification; import org.roda.wui.client.management.DetailsPanelLogEntry; import org.roda.wui.client.ingest.transfer.DetailsPanelTransferredResource; import org.roda.wui.client.planning.DetailsPanelAIP; @@ -67,6 +69,12 @@ public DetailsTab(TransferredResource resource) { content.add(detailsPanel); } + public DetailsTab(Notification notification) { + initWidget(uiBinder.createAndBindUi(this)); + DetailsPanelNotification detailsPanel = new DetailsPanelNotification(notification); + content.add(detailsPanel); + } + public DetailsTab(LogEntry logEntry) { initWidget(uiBinder.createAndBindUi(this)); DetailsPanelLogEntry detailsPanel = new DetailsPanelLogEntry(logEntry); diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/resources/main.gss b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/resources/main.gss index 2b9bf9f549..5597ef3d8f 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/resources/main.gss +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/resources/main.gss @@ -714,6 +714,18 @@ pre code { border-radius: 4px; } +.notification-body-content pre > code { + overflow: visible; +} + +.notification-body-content pre code { + max-height: none; +} + +.notification-body-content { + overflow: visible; +} + .error { color: #D20707; } diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/utils/JavascriptUtils.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/utils/JavascriptUtils.java index 80438d1709..095c1c8486 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/utils/JavascriptUtils.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/utils/JavascriptUtils.java @@ -42,10 +42,14 @@ public static native void runHighlighter() /*-{ }-*/; public static native void runHighlighter(JavaScriptObject parent) /*-{ - $wnd.jQuery(parent).find('pre code').each(function(i, block) { + $wnd.jQuery(parent).find('pre code').each(function(i, block) { + if ($wnd.hljs && $wnd.hljs.highlightElement) { + $wnd.hljs.highlightElement(block); + } else if ($wnd.hljs && $wnd.hljs.highlightBlock) { $wnd.hljs.highlightBlock(block); - }); - }-*/; + } + }); +}-*/; public static native void runHighlighterOn(JavaScriptObject parent) /*-{ $wnd.jQuery(parent).each(function(i, block) { diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/main/BreadcrumbUtils.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/main/BreadcrumbUtils.java index 6a9cf19647..f70a2386c4 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/main/BreadcrumbUtils.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/main/BreadcrumbUtils.java @@ -374,6 +374,21 @@ public static List getLogEntryBreadcrumbs(LogEntry logEntry) { return ret; } + public static List getNotificationBreadcrumbs(Notification notification) { + List ret = new ArrayList<>(); + ret.add(new BreadcrumbItem(SafeHtmlUtils.fromSafeConstant(messages.notificationsTitle()), + messages.notificationsTitle(), NotificationRegister.RESOLVER.getHistoryPath())); + + if (notification != null) { + List path = new ArrayList<>(ShowNotification.RESOLVER.getHistoryPath()); + path.add(notification.getUUID()); + String label = StringUtils.isNotBlank(notification.getId()) ? notification.getId() : notification.getUUID(); + ret.add(new BreadcrumbItem(SafeHtmlUtils.fromString(label), label, path)); + } + + return ret; + } + public static List getDipBreadcrumbs(IndexedDIP dip, DIPFile dipFile, List dipFileAncestors) { List ret = new ArrayList<>(); diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/DetailsPanelNotification.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/DetailsPanelNotification.java new file mode 100644 index 0000000000..9ad6300aa9 --- /dev/null +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/DetailsPanelNotification.java @@ -0,0 +1,180 @@ +package org.roda.wui.client.management; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.google.gwt.json.client.JSONParser; +import com.google.gwt.user.client.ui.HTML; +import org.roda.core.data.v2.notifications.Notification; +import org.roda.wui.client.common.utils.HtmlSnippetUtils; +import org.roda.wui.client.common.utils.JavascriptUtils; +import org.roda.wui.common.client.tools.Humanize; +import org.roda.wui.common.client.tools.StringUtils; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.safehtml.shared.SafeHtmlUtils; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.InlineHTML; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Widget; + +import config.i18n.client.ClientMessages; + +/** + * + * @author Eduardo Teixeira + */ +public class DetailsPanelNotification extends Composite { + private static final ClientMessages messages = GWT.create(ClientMessages.class); + private static final MyUiBinder uiBinder = GWT.create(DetailsPanelNotification.MyUiBinder.class); + + @UiField + FlowPanel details; + + public DetailsPanelNotification(Notification resource) { + initWidget(uiBinder.createAndBindUi(this)); + init(resource); + } + + public void init(Notification n) { + addIfNotBlank(messages.notificationIdentifier(), n.getId()); + addIfNotBlank(messages.notificationSubject(), n.getSubject()); + + if (StringUtils.isNotBlank(n.getBody())) { + details.add(buildBodyField(messages.notificationBody(), n.getBody())); + } + + if (n.getSentOn() != null) { + details.add(buildField(messages.notificationSentOn(), + new InlineHTML(SafeHtmlUtils.htmlEscape(Humanize.formatDateTime(n.getSentOn()))))); + } + + addIfNotBlank(messages.notificationFromUser(), n.getFromUser()); + addIfNotBlank(messages.notificationIsAcknowledged(), + messages.isAcknowledged(Boolean.toString(n.isAcknowledged()).toLowerCase())); + + if (n.getState() != null) { + details.add(buildField(messages.notificationState(), + new InlineHTML(HtmlSnippetUtils.getNotificationStateHTML(n.getState())))); + } + + if (n.getAcknowledgedUsers() != null && !n.getAcknowledgedUsers().isEmpty()) { + FlowPanel ack = new FlowPanel(); + for (Map.Entry e : n.getAcknowledgedUsers().entrySet()) { + ack.add(new InlineHTML(SafeHtmlUtils.htmlEscape(e.getKey() + " " + e.getValue()))); + } + details.add(buildField(messages.notificationAcknowledgedUsers(), ack)); + } + + List remaining = new ArrayList<>(); + if (n.getRecipientUsers() != null) { + remaining.addAll(n.getRecipientUsers()); + } + + if (n.getAcknowledgedUsers() != null) { + remaining.removeAll(n.getAcknowledgedUsers().keySet()); + } + if (!remaining.isEmpty()) { + FlowPanel notAck = new FlowPanel(); + for (String user : remaining) { + notAck.add(new InlineHTML(SafeHtmlUtils.htmlEscape(user))); + } + details.add(buildField(messages.notificationNotAcknowledgedUsers(), notAck)); + } + } + + private void addIfNotBlank(String label, String value) { + if (StringUtils.isNotBlank(value)) { + details.add(buildField(label, new InlineHTML(SafeHtmlUtils.htmlEscape(value)))); + } + } + + private FlowPanel buildField(String label, Widget valueWidget) { + FlowPanel fieldPanel = new FlowPanel(); + fieldPanel.setStyleName("field"); + + Label fieldLabel = new Label(label); + fieldLabel.setStyleName("label"); + + FlowPanel fieldValuePanel = new FlowPanel(); + fieldValuePanel.setStyleName("value"); + fieldValuePanel.add(valueWidget); + + fieldPanel.add(fieldLabel); + fieldPanel.add(fieldValuePanel); + + return fieldPanel; + } + + private FlowPanel buildBodyField(String label, String rawBody) { + FlowPanel bodyPanel = new FlowPanel(); + bodyPanel.setStyleName("field"); + + Label fieldLabel = new Label(label); + fieldLabel.setStyleName("label"); + + FlowPanel fieldValuePanel = new FlowPanel(); + fieldValuePanel.setStyleName("value"); + fieldValuePanel.addStyleName("code-pre"); + fieldValuePanel.addStyleName("notification-body-content"); + + fieldValuePanel.add(buildNotificationBody(rawBody)); + + bodyPanel.add(fieldLabel); + bodyPanel.add(fieldValuePanel); + + return bodyPanel; + } + + private Widget buildNotificationBody(String rawBody) { + String body = rawBody == null ? "" : rawBody.trim(); + + if (body.isEmpty()) { + return new InlineHTML(""); + } + + if (isJson(body)) { + return buildHighlightedCodeBlock(body, "json"); + } + + if (isHtml(body)) { + return buildHighlightedCodeBlock(body, "html"); + } + + return new HTML("
" + SafeHtmlUtils.htmlEscape(body) + "
"); + } + + private boolean isJson(String body) { + try { + JSONParser.parseStrict(body); + return true; + } catch (Exception e) { + return false; + } + } + + private boolean isHtml(String body) { + String s = body == null ? "" : body.trim().toLowerCase(); + return s.contains("" + escaped + ""); + codeHtml.addAttachHandler(event -> { + if (event.isAttached()) { + JavascriptUtils.runHighlighter(codeHtml.getElement()); + } + }); + return codeHtml; + } + + interface MyUiBinder extends UiBinder { + Widget createAndBindUi(DetailsPanelNotification detailsPanelNotification); + } +} diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/DetailsPanelNotification.ui.xml b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/DetailsPanelNotification.ui.xml new file mode 100644 index 0000000000..3f340b0194 --- /dev/null +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/DetailsPanelNotification.ui.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.java b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.java index 12a9679b3d..c53249a08e 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.java +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.java @@ -10,31 +10,29 @@ */ package org.roda.wui.client.management; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.roda.core.data.common.RodaConstants; import org.roda.core.data.v2.notifications.Notification; +import org.roda.wui.client.browse.tabs.BrowseNotificationsTabs; +import org.roda.wui.client.common.ActionsToolbar; +import org.roda.wui.client.common.NavigationToolbar; +import org.roda.wui.client.common.TitlePanel; import org.roda.wui.client.common.UserLogin; -import org.roda.wui.client.common.utils.HtmlSnippetUtils; +import org.roda.wui.client.main.BreadcrumbUtils; import org.roda.wui.client.services.Services; import org.roda.wui.common.client.HistoryResolver; import org.roda.wui.common.client.tools.HistoryUtils; -import org.roda.wui.common.client.tools.Humanize; import org.roda.wui.common.client.tools.ListUtils; +import org.roda.wui.common.client.tools.StringUtils; import com.google.gwt.core.client.GWT; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; -import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.Widget; import config.i18n.client.ClientMessages; @@ -96,89 +94,30 @@ interface MyUiBinder extends UiBinder { RodaConstants.NOTIFICATION_ACKNOWLEDGED_USERS, RodaConstants.NOTIFICATION_STATE); @UiField - Label notificationId; - + TitlePanel title; @UiField - Label notificationSubject; - + ActionsToolbar actionsToolbar; @UiField - HTML notificationBody; - + NavigationToolbar navigationToolbar; @UiField - Label notificationSentOn; - + FocusPanel keyboardFocus; @UiField - Label notificationFromUser; + BrowseNotificationsTabs browseTab; - @UiField - Label notificationIsAcknowledged; - - @UiField - Label acknowledgedUsersKey; - - @UiField - HTML acknowledgedUsersValue; - - @UiField - Label stateLabel; - - @UiField - HTML stateValue; - - @UiField - Label notAcknowledgedUsersKey; - - @UiField - HTML notAcknowledgedUsersValue; - - @UiField - Button buttonCancel; - - /** - * Create a new panel to view a notification - * - */ public ShowNotification(Notification notification) { initWidget(uiBinder.createAndBindUi(this)); + navigationToolbar.withoutButtons().build(); + navigationToolbar.updateBreadcrumbPath(BreadcrumbUtils.getNotificationBreadcrumbs(notification)); - notificationId.setText(notification.getId()); - notificationSubject.setText(notification.getSubject()); - notificationBody.setHTML(notification.getBody()); - notificationSentOn.setText(Humanize.formatDateTime(notification.getSentOn())); - notificationFromUser.setText(notification.getFromUser()); - notificationIsAcknowledged - .setText(messages.isAcknowledged(Boolean.toString(notification.isAcknowledged()).toLowerCase())); - acknowledgedUsersKey.setVisible(false); - notAcknowledgedUsersKey.setVisible(false); - - List recipientUsers = new ArrayList<>(notification.getRecipientUsers()); - - for (String user : notification.getAcknowledgedUsers().keySet()) { - String ackDate = notification.getAcknowledgedUsers().get(user); - acknowledgedUsersKey.setVisible(true); - acknowledgedUsersValue.setHTML(SafeHtmlUtils.fromSafeConstant( - acknowledgedUsersValue.getHTML() + "

" + user + " " + ackDate + "

")); - recipientUsers.remove(user); - } - - for (String user : recipientUsers) { - notAcknowledgedUsersKey.setVisible(true); - notAcknowledgedUsersValue - .setHTML(SafeHtmlUtils.fromSafeConstant(notAcknowledgedUsersValue.getHTML() + "

" + user + "

")); - } + actionsToolbar.setLabel(messages.notificationTitle()); + actionsToolbar.setTagsVisible(false); - stateValue.setHTML(HtmlSnippetUtils.getNotificationStateHTML(notification.getState())); - stateLabel.setVisible(notification.getState() != null); - stateValue.setVisible(notification.getState() != null); - } + title.setText(StringUtils.isNotBlank(notification.getSubject()) ? notification.getSubject() : notification.getId()); - @UiHandler("buttonCancel") - void handleButtonCancel(ClickEvent e) { - cancel(); - } + browseTab.init(notification); - private void cancel() { - HistoryUtils.newHistory(NotificationRegister.RESOLVER); + keyboardFocus.setFocus(true); + keyboardFocus.addStyleName("browse browse-file browse_main_panel"); } } diff --git a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.ui.xml b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.ui.xml index 301e8dfab4..04157e14d6 100644 --- a/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.ui.xml +++ b/roda-ui/roda-wui/src/main/java/org/roda/wui/client/management/ShowNotification.ui.xml @@ -1,89 +1,23 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - + + \ No newline at end of file