Fossil SCM

Add the "Last Change" activity report.

drh 2017-07-01 17:54 trunk
Commit b629647e820a2f111e2eb2b2cfb14279fffaeda554c11c1c4f645698fc195b41
2 files changed +1 +48 -2
--- src/setup.c
+++ src/setup.c
@@ -247,10 +247,11 @@
247247
@ <td>%h(zInfo)
248248
@ <td>%h(zDate?zDate:"")
249249
@ <td>%h(zExp?zExp:"")
250250
@ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"")
251251
@ </tr>
252
+ fossil_free(zAge);
252253
}
253254
@ </tbody></table>
254255
db_finalize(&s);
255256
output_table_sorting_javascript("userlist","nktxTTK",2);
256257
style_footer();
257258
--- src/setup.c
+++ src/setup.c
@@ -247,10 +247,11 @@
247 @ <td>%h(zInfo)
248 @ <td>%h(zDate?zDate:"")
249 @ <td>%h(zExp?zExp:"")
250 @ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"")
251 @ </tr>
 
252 }
253 @ </tbody></table>
254 db_finalize(&s);
255 output_table_sorting_javascript("userlist","nktxTTK",2);
256 style_footer();
257
--- src/setup.c
+++ src/setup.c
@@ -247,10 +247,11 @@
247 @ <td>%h(zInfo)
248 @ <td>%h(zDate?zDate:"")
249 @ <td>%h(zExp?zExp:"")
250 @ <td data-sortkey='%f(rATime)' style='white-space:nowrap'>%s(zAge?zAge:"")
251 @ </tr>
252 fossil_free(zAge);
253 }
254 @ </tbody></table>
255 db_finalize(&s);
256 output_table_sorting_javascript("userlist","nktxTTK",2);
257 style_footer();
258
+48 -2
--- src/statrep.c
+++ src/statrep.c
@@ -639,19 +639,61 @@
639639
"Average per active week: %d</div>",
640640
total, nAvg);
641641
}
642642
output_table_sorting_javascript("statsTable","tnx",-1);
643643
}
644
+
645
+
646
+/*
647
+** Generate a report that shows the most recent change for each user.
648
+*/
649
+static void stats_report_last_change(void){
650
+ Stmt s;
651
+ double rNow;
652
+
653
+ stats_report_init_view();
654
+ @ <table border=1 cellpadding=2 cellspacing=0
655
+ @ class='lastchngTable' id='lastchng'>
656
+ @ <thead><tr>
657
+ @ <th>Username<th>Total Changes<th>Last Change</tr></thead>
658
+ @ <tbody>
659
+ db_prepare(&s,
660
+ "SELECT coalesce(euser,user),"
661
+ " count(*),"
662
+ " max(mtime)"
663
+ " FROM v_reports"
664
+ " GROUP BY 1"
665
+ " ORDER BY 3 DESC"
666
+ );
667
+ rNow = db_double(0.0, "SELECT julianday('now');");
668
+ while( db_step(&s)==SQLITE_ROW ){
669
+ const char *zUser = db_column_text(&s, 0);
670
+ int cnt = db_column_int(&s, 1);
671
+ double rMTime = db_column_double(&s,2);
672
+ char *zAge = human_readable_age(rNow - rMTime);
673
+ @ <tr>
674
+ @ <td>%h(zUser)</a>
675
+ @ <td>%d(cnt)
676
+ @ <td data-sortkey='%f(rMTime)' style='white-space:nowrap'>%s(zAge?zAge:"")
677
+ @ </tr>
678
+ fossil_free(zAge);
679
+ }
680
+ @ </tbody></table>
681
+ db_finalize(&s);
682
+ output_table_sorting_javascript("userlist","tTK",3);
683
+}
684
+
644685
645686
/* Report types
646687
*/
647688
#define RPT_BYFILE 1
648689
#define RPT_BYMONTH 2
649690
#define RPT_BYUSER 3
650691
#define RPT_BYWEEK 4
651692
#define RPT_BYWEEKDAY 5
652693
#define RPT_BYYEAR 6
694
+#define RPT_LASTCHNG 7 /* Last change made for each user */
653695
#define RPT_NONE 0 /* None of the above */
654696
655697
/*
656698
** WEBPAGE: reports
657699
**
@@ -682,15 +724,16 @@
682724
const char *zName; /* Name of view= screen type */
683725
const char *zVal; /* Value of view= query parameter */
684726
int eType; /* Corresponding RPT_* define */
685727
} aViewType[] = {
686728
{ "File Changes","byfile", RPT_BYFILE },
729
+ { "Last Change", "lastchng", RPT_LASTCHNG },
687730
{ "By Month", "bymonth", RPT_BYMONTH },
688731
{ "By User", "byuser", RPT_BYUSER },
689732
{ "By Week", "byweek", RPT_BYWEEK },
690733
{ "By Weekday", "byweekday", RPT_BYWEEKDAY },
691
- { "By Year", "byyear", RPT_BYYEAR },
734
+ { "By Year", "byyear", RPT_BYYEAR },
692735
};
693736
static const char *const azType[] = {
694737
"a", "All Changes",
695738
"ci", "Check-ins",
696739
"g", "Tags",
@@ -722,11 +765,11 @@
722765
}
723766
if( eType!=RPT_BYFILE ){
724767
style_submenu_multichoice("type", count(azType)/2, azType, 0);
725768
}
726769
style_submenu_multichoice("view", nView/2, azView, 0);
727
- if( eType!=RPT_BYUSER ){
770
+ if( eType!=RPT_BYUSER && eType!=RPT_LASTCHNG ){
728771
style_submenu_sql("user","User:",
729772
"SELECT '', 'All Users' UNION ALL "
730773
"SELECT x, x FROM ("
731774
" SELECT DISTINCT trim(coalesce(euser,user)) AS x FROM event %s"
732775
" ORDER BY 1 COLLATE nocase) WHERE x!=''",
@@ -754,8 +797,11 @@
754797
stats_report_day_of_week(zUserName);
755798
break;
756799
case RPT_BYFILE:
757800
stats_report_by_file(zUserName);
758801
break;
802
+ case RPT_LASTCHNG:
803
+ stats_report_last_change();
804
+ break;
759805
}
760806
style_footer();
761807
}
762808
--- src/statrep.c
+++ src/statrep.c
@@ -639,19 +639,61 @@
639 "Average per active week: %d</div>",
640 total, nAvg);
641 }
642 output_table_sorting_javascript("statsTable","tnx",-1);
643 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
644
645 /* Report types
646 */
647 #define RPT_BYFILE 1
648 #define RPT_BYMONTH 2
649 #define RPT_BYUSER 3
650 #define RPT_BYWEEK 4
651 #define RPT_BYWEEKDAY 5
652 #define RPT_BYYEAR 6
 
