From 36c5ff5b08004ad459b978646c98c8c0e6387127 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Thu, 13 Dec 2007 20:26:32 +0000 Subject: [PATCH] Display of current invites now updates when you add new invites. This means that controller.Users.send_invites() now returns a list of current invites. Added a "new!" to the share link. --- controller/Users.py | 15 ++++-- controller/test/Test_users.py | 86 +++++++++++++++++++++++++++++------ static/css/style.css | 6 +++ static/js/Editor.js | 5 +- static/js/Wiki.js | 85 ++++++++++++++++++---------------- view/Link_area.py | 4 ++ 6 files changed, 142 insertions(+), 59 deletions(-) diff --git a/controller/Users.py b/controller/Users.py index 79ca044..631b211 100644 --- a/controller/Users.py +++ b/controller/Users.py @@ -676,7 +676,7 @@ class Users( object ): @type user_id: unicode @param user_id: id of current logged-in user (if any), determined by @grab_user_id @rtype: json dict - @return: { 'message': message } + @return: { 'message': message, 'invites': invites } @raise Password_reset_error: an error occured when sending the password reset email @raise Validation_error: one of the arguments is invalid @raise Access_error: user_id doesn't have owner-level notebook access to send an invite or @@ -747,7 +747,7 @@ class Users( object ): message[ u"To" ] = email_address message[ u"Subject" ] = notebook_name message.set_payload( - u"I've shared a wiki with you called: %s\n" % notebook_name + + u"I've shared a wiki with you called \"%s\".\n" % notebook_name + u"Please visit the following link to view it online:\n\n" + u"%s/i/%s\n\n" % ( self.__https_url or self.__http_url, invite.object_id ) ) @@ -759,8 +759,15 @@ class Users( object ): server.quit() self.__database.commit() + invites = self.__database.select_many( Invite, Invite.sql_load_notebook_invites( notebook_id ) ) if email_count == 1: - return dict( message = u"An invitation has been sent." ) + return dict( + message = u"An invitation has been sent.", + invites = invites, + ) else: - return dict( message = u"%s invitations have been sent." % email_count ) + return dict( + message = u"%s invitations have been sent." % email_count, + invites = invites, + ) diff --git a/controller/test/Test_users.py b/controller/test/Test_users.py index 4a72fc6..b40a687 100644 --- a/controller/test/Test_users.py +++ b/controller/test/Test_users.py @@ -775,6 +775,13 @@ class Test_users( Test_controller ): session_id = result[ u"session_id" ] assert u"An invitation has been sent." in result[ u"message" ] + invites = result[ u"invites" ] + assert len( invites ) == 1 + invite = invites[ -1 ] + assert invite + assert invite.read_write is False + assert invite.owner is False + assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == 1 @@ -787,10 +794,10 @@ class Test_users( Test_controller ): assert invite_id # assert that the invite has the read_write / owner flags set appropriately - invite_list = self.database.objects.get( invite_id ) - assert invite_list - assert len( invite_list ) == 1 - invite = invite_list[ -1 ] + invites = self.database.objects.get( invite_id ) + assert invites + assert len( invites ) == 1 + invite = invites[ -1 ] assert invite assert invite.read_write is False assert invite.owner is False @@ -816,6 +823,13 @@ class Test_users( Test_controller ): session_id = result[ u"session_id" ] assert u"An invitation has been sent." in result[ u"message" ] + invites = result[ u"invites" ] + assert len( invites ) == 1 + invite = invites[ -1 ] + assert invite + assert invite.read_write is True + assert invite.owner is False + assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == 1 @@ -828,10 +842,10 @@ class Test_users( Test_controller ): assert invite_id # assert that the invite has the read_write / owner flags set appropriately - invite_list = self.database.objects.get( invite_id ) - assert invite_list - assert len( invite_list ) == 1 - invite = invite_list[ -1 ] + invites = self.database.objects.get( invite_id ) + assert invites + assert len( invites ) == 1 + invite = invites[ -1 ] assert invite assert invite.read_write is True assert invite.owner is False @@ -857,6 +871,13 @@ class Test_users( Test_controller ): session_id = result[ u"session_id" ] assert u"An invitation has been sent." in result[ u"message" ] + invites = result[ u"invites" ] + assert len( invites ) == 1 + invite = invites[ -1 ] + assert invite + assert invite.read_write is True + assert invite.owner is True + assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == 1 @@ -869,10 +890,10 @@ class Test_users( Test_controller ): assert invite_id # assert that the invite has the read_write / owner flags set appropriately - invite_list = self.database.objects.get( invite_id ) - assert invite_list - assert len( invite_list ) == 1 - invite = invite_list[ -1 ] + invites = self.database.objects.get( invite_id ) + assert invites + assert len( invites ) == 1 + invite = invites[ -1 ] assert invite assert invite.read_write is True assert invite.owner is True @@ -898,6 +919,13 @@ class Test_users( Test_controller ): session_id = result[ u"session_id" ] email_count = len( email_addresses_list ) + invites = result[ u"invites" ] + assert len( invites ) == email_count + for invite in invites: + assert invite + assert invite.read_write is False + assert invite.owner is False + assert u"%s invitations have been sent." % email_count in result[ u"message" ] assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == email_count @@ -931,6 +959,13 @@ class Test_users( Test_controller ): session_id = result[ u"session_id" ] email_count = len( email_addresses_list ) - 1 # -1 because of the duplicate + invites = result[ u"invites" ] + assert len( invites ) == email_count + for invite in invites: + assert invite + assert invite.read_write is False + assert invite.owner is False + assert u"%s invitations have been sent." % email_count in result[ u"message" ] assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == email_count @@ -967,13 +1002,20 @@ class Test_users( Test_controller ): assert invite_id1 # then send a similar invite to the same email address with read_write and owner set to True - self.http_post( "/users/send_invites", dict( + result = self.http_post( "/users/send_invites", dict( notebook_id = self.notebooks[ 0 ].object_id, email_addresses = email_addresses, access = u"owner", invite_button = u"send invites", ), session_id = self.session_id ) + invites = result[ u"invites" ] + assert len( invites ) == 1 + invite = invites[ 0 ] + assert invite + assert invite.read_write is True + assert invite.owner is True + matches = self.INVITE_LINK_PATTERN.search( smtplib.SMTP.message ) invite_id2 = matches.group( 2 ) assert invite_id2 @@ -1000,8 +1042,10 @@ class Test_users( Test_controller ): smtplib.SMTP = Stub_smtp self.login() - self.user.rate_plan = 1 + # setting the user's email address to None means the invite will be sent + # with a "generic" From address (in this case, Luminotes support) self.user._User__email_address = None + self.user.rate_plan = 1 self.database.save( self.user ) email_addresses_list = [ u"foo@example.com" ] @@ -1015,6 +1059,13 @@ class Test_users( Test_controller ): ), session_id = self.session_id ) session_id = result[ u"session_id" ] + invites = result[ u"invites" ] + assert len( invites ) == 1 + invite = invites[ 0 ] + assert invite + assert invite.read_write is False + assert invite.owner is False + assert u"An invitation has been sent." in result[ u"message" ] assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == 1 @@ -1219,6 +1270,13 @@ class Test_users( Test_controller ): ), session_id = self.session_id ) session_id = result[ u"session_id" ] + invites = result[ u"invites" ] + assert len( invites ) == 1 + invite = invites[ 0 ] + assert invite + assert invite.read_write is False + assert invite.owner is False + assert u"An invitation has been sent." in result[ u"message" ] assert smtplib.SMTP.connected == False assert len( smtplib.SMTP.emails ) == 1 diff --git a/static/css/style.css b/static/css/style.css index 2ce1110..58b81f1 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -576,3 +576,9 @@ img { .small_text { font-size: 90%; } + +.new_feature_text { + font-size: 90%; + font-weight: bold; + color: #ff6600; +} diff --git a/static/js/Editor.js b/static/js/Editor.js index f060c4e..3aaa8f6 100644 --- a/static/js/Editor.js +++ b/static/js/Editor.js @@ -207,7 +207,10 @@ Editor.prototype.finish_init = function () { var invite_form = getElement( "invite_form" ); connect( invite_button, "onclick", function ( event ) { - signal( self, "submit_form", "/users/send_invites", invite_form ); event.stop(); + signal( self, "submit_form", "/users/send_invites", invite_form, function ( result ) { + if ( !result.invites ) return; + signal( self, "invites_updated", result.invites ); + } ); event.stop(); } ); } } ); diff --git a/static/js/Wiki.js b/static/js/Wiki.js index aa0cd1a..104a579 100644 --- a/static/js/Wiki.js +++ b/static/js/Wiki.js @@ -640,8 +640,9 @@ Wiki.prototype.create_editor = function ( id, note_text, deleted_from_id, revisi connect( editor, "load_editor", this, "load_editor" ); connect( editor, "hide_clicked", function ( event ) { self.hide_editor( event, editor ) } ); - connect( editor, "submit_form", function ( url, form ) { - self.invoker.invoke( url, "POST", null, null, form ); + connect( editor, "invites_updated", function ( invites ) { self.invites = invites; self.share_notebook(); } ); + connect( editor, "submit_form", function ( url, form, callback ) { + self.invoker.invoke( url, "POST", null, callback, form ); } ); this.clear_messages(); @@ -1246,10 +1247,8 @@ Wiki.prototype.share_notebook = function () { this.clear_pulldowns(); var share_notebook_frame = getElement( "note_share_notebook" ); - if ( share_notebook_frame ) { - share_notebook_frame.editor.highlight(); - return; - } + if ( share_notebook_frame ) + share_notebook_frame.editor.shutdown(); var collaborators_link = createDOM( "a", { "href": "#", "id": "collaborators_link", "class": "radio_link", "title": "Collaborators may view and edit this notebook." }, @@ -1297,40 +1296,8 @@ Wiki.prototype.share_notebook = function () { ); } - if ( this.invites ) { - var collaborators = createDOM( "ul", { "id": "collaborators" } ); - var viewers = createDOM( "ul", { "id": "viewers" } ); - var owners = createDOM( "ul", { "id": "owners" } ); - - for ( var i in this.invites ) { - var invite = this.invites[ i ]; - if ( invite.owner ) { - appendChildNodes( owners, createDOM( "li", {}, invite.email_address ) ); - } else { - if ( invite.read_write ) - appendChildNodes( collaborators, createDOM( "li", {}, invite.email_address ) ); - else - appendChildNodes( viewers, createDOM( "li", {}, invite.email_address ) ); - } - } - - var invite_area = createDOM( "p", { "id": "invite_area" } ); - - if ( collaborators.childNodes.length > 0 ) { - appendChildNodes( invite_area, createDOM( "h3", {}, "collaborators" ) ); - appendChildNodes( invite_area, collaborators ); - } - if ( viewers.childNodes.length > 0 ) { - appendChildNodes( invite_area, createDOM( "h3", {}, "viewers" ) ); - appendChildNodes( invite_area, viewers ); - } - if ( owners.childNodes.length > 0 ) { - appendChildNodes( invite_area, createDOM( "h3", {}, "owners" ) ); - appendChildNodes( invite_area, owners ); - } - } else { - var invite_area = createDOM( "p", {}, "There are no invites." ); - } + var invite_area = createDOM( "p", { "id": "invite_area" } ); + this.update_invites( invite_area ); var div = createDOM( "div", {}, createDOM( "form", { "id": "invite_form" }, @@ -1356,6 +1323,44 @@ Wiki.prototype.share_notebook = function () { this.create_editor( "share_notebook", "

