Skip to content

Commit 80abcff

Browse files
authored
notification logs UI update. (#3642)
1 parent c2346f5 commit 80abcff

9 files changed

Lines changed: 288 additions & 164 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.roda.wui.client.browse.tabs;
2+
3+
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
4+
import com.google.gwt.user.client.ui.Widget;
5+
import org.roda.core.data.v2.notifications.Notification;
6+
7+
/**
8+
*
9+
* @author Eduardo Teixeira <eteixeira@keep.pt>
10+
*/
11+
public class BrowseNotificationsTabs extends Tabs {
12+
public void init(Notification notification) {
13+
createAndAddTab(SafeHtmlUtils.fromSafeConstant(messages.detailsTab()), new TabContentBuilder() {
14+
@Override
15+
public Widget buildTabWidget() {
16+
return new DetailsTab(notification);
17+
}
18+
});
19+
}
20+
}

roda-ui/roda-wui/src/main/java/org/roda/wui/client/browse/tabs/DetailsTab.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
import org.roda.core.data.v2.ip.IndexedFile;
1313
import org.roda.core.data.v2.ip.TransferredResource;
14+
import org.roda.core.data.v2.notifications.Notification;
1415
import org.roda.core.data.v2.log.LogEntry;
1516
import org.roda.wui.client.common.model.BrowseAIPResponse;
1617
import org.roda.wui.client.common.model.BrowseRepresentationResponse;
18+
import org.roda.wui.client.management.DetailsPanelNotification;
1719
import org.roda.wui.client.management.DetailsPanelLogEntry;
1820
import org.roda.wui.client.ingest.transfer.DetailsPanelTransferredResource;
1921
import org.roda.wui.client.planning.DetailsPanelAIP;
@@ -67,6 +69,12 @@ public DetailsTab(TransferredResource resource) {
6769
content.add(detailsPanel);
6870
}
6971

72+
public DetailsTab(Notification notification) {
73+
initWidget(uiBinder.createAndBindUi(this));
74+
DetailsPanelNotification detailsPanel = new DetailsPanelNotification(notification);
75+
content.add(detailsPanel);
76+
}
77+
7078
public DetailsTab(LogEntry logEntry) {
7179
initWidget(uiBinder.createAndBindUi(this));
7280
DetailsPanelLogEntry detailsPanel = new DetailsPanelLogEntry(logEntry);

roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/resources/main.gss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,18 @@ pre code {
714714
border-radius: 4px;
715715
}
716716

717+
.notification-body-content pre > code {
718+
overflow: visible;
719+
}
720+
721+
.notification-body-content pre code {
722+
max-height: none;
723+
}
724+
725+
.notification-body-content {
726+
overflow: visible;
727+
}
728+
717729
.error {
718730
color: #D20707;
719731
}

roda-ui/roda-wui/src/main/java/org/roda/wui/client/common/utils/JavascriptUtils.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,14 @@ public static native void runHighlighter() /*-{
4242
}-*/;
4343

4444
public static native void runHighlighter(JavaScriptObject parent) /*-{
45-
$wnd.jQuery(parent).find('pre code').each(function(i, block) {
45+
$wnd.jQuery(parent).find('pre code').each(function(i, block) {
46+
if ($wnd.hljs && $wnd.hljs.highlightElement) {
47+
$wnd.hljs.highlightElement(block);
48+
} else if ($wnd.hljs && $wnd.hljs.highlightBlock) {
4649
$wnd.hljs.highlightBlock(block);
47-
});
48-
}-*/;
50+
}
51+
});
52+
}-*/;
4953

