From 513fe451913ba00bc6083927d947704ebc925f5d Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Sun, 9 May 2021 22:06:20 +0200
Subject: [PATCH] allow multiple notifications at once

---
 .../advices/NotificationAdvice.java           |  8 +++--
 .../budgetmaster/utils/WebRequestUtils.java   | 33 ++++++++++++------
 src/main/resources/static/js/main.js          |  2 +-
 .../resources/templates/helpers/header.ftl    | 34 ++++++++++---------
 4 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/src/main/java/de/deadlocker8/budgetmaster/advices/NotificationAdvice.java b/src/main/java/de/deadlocker8/budgetmaster/advices/NotificationAdvice.java
index b0fd6172b..2eca37806 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/advices/NotificationAdvice.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/advices/NotificationAdvice.java
@@ -6,12 +6,14 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.context.request.WebRequest;
 
+import java.util.List;
+
 @ControllerAdvice
 public class NotificationAdvice
 {
-	@ModelAttribute("notification")
-	public Notification getToast(WebRequest request)
+	@ModelAttribute("notifications")
+	public List<Notification> getNotifications(WebRequest request)
 	{
-		return WebRequestUtils.popNotification(request);
+		return WebRequestUtils.getNotifications(request);
 	}
 }
diff --git a/src/main/java/de/deadlocker8/budgetmaster/utils/WebRequestUtils.java b/src/main/java/de/deadlocker8/budgetmaster/utils/WebRequestUtils.java
index 5247a50ee..06cf5d2bf 100644
--- a/src/main/java/de/deadlocker8/budgetmaster/utils/WebRequestUtils.java
+++ b/src/main/java/de/deadlocker8/budgetmaster/utils/WebRequestUtils.java
@@ -4,9 +4,12 @@ import de.deadlocker8.budgetmaster.utils.notification.Notification;
 import org.springframework.web.context.request.RequestAttributes;
 import org.springframework.web.context.request.WebRequest;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class WebRequestUtils
 {
-	private static final String ATTR_NOTIFICATION = "notification";
+	private static final String ATTR_NOTIFICATIONS = "notifications";
 
 	private WebRequestUtils()
 	{
@@ -14,24 +17,32 @@ public class WebRequestUtils
 
 	public static void putNotification(WebRequest request, Notification notification)
 	{
-		put(request, notification, ATTR_NOTIFICATION);
+		List<Notification> notifications = getNotifications(request, ATTR_NOTIFICATIONS);
+		notifications.add(notification);
+		put(request, notifications, ATTR_NOTIFICATIONS);
 	}
 
-	public static Notification popNotification(WebRequest request)
+	public static List<Notification> getNotifications(WebRequest request)
 	{
-		return (Notification) pop(request, ATTR_NOTIFICATION);
+		List<Notification> notifications = getNotifications(request, ATTR_NOTIFICATIONS);
+		request.removeAttribute(ATTR_NOTIFICATIONS, RequestAttributes.SCOPE_SESSION);
+		return notifications;
 	}
 
-	private static void put(WebRequest request, Object any, String key)
+	@SuppressWarnings("unchecked")
+	private static List<Notification> getNotifications(WebRequest request, String key)
 	{
-		request.setAttribute(key, any, RequestAttributes.SCOPE_SESSION);
+		Object notifications = request.getAttribute(key, RequestAttributes.SCOPE_SESSION);
+		if(notifications == null)
+		{
+			return new ArrayList<>();
+		}
+
+		return (List<Notification>) notifications;
 	}
 
-	public static Object pop(WebRequest request, String key)
+	private static void put(WebRequest request, Object any, String key)
 	{
-		final Object any = request.getAttribute(key, RequestAttributes.SCOPE_SESSION);
-		request.removeAttribute(key, RequestAttributes.SCOPE_SESSION);
-
-		return any;
+		request.setAttribute(key, any, RequestAttributes.SCOPE_SESSION);
 	}
 }
diff --git a/src/main/resources/static/js/main.js b/src/main/resources/static/js/main.js
index 60db641da..5699844ea 100644
--- a/src/main/resources/static/js/main.js
+++ b/src/main/resources/static/js/main.js
@@ -48,7 +48,7 @@ $(document).ready(function()
 
     $('.notification-clear').click(function()
     {
-        document.getElementsByClassName("notification-row")[0].style.display = "none";
+        document.getElementById(this.dataset.id).style.display = "none";
     });
 });
 
diff --git a/src/main/resources/templates/helpers/header.ftl b/src/main/resources/templates/helpers/header.ftl
index 7f47dad84..efd6955c3 100644
--- a/src/main/resources/templates/helpers/header.ftl
+++ b/src/main/resources/templates/helpers/header.ftl
@@ -66,31 +66,33 @@
 </#macro>
 
 <#macro content>
-    <#if notification??>
-        <@showNotification notification/>
+    <#if notifications??>
+        <@showNotifications notifications/>
     </#if>
 
     <#nested>
 </#macro>
 
-<#macro showNotification notification>
-    <div class="row notification-row">
-        <div class="col s12 center-align">
-            <div class="notification-wrapper">
-                <div class="notification ${notification.getBackgroundColor()} ${notification.getTextColor()}">
-                    <div>
-                        <#if notification.getIcon()??>
-                            <i class="${notification.getIcon()} notification-item"></i>
-                        </#if>
-                        <span class="notification-item">${notification.getMessage()}</span>
+<#macro showNotifications notifications>
+    <#list notifications as notification>
+        <div class="row notification-row" id="notification-${notification?index}">
+            <div class="col s12 center-align">
+                <div class="notification-wrapper">
+                    <div class="notification ${notification.getBackgroundColor()} ${notification.getTextColor()}">
+                        <div>
+                            <#if notification.getIcon()??>
+                                <i class="${notification.getIcon()} notification-item"></i>
+                            </#if>
+                            <span class="notification-item">${notification.getMessage()}</span>
+                        </div>
+                        <a class="notification-item notification-clear ${notification.getTextColor()}" data-id="notification-${notification?index}">
+                            <i class="material-icons">clear</i>
+                        </a>
                     </div>
-                    <a class="notification-item notification-clear ${notification.getTextColor()}">
-                        <i class="material-icons">clear</i>
-                    </a>
                 </div>
             </div>
         </div>
-    </div>
+    </#list>
 </#macro>
 
 <#macro buttonLink url icon localizationKey id="" color="background-blue" classes="" isDataUrl=false noUrl=false disabled=false>
-- 
GitLab