Fossil SCM

New "By Day" report format.

drh 2026-06-30 12:59 UTC trunk
Commit 31da5e3db7b8e428a08e7341503a9de7d65703b1f54bdfff084589e7db345836
2 files changed +110 -3 +7 -1
+110 -3
--- src/statrep.c
+++ src/statrep.c
@@ -663,12 +663,14 @@
663663
db_finalize(&query);
664664
}
665665
666666
667667
/*
668
-** Helper for stats_report_by_month_year(), which generates a list of
669
-** week numbers. The "y" query parameter is the year in format YYYY.
668
+** Generator for the by-week report (RPT_BYWEEK).
669
+**
670
+** The "y" query parameter is the year in format YYYY.
671
+**
670672
** If zUserName is not NULL then the report is restricted to events
671673
** created by the named user account.
672674
*/
673675
static void stats_report_year_weeks(const char *zUserName){
674676
const char *zYear = P("y"); /* Year for which report shown */
@@ -788,10 +790,109 @@
788790
"Average per active week: %d</div>",
789791
total, nAvg);
790792
}
791793
}
792794
795
+/*
796
+** Generator for the by-day report (RPT_BYDAY).
797
+**
798
+** The "y" query parameter is the year in format YYYY.
799
+**
800
+** If zUserName is not NULL then the report is restricted to events
801
+** created by the named user account.
802
+*/
803
+static void stats_report_year_days(const char *zUserName){
804
+ const char *zYear = P("y"); /* Year for which report shown */
805
+ Stmt q;
806
+ int nMaxEvents = 1; /* max number of events for
807
+ all rows. */
808
+ int iterations = 0; /* # of active time periods. */
809
+ int rowCount = 0;
810
+ int total = 0;
811
+
812
+ stats_report_init_view();
813
+ style_submenu_sql("y", "Year:",
814
+ "WITH RECURSIVE a(b) AS ("
815
+ " SELECT substr(date('now'),1,4) UNION ALL"
816
+ " SELECT b-1 FROM a"
817
+ " WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)"
818
+ ") SELECT b, b FROM a ORDER BY b DESC");
819
+ if( zYear==0 || strlen(zYear)!=4 ){
820
+ zYear = db_text("1970","SELECT substr(date('now'),1,4);");
821
+ }
822
+ cgi_printf("<br>\n");
823
+ db_prepare(&q,
824
+ "SELECT DISTINCT strftime('%%w',mtime) AS wkday, "
825
+ " date(mtime) AS date,"
826
+ " count(*) AS n "
827
+ " FROM v_reports"
828
+ " WHERE %Q=substr(date(mtime),1,4) "
829
+ " AND mtime < current_timestamp "
830
+ " AND ifnull(coalesce(euser,user,'')=%Q,1)"
831
+ " GROUP BY date ORDER BY date DESC", zYear, zUserName);
832
+ @ <h1>Timeline events (%h(stats_report_label_for_type()))
833
+ @ for each day of %h(zYear)
834
+ if( zUserName ){
835
+ @ for user %h(zUserName)
836
+ }
837
+ @ </h1>
838
+ style_table_sorter();
839
+ cgi_printf("<table class='statistics-report-table-events sortable' "
840
+ "border='0' cellpadding='2' width='100%%' "
841
+ "cellspacing='0' data-column-types='tnx' data-init-sort='0'>\n");
842
+ cgi_printf("<thead><tr>"
843
+ "<th>Date</th>"
844
+ "<th>Events</th>"
845
+ "<th width='90%%'><!-- relative commits graph --></th>"
846
+ "</tr></thead>\n"
847
+ "<tbody>\n");
848
+ while( SQLITE_ROW == db_step(&q) ){
849
+ int nCount = db_column_int(&q, 2);
850
+ if(nCount>nMaxEvents){
851
+ nMaxEvents = nCount;
852
+ }
853
+ ++iterations;
854
+ }
855
+ db_reset(&q);
856
+ while( SQLITE_ROW == db_step(&q) ){
857
+ static const char *azDayName[] = {
858
+ "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"
859
+ };
860
+ int dayOfWeek = db_column_int(&q,0);
861
+ const char *zDate = db_column_text(&q,1);
862
+ const int nCount = db_column_int(&q,2);
863
+ int nSize = (nCount>0 && nMaxEvents>0)
864
+ ? (int)(100 * nCount / nMaxEvents)
865
+ : 0;
866
+ if(!nSize) nSize = 1;
867
+ total += nCount;
868
+ cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
869
+ cgi_printf("<td><a href='%R/timeline?ymd=%s&y=%s",
870
+ zDate, statsReportTimelineYFlag);
871
+ if( zUserName ){
872
+ cgi_printf("&u=%t",zUserName);
873
+ }
874
+ cgi_printf("'>%s&nbsp;(%s)</a></td>",zDate, azDayName[dayOfWeek]);
875
+
876
+ cgi_printf("<td>%d</td>",nCount);
877
+ cgi_printf("<td style='white-space: nowrap;'>");
878
+ if( nCount ){
879
+ @ <div class='statistics-report-graph-line' \
880
+ @ style='width:%d(nSize)%%;'>&nbsp;</div> \
881
+ }
882
+ cgi_printf("</td></tr>\n");
883
+ }
884
+ db_finalize(&q);
885
+ cgi_printf("</tbody></table>");
886
+ if(total){
887
+ int nAvg = iterations ? (total/iterations) : 0;
888
+ cgi_printf("<br><div>Total events: %d<br>"
889
+ "Average per active day: %d</div>",
890
+ total, nAvg);
891
+ }
892
+}
893
+
793894
794895
/*
795896
** Generate a report that shows the most recent change for each user.
796897
*/
797898
static void stats_report_last_change(void){
@@ -843,10 +944,11 @@
843944
#define RPT_BYWEEK 4
844945
#define RPT_BYWEEKDAY 5
845946
#define RPT_BYYEAR 6
846947
#define RPT_LASTCHNG 7 /* Last change made for each user */
847948
#define RPT_BYHOUR 8 /* hour-of-day */
949
+#define RPT_BYDAY 9
848950
#define RPT_NONE 0 /* None of the above */
849951
850952
/*
851953
** WEBPAGE: reports
852954
**
@@ -856,10 +958,11 @@
856958
**
857959
** view=REPORT_NAME Valid REPORT_NAME values:
858960
** * byyear
859961
** * bymonth
860962
** * byweek
963
+** * byday
861964
** * byweekday
862965
** * byhour
863966
** * byuser
864967
** * byfile
865968
** * lastchng
@@ -889,11 +992,11 @@
889992
void stats_report_page(){
890993
const char *zView = P("view"); /* Which view/report to show. */
891994
int eType = RPT_NONE; /* Numeric code for view/report to show */
892995
int i; /* Loop counter */
893996
const char *zUserName; /* Name of user */
894
- const char *azView[16]; /* Drop-down menu of view types */
997
+ const char *azView[24]; /* Drop-down menu of view types */
895998
static const struct {
896999
const char *zName; /* Name of view= screen type */
8971000
const char *zVal; /* Value of view= query parameter */
8981001
int eType; /* Corresponding RPT_* define */
8991002
} aViewType[] = {
@@ -900,10 +1003,11 @@
9001003
{ "File Changes","byfile", RPT_BYFILE },
9011004
{ "Last Change", "lastchng", RPT_LASTCHNG },
9021005
{ "By Month", "bymonth", RPT_BYMONTH },
9031006
{ "By User", "byuser", RPT_BYUSER },
9041007
{ "By Week", "byweek", RPT_BYWEEK },
1008
+ { "By Day", "byday", RPT_BYDAY },
9051009
{ "By Weekday", "byweekday", RPT_BYWEEKDAY },
9061010
{ "By Year", "byyear", RPT_BYYEAR },
9071011
{ "By Hour", "byhour", RPT_BYHOUR },
9081012
};
9091013
static const char *const azType[] = {
@@ -965,10 +1069,13 @@
9651069
stats_report_by_month_year(1, zUserName);
9661070
break;
9671071
case RPT_BYWEEK:
9681072
stats_report_year_weeks(zUserName);
9691073
break;
1074
+ case RPT_BYDAY:
1075
+ stats_report_year_days(zUserName);
1076
+ break;
9701077
default:
9711078
case RPT_BYUSER:
9721079
stats_report_by_user();
9731080
break;
9741081
case RPT_BYWEEKDAY:
9751082
--- src/statrep.c
+++ src/statrep.c
@@ -663,12 +663,14 @@
663 db_finalize(&query);
664 }
665
666
667 /*
668 ** Helper for stats_report_by_month_year(), which generates a list of
669 ** week numbers. The "y" query parameter is the year in format YYYY.
 
 
670 ** If zUserName is not NULL then the report is restricted to events
671 ** created by the named user account.
672 */
673 static void stats_report_year_weeks(const char *zUserName){
674 const char *zYear = P("y"); /* Year for which report shown */
@@ -788,10 +790,109 @@
788 "Average per active week: %d</div>",
789 total, nAvg);
790 }
791 }
792
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
794 /*
795 ** Generate a report that shows the most recent change for each user.
796 */
797 static void stats_report_last_change(void){
@@ -843,10 +944,11 @@
843 #define RPT_BYWEEK 4
844 #define RPT_BYWEEKDAY 5
845 #define RPT_BYYEAR 6
846 #define RPT_LASTCHNG 7 /* Last change made for each user */
847 #define RPT_BYHOUR 8 /* hour-of-day */
 
848 #define RPT_NONE 0 /* None of the above */
849
850 /*
851 ** WEBPAGE: reports
852 **
@@ -856,10 +958,11 @@
856 **
857 ** view=REPORT_NAME Valid REPORT_NAME values:
858 ** * byyear
859 ** * bymonth
860 ** * byweek
 
861 ** * byweekday
862 ** * byhour
863 ** * byuser
864 ** * byfile
865 ** * lastchng
@@ -889,11 +992,11 @@
889 void stats_report_page(){
890 const char *zView = P("view"); /* Which view/report to show. */
891 int eType = RPT_NONE; /* Numeric code for view/report to show */
892 int i; /* Loop counter */
893 const char *zUserName; /* Name of user */
894 const char *azView[16]; /* Drop-down menu of view types */
895 static const struct {
896 const char *zName; /* Name of view= screen type */
897 const char *zVal; /* Value of view= query parameter */
898 int eType; /* Corresponding RPT_* define */
899 } aViewType[] = {
@@ -900,10 +1003,11 @@
900 { "File Changes","byfile", RPT_BYFILE },
901 { "Last Change", "lastchng", RPT_LASTCHNG },
902 { "By Month", "bymonth", RPT_BYMONTH },
903 { "By User", "byuser", RPT_BYUSER },
904 { "By Week", "byweek", RPT_BYWEEK },
 
905 { "By Weekday", "byweekday", RPT_BYWEEKDAY },
906 { "By Year", "byyear", RPT_BYYEAR },
907 { "By Hour", "byhour", RPT_BYHOUR },
908 };
909 static const char *const azType[] = {
@@ -965,10 +1069,13 @@
965 stats_report_by_month_year(1, zUserName);
966 break;
967 case RPT_BYWEEK:
968 stats_report_year_weeks(zUserName);
969 break;
 
 
 
970 default:
971 case RPT_BYUSER:
972 stats_report_by_user();
973 break;
974 case RPT_BYWEEKDAY:
975
--- src/statrep.c
+++ src/statrep.c
@@ -663,12 +663,14 @@
663 db_finalize(&query);
664 }
665
666
667 /*
668 ** Generator for the by-week report (RPT_BYWEEK).
669 **
670 ** The "y" query parameter is the year in format YYYY.
671 **
672 ** If zUserName is not NULL then the report is restricted to events
673 ** created by the named user account.
674 */
675 static void stats_report_year_weeks(const char *zUserName){
676 const char *zYear = P("y"); /* Year for which report shown */
@@ -788,10 +790,109 @@
790 "Average per active week: %d</div>",
791 total, nAvg);
792 }
793 }
794
795 /*
796 ** Generator for the by-day report (RPT_BYDAY).
797 **
798 ** The "y" query parameter is the year in format YYYY.
799 **
800 ** If zUserName is not NULL then the report is restricted to events
801 ** created by the named user account.
802 */
803 static void stats_report_year_days(const char *zUserName){
804 const char *zYear = P("y"); /* Year for which report shown */
805 Stmt q;
806 int nMaxEvents = 1; /* max number of events for
807 all rows. */
808 int iterations = 0; /* # of active time periods. */
809 int rowCount = 0;
810 int total = 0;
811
812 stats_report_init_view();
813 style_submenu_sql("y", "Year:",
814 "WITH RECURSIVE a(b) AS ("
815 " SELECT substr(date('now'),1,4) UNION ALL"
816 " SELECT b-1 FROM a"
817 " WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)"
818 ") SELECT b, b FROM a ORDER BY b DESC");
819 if( zYear==0 || strlen(zYear)!=4 ){
820 zYear = db_text("1970","SELECT substr(date('now'),1,4);");
821 }
822 cgi_printf("<br>\n");
823 db_prepare(&q,
824 "SELECT DISTINCT strftime('%%w',mtime) AS wkday, "
825 " date(mtime) AS date,"
826 " count(*) AS n "
827 " FROM v_reports"
828 " WHERE %Q=substr(date(mtime),1,4) "
829 " AND mtime < current_timestamp "
830 " AND ifnull(coalesce(euser,user,'')=%Q,1)"
831 " GROUP BY date ORDER BY date DESC", zYear, zUserName);
832 @ <h1>Timeline events (%h(stats_report_label_for_type()))
833 @ for each day of %h(zYear)
834 if( zUserName ){
835 @ for user %h(zUserName)
836 }
837 @ </h1>
838 style_table_sorter();
839 cgi_printf("<table class='statistics-report-table-events sortable' "
840 "border='0' cellpadding='2' width='100%%' "
841 "cellspacing='0' data-column-types='tnx' data-init-sort='0'>\n");
842 cgi_printf("<thead><tr>"
843 "<th>Date</th>"
844 "<th>Events</th>"
845 "<th width='90%%'><!-- relative commits graph --></th>"
846 "</tr></thead>\n"
847 "<tbody>\n");
848 while( SQLITE_ROW == db_step(&q) ){
849 int nCount = db_column_int(&q, 2);
850 if(nCount>nMaxEvents){
851 nMaxEvents = nCount;
852 }
853 ++iterations;
854 }
855 db_reset(&q);
856 while( SQLITE_ROW == db_step(&q) ){
857 static const char *azDayName[] = {
858 "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"
859 };
860 int dayOfWeek = db_column_int(&q,0);
861 const char *zDate = db_column_text(&q,1);
862 const int nCount = db_column_int(&q,2);
863 int nSize = (nCount>0 && nMaxEvents>0)
864 ? (int)(100 * nCount / nMaxEvents)
865 : 0;
866 if(!nSize) nSize = 1;
867 total += nCount;
868 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
869 cgi_printf("<td><a href='%R/timeline?ymd=%s&y=%s",
870 zDate, statsReportTimelineYFlag);
871 if( zUserName ){
872 cgi_printf("&u=%t",zUserName);
873 }
874 cgi_printf("'>%s&nbsp;(%s)</a></td>",zDate, azDayName[dayOfWeek]);
875
876 cgi_printf("<td>%d</td>",nCount);
877 cgi_printf("<td style='white-space: nowrap;'>");
878 if( nCount ){
879 @ <div class='statistics-report-graph-line' \
880 @ style='width:%d(nSize)%%;'>&nbsp;</div> \
881 }
882 cgi_printf("</td></tr>\n");
883 }
884 db_finalize(&q);
885 cgi_printf("</tbody></table>");
886 if(total){
887 int nAvg = iterations ? (total/iterations) : 0;
888 cgi_printf("<br><div>Total events: %d<br>"
889 "Average per active day: %d</div>",
890 total, nAvg);
891 }
892 }
893
894
895 /*
896 ** Generate a report that shows the most recent change for each user.
897 */
898 static void stats_report_last_change(void){
@@ -843,10 +944,11 @@
944 #define RPT_BYWEEK 4
945 #define RPT_BYWEEKDAY 5
946 #define RPT_BYYEAR 6
947 #define RPT_LASTCHNG 7 /* Last change made for each user */
948 #define RPT_BYHOUR 8 /* hour-of-day */
949 #define RPT_BYDAY 9
950 #define RPT_NONE 0 /* None of the above */
951
952 /*
953 ** WEBPAGE: reports
954 **
@@ -856,10 +958,11 @@
958 **
959 ** view=REPORT_NAME Valid REPORT_NAME values:
960 ** * byyear
961 ** * bymonth
962 ** * byweek
963 ** * byday
964 ** * byweekday
965 ** * byhour
966 ** * byuser
967 ** * byfile
968 ** * lastchng
@@ -889,11 +992,11 @@
992 void stats_report_page(){
993 const char *zView = P("view"); /* Which view/report to show. */
994 int eType = RPT_NONE; /* Numeric code for view/report to show */
995 int i; /* Loop counter */
996 const char *zUserName; /* Name of user */
997 const char *azView[24]; /* Drop-down menu of view types */
998 static const struct {
999 const char *zName; /* Name of view= screen type */
1000 const char *zVal; /* Value of view= query parameter */
1001 int eType; /* Corresponding RPT_* define */
1002 } aViewType[] = {
@@ -900,10 +1003,11 @@
1003 { "File Changes","byfile", RPT_BYFILE },
1004 { "Last Change", "lastchng", RPT_LASTCHNG },
1005 { "By Month", "bymonth", RPT_BYMONTH },
1006 { "By User", "byuser", RPT_BYUSER },
1007 { "By Week", "byweek", RPT_BYWEEK },
1008 { "By Day", "byday", RPT_BYDAY },
1009 { "By Weekday", "byweekday", RPT_BYWEEKDAY },
1010 { "By Year", "byyear", RPT_BYYEAR },
1011 { "By Hour", "byhour", RPT_BYHOUR },
1012 };
1013 static const char *const azType[] = {
@@ -965,10 +1069,13 @@
1069 stats_report_by_month_year(1, zUserName);
1070 break;
1071 case RPT_BYWEEK:
1072 stats_report_year_weeks(zUserName);
1073 break;
1074 case RPT_BYDAY:
1075 stats_report_year_days(zUserName);
1076 break;
1077 default:
1078 case RPT_BYUSER:
1079 stats_report_by_user();
1080 break;
1081 case RPT_BYWEEKDAY:
1082
+7 -1
--- src/timeline.c
+++ src/timeline.c
@@ -1720,11 +1720,11 @@
17201720
** mionly Show related parents but not related children.
17211721
** nowiki Do not show wiki associated with branch or tag
17221722
** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob",
17231723
** "like", or "regexp".
17241724
** u=USER Only show items associated with USER
1725
-** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', or 'all'.
1725
+** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', 'h', or 'all'.
17261726
** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar",
17271727
** x: "Classic".
17281728
** advm Use the "Advanced" or "Busy" menu design.
17291729
** ng No Graph.
17301730
** ncp Omit cherrypick merges
@@ -2944,10 +2944,11 @@
29442944
|| (zType[0]=='n' && !g.perm.RdTkt)
29452945
|| (zType[0]=='e' && !g.perm.RdWiki)
29462946
|| (zType[0]=='c' && !g.perm.Read)
29472947
|| (zType[0]=='g' && !g.perm.Read)
29482948
|| (zType[0]=='f' && !g.perm.RdForum)
2949
+ || (zType[0]=='h' && !g.perm.RdForum)
29492950
){
29502951
zType = "all";
29512952
}
29522953
if( zType[0]=='a' ){
29532954
if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
@@ -2973,10 +2974,13 @@
29732974
}
29742975
}else{ /* zType!="all" */
29752976
if( zType[0]=='n' ){
29762977
blob_append_sql(&cond,
29772978
" AND event.type='t' AND event.comment GLOB 'New ticket*'");
2979
+ }else if( zType[0]=='h' ){
2980
+ blob_append_sql(&cond,
2981
+ " AND event.type='f' AND event.comment GLOB 'Post:*'");
29782982
}else{
29792983
blob_append_sql(&cond, " AND event.type=%Q", zType);
29802984
}
29812985
if( zType[0]=='c' ){
29822986
zEType = "check-in";
@@ -2990,10 +2994,12 @@
29902994
zEType = "technical note";
29912995
}else if( zType[0]=='g' ){
29922996
zEType = "tag";
29932997
}else if( zType[0]=='f' ){
29942998
zEType = "forum post";
2999
+ }else if( zType[0]=='h' ){
3000
+ zEType = "new forum thread";
29953001
}
29963002
}
29973003
if( zUser ){
29983004
int n = db_int(0,"SELECT count(*) FROM event"
29993005
" WHERE user=%Q OR euser=%Q", zUser, zUser);
30003006
--- src/timeline.c
+++ src/timeline.c
@@ -1720,11 +1720,11 @@
1720 ** mionly Show related parents but not related children.
1721 ** nowiki Do not show wiki associated with branch or tag
1722 ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob",
1723 ** "like", or "regexp".
1724 ** u=USER Only show items associated with USER
1725 ** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', or 'all'.
1726 ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar",
1727 ** x: "Classic".
1728 ** advm Use the "Advanced" or "Busy" menu design.
1729 ** ng No Graph.
1730 ** ncp Omit cherrypick merges
@@ -2944,10 +2944,11 @@
2944 || (zType[0]=='n' && !g.perm.RdTkt)
2945 || (zType[0]=='e' && !g.perm.RdWiki)
2946 || (zType[0]=='c' && !g.perm.Read)
2947 || (zType[0]=='g' && !g.perm.Read)
2948 || (zType[0]=='f' && !g.perm.RdForum)
 
2949 ){
2950 zType = "all";
2951 }
2952 if( zType[0]=='a' ){
2953 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
@@ -2973,10 +2974,13 @@
2973 }
2974 }else{ /* zType!="all" */
2975 if( zType[0]=='n' ){
2976 blob_append_sql(&cond,
2977 " AND event.type='t' AND event.comment GLOB 'New ticket*'");
 
 
 
2978 }else{
2979 blob_append_sql(&cond, " AND event.type=%Q", zType);
2980 }
2981 if( zType[0]=='c' ){
2982 zEType = "check-in";
@@ -2990,10 +2994,12 @@
2990 zEType = "technical note";
2991 }else if( zType[0]=='g' ){
2992 zEType = "tag";
2993 }else if( zType[0]=='f' ){
2994 zEType = "forum post";
 
 
2995 }
2996 }
2997 if( zUser ){
2998 int n = db_int(0,"SELECT count(*) FROM event"
2999 " WHERE user=%Q OR euser=%Q", zUser, zUser);
3000
--- src/timeline.c
+++ src/timeline.c
@@ -1720,11 +1720,11 @@
1720 ** mionly Show related parents but not related children.
1721 ** nowiki Do not show wiki associated with branch or tag
1722 ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob",
1723 ** "like", or "regexp".
1724 ** u=USER Only show items associated with USER
1725 ** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', 'h', or 'all'.
1726 ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar",
1727 ** x: "Classic".
1728 ** advm Use the "Advanced" or "Busy" menu design.
1729 ** ng No Graph.
1730 ** ncp Omit cherrypick merges
@@ -2944,10 +2944,11 @@
2944 || (zType[0]=='n' && !g.perm.RdTkt)
2945 || (zType[0]=='e' && !g.perm.RdWiki)
2946 || (zType[0]=='c' && !g.perm.Read)
2947 || (zType[0]=='g' && !g.perm.Read)
2948 || (zType[0]=='f' && !g.perm.RdForum)
2949 || (zType[0]=='h' && !g.perm.RdForum)
2950 ){
2951 zType = "all";
2952 }
2953 if( zType[0]=='a' ){
2954 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
@@ -2973,10 +2974,13 @@
2974 }
2975 }else{ /* zType!="all" */
2976 if( zType[0]=='n' ){
2977 blob_append_sql(&cond,
2978 " AND event.type='t' AND event.comment GLOB 'New ticket*'");
2979 }else if( zType[0]=='h' ){
2980 blob_append_sql(&cond,
2981 " AND event.type='f' AND event.comment GLOB 'Post:*'");
2982 }else{
2983 blob_append_sql(&cond, " AND event.type=%Q", zType);
2984 }
2985 if( zType[0]=='c' ){
2986 zEType = "check-in";
@@ -2990,10 +2994,12 @@
2994 zEType = "technical note";
2995 }else if( zType[0]=='g' ){
2996 zEType = "tag";
2997 }else if( zType[0]=='f' ){
2998 zEType = "forum post";
2999 }else if( zType[0]=='h' ){
3000 zEType = "new forum thread";
3001 }
3002 }
3003 if( zUser ){
3004 int n = db_int(0,"SELECT count(*) FROM event"
3005 " WHERE user=%Q OR euser=%Q", zUser, zUser);
3006

Keyboard Shortcuts

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