Display a realtime count of total notes next to the "all notes" link.
This commit is contained in:
parent
89a3d6d300
commit
27a6a06c91
|
@ -96,6 +96,7 @@ class Notebooks( object ):
|
|||
@return: {
|
||||
'notebook': notebook,
|
||||
'startup_notes': notelist,
|
||||
'total_notes_count': notecount,
|
||||
'note': note or None,
|
||||
}
|
||||
@raise Access_error: the current user doesn't have access to the given notebook or note
|
||||
|
@ -123,10 +124,12 @@ class Notebooks( object ):
|
|||
note = None
|
||||
|
||||
startup_notes = self.__database.select_many( Note, notebook.sql_load_startup_notes() )
|
||||
total_notes_count = self.__database.select_one( int, notebook.sql_count_notes() )
|
||||
|
||||
return dict(
|
||||
notebook = notebook,
|
||||
startup_notes = startup_notes,
|
||||
total_notes_count = total_notes_count,
|
||||
note = note,
|
||||
)
|
||||
|
||||
|
|
|
@ -546,6 +546,7 @@ class Users( object ):
|
|||
result = self.current( anonymous.object_id )
|
||||
result[ "notebook" ] = main_notebook
|
||||
result[ "startup_notes" ] = self.__database.select_many( Note, main_notebook.sql_load_startup_notes() )
|
||||
result[ "total_notes_count" ] = self.__database.select_one( Note, main_notebook.sql_count_notes() )
|
||||
result[ "note_read_write" ] = False
|
||||
result[ "note" ] = Note.create(
|
||||
object_id = u"password_reset",
|
||||
|
|
|
@ -169,6 +169,19 @@ class Test_controller( object ):
|
|||
Notebook.sql_highest_rank = lambda self: \
|
||||
lambda database: sql_highest_rank( self, database )
|
||||
|
||||
def sql_count_notes( self, database ):
|
||||
count = 0
|
||||
|
||||
for ( object_id, obj_list ) in database.objects.items():
|
||||
obj = obj_list[ -1 ]
|
||||
if isinstance( obj, Note ) and obj.notebook_id == self.object_id:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
Notebook.sql_count_notes = lambda self: \
|
||||
lambda database: sql_count_notes( self, database )
|
||||
|
||||
def setUp( self ):
|
||||
from controller.Root import Root
|
||||
cherrypy.lowercase_api = True
|
||||
|
|
|
@ -79,6 +79,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert result.get( u"rate_plan" )
|
||||
assert result.get( u"notebook" ).object_id == self.notebook.object_id
|
||||
assert len( result.get( u"startup_notes" ) ) == 1
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
assert result.get( u"note" ) is None
|
||||
assert result.get( u"parent_id" ) == None
|
||||
assert result.get( u"note_read_write" ) in ( None, True )
|
||||
|
@ -101,6 +102,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert result.get( u"rate_plan" )
|
||||
assert result.get( u"notebook" ).object_id == self.notebook.object_id
|
||||
assert len( result.get( u"startup_notes" ) ) == 1
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
assert result.get( u"note" ).object_id == self.note.object_id
|
||||
assert result.get( u"parent_id" ) == None
|
||||
assert result.get( u"note_read_write" ) in ( None, True )
|
||||
|
@ -127,6 +129,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert result.get( u"rate_plan" )
|
||||
assert result.get( u"notebook" ).object_id == self.notebook.object_id
|
||||
assert len( result.get( u"startup_notes" ) ) == 1
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
assert result.get( u"note" ).object_id == self.note.object_id
|
||||
assert result.get( u"note" ).revision == self.note.revision
|
||||
assert result.get( u"parent_id" ) == None
|
||||
|
@ -151,6 +154,7 @@ class Test_notebooks( Test_controller ):
|
|||
assert result.get( u"rate_plan" )
|
||||
assert result.get( u"notebook" ).object_id == self.notebook.object_id
|
||||
assert len( result.get( u"startup_notes" ) ) == 1
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
assert result.get( u"note" ) is None
|
||||
assert result.get( u"parent_id" ) == parent_id
|
||||
assert result.get( u"note_read_write" ) in ( None, True )
|
||||
|
@ -166,6 +170,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
notebook = result[ "notebook" ]
|
||||
startup_notes = result[ "startup_notes" ]
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
assert result[ "note" ] == None
|
||||
|
||||
assert notebook.object_id == self.notebook.object_id
|
||||
|
@ -184,6 +189,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
notebook = result[ "notebook" ]
|
||||
startup_notes = result[ "startup_notes" ]
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
|
||||
assert notebook.object_id == self.notebook.object_id
|
||||
assert notebook.read_write == True
|
||||
|
@ -207,6 +213,7 @@ class Test_notebooks( Test_controller ):
|
|||
|
||||
notebook = result[ "notebook" ]
|
||||
startup_notes = result[ "startup_notes" ]
|
||||
assert result[ "total_notes_count" ] == 2
|
||||
|
||||
assert notebook.object_id == self.notebook.object_id
|
||||
assert notebook.read_write == True
|
||||
|
@ -249,6 +256,7 @@ class Test_notebooks( Test_controller ):
|
|||
notebook = result[ "notebook" ]
|
||||
startup_notes = result[ "startup_notes" ]
|
||||
assert result[ "note" ] == None
|
||||
assert result[ "total_notes_count" ] == 0
|
||||
|
||||
assert notebook.object_id == self.anon_notebook.object_id
|
||||
assert notebook.read_write == False
|
||||
|
|
|
@ -123,8 +123,19 @@ class Notebook( Persistent ):
|
|||
( quote( self.object_id ), quote( "%" + search_text + "%" ) )
|
||||
|
||||
def sql_highest_rank( self ):
|
||||
"""
|
||||
Return a SQL string to determine the highest numbered rank of all notes in this notebook."
|
||||
"""
|
||||
return "select coalesce( max( rank ), -1 ) from note_current where notebook_id = %s;" % quote( self.object_id )
|
||||
|
||||
def sql_count_notes( self ):
|
||||
"""
|
||||
Return a SQL string to count the total number of notes in this notebook.
|
||||
"""
|
||||
return \
|
||||
"select count( id ) from note_current where notebook_id = %s;" % \
|
||||
( quote( self.object_id ) )
|
||||
|
||||
def to_dict( self ):
|
||||
d = Persistent.to_dict( self )
|
||||
|
||||
|
|
|
@ -422,3 +422,6 @@ ol li {
|
|||
background-color: #ffcc66;
|
||||
}
|
||||
|
||||
.small_text {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
|
|
@ -191,6 +191,7 @@ Wiki.prototype.create_blank_editor = function ( event ) {
|
|||
}
|
||||
|
||||
var editor = this.create_editor( undefined, undefined, undefined, undefined, this.notebook.read_write, true, true );
|
||||
this.increment_total_notes_count();
|
||||
this.blank_editor_id = editor.id;
|
||||
}
|
||||
|
||||
|
@ -369,6 +370,7 @@ Wiki.prototype.parse_loaded_editor = function ( result, note_title, requested_re
|
|||
var note_text = "<h3>" + note_title;
|
||||
var deleted_from_id = null;
|
||||
var actual_revision = null;
|
||||
this.increment_total_notes_count();
|
||||
}
|
||||
|
||||
if ( requested_revision )
|
||||
|
@ -479,6 +481,7 @@ Wiki.prototype.editor_focused = function ( editor, fire_and_forget ) {
|
|||
// if the formerly focused editor is completely empty, then remove it as the user leaves it and switches to this editor
|
||||
if ( this.focused_editor.empty() ) {
|
||||
this.focused_editor.shutdown();
|
||||
this.decrement_total_notes_count();
|
||||
this.display_empty_message();
|
||||
} else {
|
||||
// when switching editors, save the one being left
|
||||
|
@ -593,17 +596,27 @@ Wiki.prototype.hide_editor = function ( event, editor ) {
|
|||
this.clear_messages();
|
||||
this.clear_pulldowns();
|
||||
|
||||
if ( editor == this.focused_editor )
|
||||
this.focused_editor = null;
|
||||
|
||||
if ( !editor ) {
|
||||
editor = this.focused_editor;
|
||||
this.focused_editor = null;
|
||||
}
|
||||
|
||||
if ( editor ) {
|
||||
// before hiding an editor, save it
|
||||
if ( this.notebook.read_write )
|
||||
this.save_editor( editor );
|
||||
// if the editor to hide is completely empty, then simply remove it
|
||||
if ( editor.empty() ) {
|
||||
editor.shutdown();
|
||||
this.decrement_total_notes_count();
|
||||
} else {
|
||||
// before hiding an editor, save it
|
||||
if ( this.notebook.read_write )
|
||||
this.save_editor( editor );
|
||||
|
||||
editor.shutdown();
|
||||
}
|
||||
|
||||
editor.shutdown();
|
||||
this.display_empty_message();
|
||||
}
|
||||
|
||||
|
@ -652,6 +665,7 @@ Wiki.prototype.delete_editor = function ( event, editor ) {
|
|||
}
|
||||
|
||||
editor.shutdown();
|
||||
this.decrement_total_notes_count();
|
||||
this.display_empty_message();
|
||||
}
|
||||
|
||||
|
@ -685,6 +699,7 @@ Wiki.prototype.undelete_editor_via_trash = function ( event, editor ) {
|
|||
this.focused_editor = null;
|
||||
|
||||
editor.shutdown();
|
||||
this.decrement_total_notes_count();
|
||||
this.display_empty_message();
|
||||
}
|
||||
|
||||
|
@ -705,6 +720,7 @@ Wiki.prototype.undelete_editor_via_undo = function( event, editor ) {
|
|||
}
|
||||
|
||||
this.startup_notes[ editor.id ] = true;
|
||||
this.increment_total_notes_count();
|
||||
this.load_editor( "Note not found.", editor.id, null );
|
||||
}
|
||||
|
||||
|
@ -994,6 +1010,7 @@ Wiki.prototype.delete_all_editors = function ( event ) {
|
|||
editor.shutdown();
|
||||
}
|
||||
|
||||
this.zero_total_notes_count();
|
||||
this.display_empty_message();
|
||||
|
||||
event.stop();
|
||||
|
@ -1027,8 +1044,24 @@ Wiki.prototype.brief_revision = function ( revision ) {
|
|||
matches[ 6 ], // second
|
||||
matches[ 7 ] * 0.001 // milliseconds
|
||||
) ).toLocaleString();
|
||||
}
|
||||
|
||||
// return revision.split( /\.\d/ )[ 0 ]; // strip off seconds from the timestamp
|
||||
Wiki.prototype.increment_total_notes_count = function () {
|
||||
var total_notes_count = getElement( "total_notes_count" );
|
||||
if ( !total_notes_count ) return;
|
||||
replaceChildNodes( total_notes_count, parseInt( scrapeText( total_notes_count ) ) + 1 );
|
||||
}
|
||||
|
||||
Wiki.prototype.decrement_total_notes_count = function () {
|
||||
var total_notes_count = getElement( "total_notes_count" );
|
||||
if ( !total_notes_count ) return;
|
||||
replaceChildNodes( total_notes_count, parseInt( scrapeText( total_notes_count ) ) - 1 );
|
||||
}
|
||||
|
||||
Wiki.prototype.zero_total_notes_count = function () {
|
||||
var total_notes_count = getElement( "total_notes_count" );
|
||||
if ( !total_notes_count ) return;
|
||||
replaceChildNodes( total_notes_count, 0 );
|
||||
}
|
||||
|
||||
Wiki.prototype.toggle_editor_changes = function ( event, editor ) {
|
||||
|
|
|
@ -2,7 +2,7 @@ from Tags import Div, Span, H4, A
|
|||
|
||||
|
||||
class Link_area( Div ):
|
||||
def __init__( self, notebooks, notebook, parent_id ):
|
||||
def __init__( self, notebooks, notebook, total_notes_count, parent_id ):
|
||||
Div.__init__(
|
||||
self,
|
||||
Div(
|
||||
|
@ -14,6 +14,10 @@ class Link_area( Div ):
|
|||
id = u"all_notes_link",
|
||||
title = u"View a list of all notes in this notebook.",
|
||||
),
|
||||
Span(
|
||||
Span( total_notes_count, id = u"total_notes_count" ), u"total",
|
||||
class_ = u"small_text",
|
||||
),
|
||||
class_ = u"link_area_item",
|
||||
) or None,
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ class Main_page( Page ):
|
|||
login_url = None,
|
||||
logout_url = None,
|
||||
startup_notes = None,
|
||||
total_notes_count = None,
|
||||
note = None,
|
||||
note_read_write = True,
|
||||
):
|
||||
|
@ -76,7 +77,7 @@ class Main_page( Page ):
|
|||
Toolbar( hide_toolbar = not notebook.read_write ),
|
||||
id = u"toolbar_area",
|
||||
),
|
||||
Link_area( notebooks, notebook, parent_id ),
|
||||
Link_area( notebooks, notebook, total_notes_count, parent_id ),
|
||||
Div(
|
||||
Div(
|
||||
Div(
|
||||
|
|
Reference in New Issue