Skip to content

Commit 7c7a768

Browse files
committed
notification logs UI update.
1 parent 1cd1330 commit 7c7a768

File tree

9 files changed

+292
-164
lines changed

9 files changed

+292
-164
lines changed
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,8 +11,10 @@
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.wui.client.common.model.BrowseAIPResponse;
1516
import org.roda.wui.client.common.model.BrowseRepresentationResponse;
17+
import org.roda.wui.client.management.DetailsPanelNotification;
1618
import org.roda.wui.client.ingest.transfer.DetailsPanelTransferredResource;
1719
import org.roda.wui.client.planning.DetailsPanelAIP;
1820
import org.roda.wui.client.planning.DetailsPanelFile;
@@ -65,6 +67,12 @@ public DetailsTab(TransferredResource resource) {
6567
content.add(detailsPanel);
6668
}
6769

70+
public DetailsTab(Notification notification) {
71+
initWidget(uiBinder.createAndBindUi(this));
72+
DetailsPanelNotification detailsPanel = new DetailsPanelNotification(notification);
73+
content.add(detailsPanel);
74+
}
75+
6876
interface MyUiBinder extends UiBinder<Widget, DetailsTab> {
6977
}
7078
}

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
@@ -709,6 +709,18 @@ pre code {
709709
border-radius: 4px;
710710
}
711711

712+
.notification-body-content pre > code {
713+
overflow: visible;
714+
}
715+
716+
.notification-body-content pre code {
717+
max-height: none;
718+
}
719+
720+
.notification-body-content {
721+
overflow: visible;
722+
}
723+
712724
.error {
713725
color: #D20707;
714726
}

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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
import org.roda.core.data.v2.ip.IndexedFile;
2020
import org.roda.core.data.v2.ip.IndexedRepresentation;
2121
import org.roda.core.data.v2.ip.TransferredResource;
22+
import org.roda.core.data.v2.notifications.Notification;
2223
import org.roda.wui.client.browse.BrowseTop;
2324
import org.roda.wui.client.browse.PreservationEvents;
2425
import org.roda.wui.client.disposal.DisposalDestroyedRecords;
2526
import org.roda.wui.client.ingest.appraisal.IngestAppraisal;
2627
import org.roda.wui.client.ingest.transfer.IngestTransfer;
28+
import org.roda.wui.client.management.NotificationRegister;
29+
import org.roda.wui.client.management.ShowNotification;
2730
import org.roda.wui.common.client.tools.DescriptionLevelUtils;
2831
import org.roda.wui.common.client.tools.HistoryUtils;
2932
import org.roda.wui.common.client.tools.ListUtils;
33+
import org.roda.wui.common.client.tools.StringUtils;
3034
import org.roda.wui.common.client.widgets.Toast;
3135

3236
import com.google.gwt.core.client.GWT;
@@ -352,6 +356,21 @@ public static List<BreadcrumbItem> getTransferredResourceBreadcrumbs(Transferred
352356
return ret;
353357
}
354358

359+
public static List<BreadcrumbItem> getNotificationBreadcrumbs(Notification notification) {
360+
List<BreadcrumbItem> ret = new ArrayList<>();
361+
ret.add(new BreadcrumbItem(SafeHtmlUtils.fromSafeConstant(messages.notificationsTitle()),
362+
messages.notificationsTitle(), NotificationRegister.RESOLVER.getHistoryPath()));
363+
364+
if (notification != null) {
365+
List<String> path = new ArrayList<>(ShowNotification.RESOLVER.getHistoryPath());
366+
path.add(notification.getUUID());
367+
String label = StringUtils.isNotBlank(notification.getId()) ? notification.getId() : notification.getUUID();
368+
ret.add(new BreadcrumbItem(SafeHtmlUtils.fromString(label), label, path));
369+
}
370+
371+
return ret;
372+
}
373+
355374
public static List<BreadcrumbItem> getDipBreadcrumbs(IndexedDIP dip, DIPFile dipFile,
356375
List<DIPFile> dipFileAncestors) {
357376
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)