diff --git a/changelog.html b/changelog.html
index 9e63b9448f8d906bfd1dc7da651cb087923f3c86..c2f181c22558ce0da2c3474dd84e611274d87b31 100644
--- a/changelog.html
+++ b/changelog.html
@@ -58,6 +58,8 @@ Upcoming changes
System Message - Doesnt appear on any view other than the default view.
(issue 7733)
+
+ Added UI component to show notification bar at the top of the page
diff --git a/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NotificationBar.java b/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NotificationBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf81df117b6fe5c4d393f581f7212dba84d02332
--- /dev/null
+++ b/ui-samples-plugin/src/main/java/jenkins/plugins/ui_samples/NotificationBar.java
@@ -0,0 +1,29 @@
+package jenkins.plugins.ui_samples;
+
+import hudson.Extension;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Kohsuke Kawaguchi
+ */
+@Extension
+public class NotificationBar extends UISample {
+ @Override
+ public String getDescription() {
+ return "Notification bar shows a transient message on the top of the page";
+ }
+
+ public List getSourceFiles() {
+ // TODO: generate this from index
+ return Arrays.asList(
+ new SourceFile("index.groovy"));
+ }
+
+ @Extension
+ public static final class DescriptorImpl extends UISampleDescriptor {
+ }
+}
+
+
diff --git a/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/NotificationBar/index.groovy b/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/NotificationBar/index.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..87ee9da367fee9f8f799f8cb916a42663ef02cfb
--- /dev/null
+++ b/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/NotificationBar/index.groovy
@@ -0,0 +1,17 @@
+package jenkins.plugins.ui_samples.NotificationBar;
+
+import lib.JenkinsTagLib
+
+def st=namespace("jelly:stapler")
+
+t=namespace(JenkinsTagLib.class)
+
+namespace("/lib/samples").sample(title:_("Notification Bar")) {
+ p(_("blurb"))
+
+ p("To show a notification bar, call notificationBar.show('message')");
+ button(onclick:"notificationBar.show('This is a notification');", "Show a notification bar")
+
+ p(_("blurb.hide"))
+ button(onclick:"notificationBar.hide();", "Hide it now")
+}
diff --git a/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/NotificationBar/index.properties b/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/NotificationBar/index.properties
new file mode 100644
index 0000000000000000000000000000000000000000..825bbc9c44de9df4a15e76c32ce5a92221c88fb0
--- /dev/null
+++ b/ui-samples-plugin/src/main/resources/jenkins/plugins/ui_samples/NotificationBar/index.properties
@@ -0,0 +1,4 @@
+blurb=Notification bar shows a message that disappears in a few seconds. \
+ It is typically used to provide feedback for asynchronous operations.
+
+blurb.hide=A notification bar will auto-hide itself, but you can programmatically hide it via notificationBar.hide()
\ No newline at end of file
diff --git a/war/pom.xml b/war/pom.xml
index ba1381ab4a65c8922ba78cd0454553765afb4dac..113e8c28af84944592d79ddb2eedd008b43fc315 100644
--- a/war/pom.xml
+++ b/war/pom.xml
@@ -394,7 +394,7 @@ THE SOFTWARE.
hudson.bundled.plugins
-
+
${basedir}/../maven-plugin/target/test-classes/the.hpl,
${basedir}/../ui-samples-plugin/target/test-classes/the.hpl,
${project.build.directory}/${project.build.finalName}/WEB-INF/plugins/javadoc.hpi
diff --git a/war/src/main/webapp/css/style.css b/war/src/main/webapp/css/style.css
index a44cfc823adec3192374bf3f03ad95c57f75f662..aa5981f7b1332b4a7db36c4de091b3558e6fd0e5 100644
--- a/war/src/main/webapp/css/style.css
+++ b/war/src/main/webapp/css/style.css
@@ -1002,6 +1002,17 @@ table.progress-bar.red td.progress-bar-done {
background-color: #cc0000;
}
+/* ========================= notification bar ========================= */
+#notification-bar {
+ width:100%;
+ position:fixed;
+ text-align:center;
+ left:0px;
+ font-size: 2em;
+ z-index:999;
+ border-bottom: 1px solid black;
+}
+
/* ========================= YUI dialog ========================= */
.dialog .hd {
diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js
index 03603e9038ccc5f7e50db918209f6b724dd86aa4..789d533f1122dd49298638bc52199164b16f0288 100644
--- a/war/src/main/webapp/scripts/hudson-behavior.js
+++ b/war/src/main/webapp/scripts/hudson-behavior.js
@@ -2539,4 +2539,59 @@ var layoutUpdateCallback = {
for (var i = 0, length = this.callbacks.length; i < length; i++)
this.callbacks[i]();
}
-}
\ No newline at end of file
+}
+
+// notification bar
+var notificationBar = {
+ OPACITY : 0.8,
+ DELAY : 3000, // milliseconds to auto-close the notification
+ div : null, // the main 'notification-bar' DIV
+ token : null, // timer for cancelling auto-close
+
+ init : function() {
+ if (this.div==null) {
+ this.div = document.createElement("div");
+ YAHOO.util.Dom.setStyle(this.div,"opacity",0);
+ this.div.id="notification-bar";
+ document.body.insertBefore(this.div, document.body.firstChild);
+
+ var self = this;
+ this.div.onclick = function() {
+ self.hide();
+ };
+ }
+ },
+ // cancel pending auto-hide timeout
+ clearTimeout : function() {
+ if (this.token)
+ window.clearTimeout(this.token);
+ this.token = null;
+ },
+ // hide the current notification bar, if it's displayed
+ hide : function () {
+ this.clearTimeout();
+ new YAHOO.util.Anim(this.div, {
+ opacity: { to:0 }
+ }, 0.3, YAHOO.util.Easing.easeIn).animate();
+ },
+ // show a notification bar
+ show : function (text,options) {
+ options = options || {}
+
+ this.init();
+ this.div.style.backgroundColor = options.backgroundColor || "#fff";
+ this.div.style.height = this.div.style.lineHeight = options.height || "40px";
+
+ if (options.icon)
+ text = "
"+text;
+ this.div.innerHTML = text;
+
+ new YAHOO.util.Anim(this.div, {
+ opacity: { to:this.OPACITY }
+ }, 1, YAHOO.util.Easing.easeOut).animate();
+
+ this.clearTimeout();
+ var self = this;
+ this.token = window.setTimeout(function(){self.hide();},this.DELAY);
+ }
+};