| | @@ -60,11 +60,11 @@ |
| 60 | 60 | ** 0. UUID |
| 61 | 61 | ** 1. Date/Time |
| 62 | 62 | ** 2. Comment string |
| 63 | 63 | ** 3. User |
| 64 | 64 | */ |
| 65 | | -void www_print_timeline(Stmt *pQuery){ |
| 65 | +void www_print_timeline(Stmt *pQuery, char *zLastDate){ |
| 66 | 66 | char zPrevDate[20]; |
| 67 | 67 | zPrevDate[0] = 0; |
| 68 | 68 | @ <table cellspacing=0 border=0 cellpadding=0> |
| 69 | 69 | while( db_step(pQuery)==SQLITE_ROW ){ |
| 70 | 70 | const char *zDate = db_column_text(pQuery, 1); |
| | @@ -82,10 +82,13 @@ |
| 82 | 82 | @ <tr><td valign="top">%s(&zDate[11])</td> |
| 83 | 83 | @ <td width="20"></td> |
| 84 | 84 | @ <td valign="top" align="left"> |
| 85 | 85 | hyperlink_to_uuid(db_column_text(pQuery,0)); |
| 86 | 86 | @ %h(db_column_text(pQuery,2)) (by %h(db_column_text(pQuery,3)))</td> |
| 87 | + if( zLastDate ){ |
| 88 | + strcpy(zLastDate, zDate); |
| 89 | + } |
| 87 | 90 | } |
| 88 | 91 | @ </table> |
| 89 | 92 | } |
| 90 | 93 | |
| 91 | 94 | |
| | @@ -93,27 +96,64 @@ |
| 93 | 96 | /* |
| 94 | 97 | ** WEBPAGE: timeline |
| 95 | 98 | */ |
| 96 | 99 | void page_timeline(void){ |
| 97 | 100 | Stmt q; |
| 101 | + char *zSQL; |
| 102 | + char zDate[100]; |
| 103 | + const char *zStart = P("d"); |
| 104 | + int nEntry = atoi(PD("n","25")); |
| 98 | 105 | |
| 99 | 106 | /* To view the timeline, must have permission to read project data. |
| 100 | 107 | */ |
| 101 | 108 | login_check_credentials(); |
| 102 | 109 | if( !g.okRead ){ login_needed(); return; } |
| 103 | 110 | |
| 104 | 111 | style_header("Timeline"); |
| 105 | | - db_prepare(&q, |
| 112 | + if( !g.okHistory && |
| 113 | + db_exists("SELECT 1 FROM user" |
| 114 | + " WHERE login='anonymous'" |
| 115 | + " AND cap LIKE '%%h%%'") ){ |
| 116 | + @ <p><b>Note:</b> You will be able to see much more timeline |
| 117 | + @ information if <a href="%s(g.zBaseURL)/login">login</a>.</p> |
| 118 | + } |
| 119 | + zSQL = mprintf( |
| 106 | 120 | "SELECT uuid, datetime(event.mtime,'localtime'), comment, user" |
| 107 | 121 | " FROM event, blob" |
| 108 | 122 | " WHERE event.type='ci' AND blob.rid=event.objid" |
| 109 | | - " ORDER BY event.mtime DESC" |
| 110 | 123 | ); |
| 111 | | - www_print_timeline(&q); |
| 124 | + if( zStart ){ |
| 125 | + while( isspace(zStart[0]) ){ zStart++; } |
| 126 | + if( zStart[0] ){ |
| 127 | + zSQL = mprintf("%z AND event.mtime<=julianday(%Q, 'localtime')", |
| 128 | + zSQL, zStart); |
| 129 | + } |
| 130 | + } |
| 131 | + zSQL = mprintf("%z ORDER BY event.mtime DESC LIMIT %d", zSQL, nEntry); |
| 132 | + db_prepare(&q, zSQL); |
| 133 | + free(zSQL); |
| 134 | + www_print_timeline(&q, zDate); |
| 112 | 135 | db_finalize(&q); |
| 136 | + if( zStart==0 ){ |
| 137 | + zStart = zDate; |
| 138 | + } |
| 139 | + @ <hr> |
| 140 | + @ <form method="GET" action="%s(g.zBaseURL)/timeline"> |
| 141 | + @ Start Date: |
| 142 | + @ <input type="text" size="30" value="%h(zStart)" name="d"> |
| 143 | + @ Number Of Entries: |
| 144 | + @ <input type="text" size="4" value="%d(nEntry)" name="n"> |
| 145 | + @ <br><input type="submit" value="Submit"> |
| 146 | + @ </form> |
| 147 | + @ <form method="GET" action="%s(g.zBaseURL)/timeline"> |
| 148 | + @ <input type="hidden" value="%h(zDate)" name="d"> |
| 149 | + @ <input type="hidden" value="%d(nEntry)" name="n"> |
| 150 | + @ <input type="submit" value="Next %d(nEntry) Rows"> |
| 151 | + @ </form> |
| 113 | 152 | style_footer(); |
| 114 | 153 | } |
| 154 | + |
| 115 | 155 | /* |
| 116 | 156 | ** The input query q selects various records. Print a human-readable |
| 117 | 157 | ** summary of those records. |
| 118 | 158 | ** |
| 119 | 159 | ** Limit the number of entries printed to nLine. |
| 120 | 160 | |