5054
public static native void runHighlighterOn(JavaScriptObject parent) /*-{
5155
$wnd.jQuery(parent).each(function(i, block) {

roda-ui/roda-wui/src/main/java/org/roda/wui/client/main/BreadcrumbUtils.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,21 @@ public static List<BreadcrumbItem> getLogEntryBreadcrumbs(LogEntry logEntry) {
374374
return ret;
375375
}
376376

377+
public static List<BreadcrumbItem> getNotificationBreadcrumbs(Notification notification) {
378+
List<BreadcrumbItem> ret = new ArrayList<>();
379+
ret.add(new BreadcrumbItem(SafeHtmlUtils.fromSafeConstant(messages.notificationsTitle()),
380+
messages.notificationsTitle(), NotificationRegister.RESOLVER.getHistoryPath()));
381+
382+
if (notification != null) {
383+
List<String> path = new ArrayList<>(ShowNotification.RESOLVER.getHistoryPath());
384+
path.add(notification.getUUID());
385+
String label = StringUtils.isNotBlank(notification.getId()) ? notification.getId() : notification.getUUID();
386+
ret.add(new BreadcrumbItem(SafeHtmlUtils.fromString(label), label, path));
387+
}
388+
389+
return ret;
390+
}
391+
377392
public static List<BreadcrumbItem> getDipBreadcrumbs(IndexedDIP dip, DIPFile dipFile,
378393
List<DIPFile> dipFileAncestors) {
379394
List<BreadcrumbItem> ret = new ArrayList<>();
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package org.roda.wui.client.management;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import com.google.gwt.json.client.JSONParser;
8+
import com.google.gwt.user.client.ui.HTML;
9+
import org.roda.core.data.v2.notifications.Notification;
10+
import org.roda.wui.client.common.utils.HtmlSnippetUtils;
11+
import org.roda.wui.client.common.utils.JavascriptUtils;
12+
import org.roda.wui.common.client.tools.Humanize;
13+
import org.roda.wui.common.client.tools.StringUtils;
14+
15+
import com.google.gwt.core.client.GWT;
16+
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
17+
import com.google.gwt.uibinder.client.UiBinder;
18+
import com.google.gwt.uibinder.client.UiField;
19+
import com.google.gwt.user.client.ui.Composite;
20+
import com.google.gwt.user.client.ui.FlowPanel;
21+
import com.google.gwt.user.client.ui.InlineHTML;
22+
import com.google.gwt.user.client.ui.Label;
23+
import com.google.gwt.user.client.ui.Widget;
24+
25+
import config.i18n.client.ClientMessages;
26+
27+
/**
28+
*
29+
* @author Eduardo Teixeira <eteixeira@keep.pt>
30+
*/
31+
public class DetailsPanelNotification extends Composite {
32+
private static final ClientMessages messages = GWT.create(ClientMessages.class);
33+
private static final MyUiBinder uiBinder = GWT.create(DetailsPanelNotification.MyUiBinder.class);
34+
35+
@UiField
36+
FlowPanel details;
37+
38+
public DetailsPanelNotification(Notification resource) {
39+
initWidget(uiBinder.createAndBindUi(this));
40+
init(resource);
41+
}
42+
43+
public void init(Notification n) {
44+
addIfNotBlank(messages.notificationIdentifier(), n.getId());
45+
addIfNotBlank(messages.notificationSubject(), n.getSubject());
46+
47+
if (StringUtils.isNotBlank(n.getBody())) {
48+
details.add(buildBodyField(messages.notificationBody(), n.getBody()));
49+
}
50+
51+
if (n.getSentOn() != null) {
52+
details.add(buildField(messages.notificationSentOn(),
53+
new InlineHTML(SafeHtmlUtils.htmlEscape(Humanize.formatDateTime(n.getSentOn())))));
54+
}
55+
56+
addIfNotBlank(messages.notificationFromUser(), n.getFromUser());
57+
addIfNotBlank(messages.notificationIsAcknowledged(),
58+
messages.isAcknowledged(Boolean.toString(n.isAcknowledged()).toLowerCase()));
59+
60+
if (n.getState() != null) {
61+
details.add(buildField(messages.notificationState(),
62+
new InlineHTML(HtmlSnippetUtils.getNotificationStateHTML(n.getState()))));
63+
}
64+
65+
if (n.getAcknowledgedUsers() != null && !n.getAcknowledgedUsers().isEmpty()) {
66+
FlowPanel ack = new FlowPanel();
67+
for (Map.Entry<String, String> e : n.getAcknowledgedUsers().entrySet()) {
68+
ack.add(new InlineHTML(SafeHtmlUtils.htmlEscape(e.getKey() + " " + e.getValue())));
69+
}
70+
details.add(buildField(messages.notificationAcknowledgedUsers(), ack));
71+
}
72+
73+
List<String> remaining = new ArrayList<>();
74+
if (n.getRecipientUsers() != null) {
75+
remaining.addAll(n.getRecipientUsers());
76+
}
77+
78+
if (n.getAcknowledgedUsers() != null) {
79+
remaining.removeAll(n.getAcknowledgedUsers().keySet());
80+
}
81+
if (!remaining.isEmpty()) {
82+
FlowPanel notAck = new FlowPanel();
83+
for (String user : remaining) {
84+
notAck.add(new InlineHTML(SafeHtmlUtils.htmlEscape(user)));
85+
}
86+
details.add(buildField(messages.notificationNotAcknowledgedUsers(), notAck));
87+
}
88+
}
89+
90+
private void addIfNotBlank(String label, String value) {
91+
if (StringUtils.isNotBlank(value)) {
92+
details.add(buildField(label, new InlineHTML(SafeHtmlUtils.htmlEscape(value))));
93+
}
94+
}
95+
96+
private FlowPanel buildField(String label, Widget valueWidget) {
97+
FlowPanel fieldPanel = new FlowPanel();
98+
fieldPanel.setStyleName("field");
99+
100+
Label fieldLabel = new Label(label);
101+
fieldLabel.setStyleName("label");
102+
103+
FlowPanel fieldValuePanel = new FlowPanel();
104+
fieldValuePanel.setStyleName("value");
105+
fieldValuePanel.add(valueWidget);
106+
107+
fieldPanel.add(fieldLabel);
108+
fieldPanel.add(fieldValuePanel);
109+
110+
return fieldPanel;
111+
}
112+
113+
private FlowPanel buildBodyField(String label, String rawBody) {
114+
FlowPanel bodyPanel = new FlowPanel();
115+
bodyPanel.setStyleName("field");
116+
117+
Label fieldLabel = new Label(label);
118+
fieldLabel.setStyleName("label");
119+
120+
FlowPanel fieldValuePanel = new FlowPanel();
121+
fieldValuePanel.setStyleName("value");
122+
fieldValuePanel.addStyleName("code-pre");
123+
fieldValuePanel.addStyleName("notification-body-content");
124+
125+
fieldValuePanel.add(buildNotificationBody(rawBody));
126+
127+
bodyPanel.add(fieldLabel);
128+
bodyPanel.add(fieldValuePanel);
129+
130+
return bodyPanel;
131+
}
132+
133+
private Widget buildNotificationBody(String rawBody) {
134+
String body = rawBody == null ? "" : rawBody.trim();
135+
136+
if (body.isEmpty()) {
137+
return new InlineHTML("");
138+
}
139+
140+
if (isJson(body)) {
141+
return buildHighlightedCodeBlock(body, "json");
142+
}
143+
144+
if (isHtml(body)) {
145+
return buildHighlightedCodeBlock(body, "html");
146+
}
147+
148+
return new HTML("<pre>" + SafeHtmlUtils.htmlEscape(body) + "</pre>");
149+
}
150+
151+
private boolean isJson(String body) {
152+
try {
153+
JSONParser.parseStrict(body);
154+
return true;
155+
} catch (Exception e) {
156+
return false;
157+
}
158+
}
159+
160+
private boolean isHtml(String body) {
161+
String s = body == null ? "" : body.trim().toLowerCase();
162+
return s.contains("<html") || s.contains("<body") || s.contains("<div") || s.contains("<p") || s.contains("<h1")
163+
|| s.contains("<h2") || s.contains("<ul") || s.contains("<table") || s.contains("<a ") || s.contains("<style");
164+
}
165+
166+
private HTML buildHighlightedCodeBlock(String body, String language) {
167+
String escaped = SafeHtmlUtils.htmlEscape(body);
168+
HTML codeHtml = new HTML("<pre><code class=\"language-" + language + "\">" + escaped + "</code></pre>");
169+
codeHtml.addAttachHandler(event -> {
170+
if (event.isAttached()) {
171+
JavascriptUtils.runHighlighter(codeHtml.getElement());
172+
}
173+
});
174+
return codeHtml;
175+
}
176+
177+
interface MyUiBinder extends UiBinder<Widget, DetailsPanelNotification> {
178+
Widget createAndBindUi(DetailsPanelNotification detailsPanelNotification);
179+
}
180+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
3+
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
4+
>
5+
6+
<ui:with field='messages' type='config.i18n.client.ClientMessages'/>
7+
8+
<g:FlowPanel addStyleNames="descriptiveMetadataHTML">
9+
<g:FlowPanel ui:field="details" addStyleNames="descriptiveMetadata"/>
10+
11+
</g:FlowPanel>
12+
</ui:UiBinder>

0 commit comments

Comments
 (0)