share this notebook

" + div.innerHTML, undefined, undefined, undefined, false, true, true, getElement( "notes_top" ) ); } +Wiki.prototype.update_invites = function ( invite_area ) { + if ( !this.invites || this.invites.length == 0 ) + return; + + var collaborators = createDOM( "ul", { "id": "collaborators" } ); + var viewers = createDOM( "ul", { "id": "viewers" } ); + var owners = createDOM( "ul", { "id": "owners" } ); + + for ( var i in this.invites ) { + var invite = this.invites[ i ]; + if ( invite.owner ) { + appendChildNodes( owners, createDOM( "li", {}, invite.email_address ) ); + } else { + if ( invite.read_write ) + appendChildNodes( collaborators, createDOM( "li", {}, invite.email_address ) ); + else + appendChildNodes( viewers, createDOM( "li", {}, invite.email_address ) ); + } + } + + var div = createDOM( "div" ); + + if ( collaborators.childNodes.length > 0 ) { + appendChildNodes( div, createDOM( "h3", {}, "collaborators" ) ); + appendChildNodes( div, collaborators ); + } + if ( viewers.childNodes.length > 0 ) { + appendChildNodes( div, createDOM( "h3", {}, "viewers" ) ); + appendChildNodes( div, viewers ); + } + if ( owners.childNodes.length > 0 ) { + appendChildNodes( div, createDOM( "h3", {}, "owners" ) ); + appendChildNodes( div, owners ); + } + + replaceChildNodes( invite_area, div ); +} + Wiki.prototype.display_message = function ( text, nodes, position_after ) { this.clear_messages(); this.clear_pulldowns(); diff --git a/view/Link_area.py b/view/Link_area.py index a77edfd..1a8c17e 100644 --- a/view/Link_area.py +++ b/view/Link_area.py @@ -82,6 +82,10 @@ class Link_area( Div ): id = u"share_notebook_link", title = u"Share this notebook with others.", ), + Span( + u"new!", + class_ = u"new_feature_text", + ), class_ = u"link_area_item", ) or None,