launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #03079
[Merge] lp:~wallyworld/launchpad/show-ajax-notifications into lp:launchpad
Ian Booth has proposed merging lp:~wallyworld/launchpad/show-ajax-notifications into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/show-ajax-notifications/+merge/54342
Display notifications that may be included in an xhr response object. These are of type informational, error, warning or debug.
--
https://code.launchpad.net/~wallyworld/launchpad/show-ajax-notifications/+merge/54342
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/show-ajax-notifications into lp:launchpad.
=== modified file 'lib/canonical/launchpad/webapp/configure.zcml'
--- lib/canonical/launchpad/webapp/configure.zcml 2011-02-03 19:01:10 +0000
+++ lib/canonical/launchpad/webapp/configure.zcml 2011-03-28 01:50:57 +0000
@@ -58,6 +58,11 @@
provides="lazr.restful.interfaces.IWebBrowserOriginatingRequest"
factory="canonical.launchpad.webapp.servers.web_service_request_to_browser_request"
/>
+ <adapter
+ for="canonical.launchpad.layers.WebServiceLayer"
+ provides="lazr.restful.interfaces.INotificationsProvider"
+ factory="canonical.launchpad.webapp.servers.web_service_request_to_notification_request"
+ />
<!-- lazr.batchnavigator hook -->
<adapter
=== modified file 'lib/canonical/launchpad/webapp/servers.py'
--- lib/canonical/launchpad/webapp/servers.py 2010-12-06 14:59:43 +0000
+++ lib/canonical/launchpad/webapp/servers.py 2011-03-28 01:50:57 +0000
@@ -21,7 +21,6 @@
WebServiceRequestTraversal,
)
from lazr.uri import URI
-import pytz
import transaction
from transaction.interfaces import ISynchronizer
from zc.zservertracelog.tracelog import Server as ZServerTracelogServer
@@ -704,6 +703,11 @@
return LaunchpadBrowserRequest(body, environ)
+def web_service_request_to_notification_request(request):
+ """Convert a given webservice request into one providing notifications."""
+ return INotificationRequest(request)
+
+
class Zope3WidgetsUseIBrowserFormNGMonkeyPatch:
"""Make Zope3 widgets use IBrowserFormNG.
=== modified file 'lib/lp/app/javascript/client.js'
--- lib/lp/app/javascript/client.js 2011-02-25 01:54:00 +0000
+++ lib/lp/app/javascript/client.js 2011-03-28 01:50:57 +0000
@@ -242,6 +242,8 @@
var media_type = response.getResponseHeader('Content-Type');
if (media_type.substring(0,16) == 'application/json') {
representation = Y.JSON.parse(response.responseText);
+ display_notifications(
+ response.getResponseHeader('X-Lazr-Notifications'));
wrapped = client.wrap_resource(uri, representation);
result = old_on_success(wrapped);
if (update_cache) {
@@ -254,6 +256,73 @@
}
};
+/**
+ * Display a list of notifications - error, warning, informational or debug.
+ * @param notifications An json encoded array of (level, message) tuples.
+ */
+function display_notifications(notifications) {
+ if (notifications === undefined)
+ return;
+
+ // First remove any existing notifications.
+ function remove_notifications(div_class) {
+ var nodes = Y.all('div.'+div_class);
+ nodes.each(function(node) {
+ var parent = node.get('parentNode');
+ parent.removeChild(node);
+ });
+ }
+ remove_notifications('error');
+ remove_notifications('warning');
+ remove_notifications('informational');
+ remove_notifications('debug');
+
+ // Now display the new ones.
+ notifications = Y.JSON.parse(notifications);
+ var warnings = new Array();
+ var errors = new Array();
+ var infos = new Array();
+ var debugs = new Array();
+
+ Y.each(notifications, function(notification, key) {
+ var level = notification[0];
+ var message = notification[1];
+ switch (level) {
+ case 10:
+ debugs.push(message);
+ break;
+ case 20:
+ infos.push(message);
+ break;
+ case 30:
+ warnings.push(message);
+ break;
+ case 40:
+ errors.push(message);
+ break;
+ }
+ });
+ // The place where we want to insert the notification divs.
+ var last_message = Y.one('div.context-publication');
+ var display_notification = function(notification, div_class) {
+ var node = Y.Node.create("<div class='"+div_class+"'/>");
+ node.set('innerHTML', notification);
+ last_message.insert(node, 'after');
+ last_message = node;
+ };
+ Y.each(errors, function(notification, key) {
+ display_notification(notification, 'error message');
+ });
+ Y.each(warnings, function(notification, key) {
+ display_notification(notification, 'warning message');
+ });
+ Y.each(infos, function(notification, key) {
+ display_notification(notification, 'informational message');
+ });
+ Y.each(debugs, function(notification, key) {
+ display_notification(notification, 'debug message');
+ });
+}
// The resources that come together to make Launchpad.
=== modified file 'lib/lp/app/javascript/tests/test_lp_client.html'
--- lib/lp/app/javascript/tests/test_lp_client.html 2011-02-25 01:54:00 +0000
+++ lib/lp/app/javascript/tests/test_lp_client.html 2011-03-28 01:50:57 +0000
@@ -18,7 +18,9 @@
<script type="text/javascript" src="test_lp_client.js"></script>
</head>
<body class="yui3-skin-sam">
- <div id="container-of-stuff">
+ <div class="context-publication">
+ <div id="container-of-stuff">
+ </div>
</div>
</body>
</html>
=== modified file 'lib/lp/app/javascript/tests/test_lp_client.js'
--- lib/lp/app/javascript/tests/test_lp_client.js 2011-02-25 02:51:27 +0000
+++ lib/lp/app/javascript/tests/test_lp_client.js 2011-03-28 01:50:57 +0000
@@ -171,6 +171,53 @@
}
}));
+function MockHttpResponse () {
+ this.responseText = '[]';
+ this.responseHeaders = {};
+}
+
+MockHttpResponse.prototype = {
+ setResponseHeader: function (header, value) {
+ this.responseHeaders[header] = value;
+ },
+
+ getResponseHeader: function(header) {
+ return this.responseHeaders[header];
+ }
+};
+
+suite.add(new Y.Test.Case({
+ name: "lp.client.notifications",
+
+ setUp: function() {
+ this.client = new Y.lp.client.Launchpad();
+ this.args=[this.client, null, this._on_success, false];
+ this.response = new MockHttpResponse();
+ this.response.setResponseHeader('Content-Type', 'application/json');
+ },
+
+ _on_success: function(entry) {
+ },
+
+ _checkNotificationNode: function(node_class, node_text) {
+ var node = Y.one('div.'+node_class);
+ Assert.areEqual(node_text, node.get("innerHTML"));
+ },
+
+ test_display_notifications: function() {
+ var notifications = '[ [10, "A debug"], [20, "An info"], ' +
+ '[30, "A warning"], [40, "An error"] ]';
+ this.response.setResponseHeader(
+ 'X-Lazr-Notifications', notifications);
+ Y.lp.client.wrap_resource_on_success(null, this.response, this.args);
+ this._checkNotificationNode('debug', 'A debug');
+ this._checkNotificationNode('informational', 'An info');
+ this._checkNotificationNode('warning', 'A warning');
+ this._checkNotificationNode('error', 'An error');
+ }
+
+}));
+
// Lock, stock, and two smoking barrels.
var handle_complete = function(data) {
=== modified file 'versions.cfg'
--- versions.cfg 2011-03-23 16:28:51 +0000
+++ versions.cfg 2011-03-28 01:50:57 +0000
@@ -34,7 +34,7 @@
lazr.delegates = 1.2.0
lazr.enum = 1.1.2
lazr.lifecycle = 1.1
-lazr.restful = 0.18.0
+lazr.restful = 0.18.1
lazr.restfulclient = 0.11.2
lazr.smtptest = 1.1
lazr.testing = 0.1.1