653 #define RPT_NONE 0 /* None of the above */
654
655 /*
656 ** WEBPAGE: reports
657 **
@@ -682,15 +724,16 @@
682 const char *zName; /* Name of view= screen type */
683 const char *zVal; /* Value of view= query parameter */
684 int eType; /* Corresponding RPT_* define */
685 } aViewType[] = {
686 { "File Changes","byfile", RPT_BYFILE },
 
687 { "By Month", "bymonth", RPT_BYMONTH },
688 { "By User", "byuser", RPT_BYUSER },
689 { "By Week", "byweek", RPT_BYWEEK },
690 { "By Weekday", "byweekday", RPT_BYWEEKDAY },
691 { "By Year", "byyear", RPT_BYYEAR },
692 };
693 static const char *const azType[] = {
694 "a", "All Changes",
695 "ci", "Check-ins",
696 "g", "Tags",
@@ -722,11 +765,11 @@
722 }
723 if( eType!=RPT_BYFILE ){
724 style_submenu_multichoice("type", count(azType)/2, azType, 0);
725 }
726 style_submenu_multichoice("view", nView/2, azView, 0);
727 if( eType!=RPT_BYUSER ){
728 style_submenu_sql("user","User:",
729 "SELECT '', 'All Users' UNION ALL "
730 "SELECT x, x FROM ("
731 " SELECT DISTINCT trim(coalesce(euser,user)) AS x FROM event %s"
732 " ORDER BY 1 COLLATE nocase) WHERE x!=''",
@@ -754,8 +797,11 @@
754 stats_report_day_of_week(zUserName);
755 break;
756 case RPT_BYFILE:
757 stats_report_by_file(zUserName);
758 break;
 
 
 
759 }
760 style_footer();
761 }
762
--- src/statrep.c
+++ src/statrep.c
@@ -639,19 +639,61 @@
639 "Average per active week: %d</div>",
640 total, nAvg);
641 }
642 output_table_sorting_javascript("statsTable","tnx",-1);
643 }
644
645
646 /*
647 ** Generate a report that shows the most recent change for each user.
648 */
649 static void stats_report_last_change(void){
650 Stmt s;
651 double rNow;
652
653 stats_report_init_view();
654 @ <table border=1 cellpadding=2 cellspacing=0
655 @ class='lastchngTable' id='lastchng'>
656 @ <thead><tr>
657 @ <th>Username<th>Total Changes<th>Last Change</tr></thead>
658 @ <tbody>
659 db_prepare(&s,
660 "SELECT coalesce(euser,user),"
661 " count(*),"
662 " max(mtime)"
663 " FROM v_reports"
664 " GROUP BY 1"
665 " ORDER BY 3 DESC"
666 );
667 rNow = db_double(0.0, "SELECT julianday('now');");
668 while( db_step(&s)==SQLITE_ROW ){
669 const char *zUser = db_column_text(&s, 0);
670 int cnt = db_column_int(&s, 1);
671 double rMTime = db_column_double(&s,2);
672 char *zAge = human_readable_age(rNow - rMTime);
673 @ <tr>
674 @ <td>%h(zUser)</a>
675 @ <td>%d(cnt)
676 @ <td data-sortkey='%f(rMTime)' style='white-space:nowrap'>%s(zAge?zAge:"")
677 @ </tr>
678 fossil_free(zAge);
679 }
680 @ </tbody></table>
681 db_finalize(&s);
682 output_table_sorting_javascript("userlist","tTK",3);
683 }
684
685
686 /* Report types
687 */
688 #define RPT_BYFILE 1
689 #define RPT_BYMONTH 2
690 #define RPT_BYUSER 3
691 #define RPT_BYWEEK 4
692 #define RPT_BYWEEKDAY 5
693 #define RPT_BYYEAR 6
694 #define RPT_LASTCHNG 7 /* Last change made for each user */
695 #define RPT_NONE 0 /* None of the above */
696
697 /*
698 ** WEBPAGE: reports
699 **
@@ -682,15 +724,16 @@
724 const char *zName; /* Name of view= screen type */
725 const char *zVal; /* Value of view= query parameter */
726 int eType; /* Corresponding RPT_* define */
727 } aViewType[] = {
728 { "File Changes","byfile", RPT_BYFILE },
729 { "Last Change", "lastchng", RPT_LASTCHNG },
730 { "By Month", "bymonth", RPT_BYMONTH },
731 { "By User", "byuser", RPT_BYUSER },
732 { "By Week", "byweek", RPT_BYWEEK },
733 { "By Weekday", "byweekday", RPT_BYWEEKDAY },
734 { "By Year", "byyear", RPT_BYYEAR },
735 };
736 static const char *const azType[] = {
737 "a", "All Changes",
738 "ci", "Check-ins",
739 "g", "Tags",
@@ -722,11 +765,11 @@
765 }
766 if( eType!=RPT_BYFILE ){
767 style_submenu_multichoice("type", count(azType)/2, azType, 0);
768 }
769 style_submenu_multichoice("view", nView/2, azView, 0);
770 if( eType!=RPT_BYUSER && eType!=RPT_LASTCHNG ){
771 style_submenu_sql("user","User:",
772 "SELECT '', 'All Users' UNION ALL "
773 "SELECT x, x FROM ("
774 " SELECT DISTINCT trim(coalesce(euser,user)) AS x FROM event %s"
775 " ORDER BY 1 COLLATE nocase) WHERE x!=''",
@@ -754,8 +797,11 @@
797 stats_report_day_of_week(zUserName);
798 break;
799 case RPT_BYFILE:
800 stats_report_by_file(zUserName);
801 break;
802 case RPT_LASTCHNG:
803 stats_report_last_change();
804 break;
805 }
806 style_footer();
807 }
808

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button