Fossil SCM

Add ticket-search-empty-report-number setting to optionally show a report if the ticket search page query is blank

kevgrig 2021-07-10 05:47 trunk
Commit 714ce73d38ef9d1ba46996e112209ed9c789a55e979b0949b3928d8a997277c7
+52 -23
--- src/report.c
+++ src/report.c
@@ -27,10 +27,19 @@
2727
2828
#ifndef SQLITE_RECURSIVE
2929
# define SQLITE_RECURSIVE 33
3030
#endif
3131
32
+/* Settings that can be used to control ticket reports */
33
+/*
34
+** SETTING: ticket-search-empty-report-number width=10 default=0
35
+**
36
+** If this setting has an integer value of N, then when the ticket
37
+** search page query is blank, the report with rn=N is shown.
38
+** If N is zero, then no report is shown.
39
+*/
40
+
3241
/*
3342
** WEBPAGE: reportlist
3443
**
3544
** Main menu for Tickets.
3645
*/
@@ -982,12 +991,23 @@
982991
** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
983992
** then the output consists of lines of tab-separated fields instead of
984993
** an HTML table.
985994
*/
986995
void rptview_page(void){
996
+ rptview_page_content(0, 1, 1);
997
+}
998
+
999
+/*
1000
+** Render a report.
1001
+*/
1002
+void rptview_page_content(
1003
+ int rn, /* Report number. If 0, retrieve from rn query parameter. */
1004
+ int pageWrap, /* If true, render full page; otherwise, just the report */
1005
+ int redirectMissing /* If true and report not found, go to reportlist */
1006
+){
9871007
int count = 0;
988
- int rn, rc;
1008
+ int rc;
9891009
char *zSql;
9901010
char *zTitle;
9911011
char *zOwner;
9921012
char *zClrKey;
9931013
int tabs;
@@ -996,13 +1016,16 @@
9961016
char *zErr2 = 0;
9971017
9981018
login_check_credentials();
9991019
if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
10001020
tabs = P("tablist")!=0;
1021
+ if ( rn==0 ) {
1022
+ rn = atoi(PD("rn","0"));
1023
+ }
10011024
db_prepare(&q,
10021025
"SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE rn=%d",
1003
- atoi(PD("rn","0")));
1026
+ rn);
10041027
rc = db_step(&q);
10051028
if( rc!=SQLITE_ROW ){
10061029
db_finalize(&q);
10071030
db_prepare(&q,
10081031
"SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE title GLOB %Q",
@@ -1009,11 +1032,13 @@
10091032
P("title"));
10101033
rc = db_step(&q);
10111034
}
10121035
if( rc!=SQLITE_ROW ){
10131036
db_finalize(&q);
1014
- cgi_redirect("reportlist");
1037
+ if (redirectMissing) {
1038
+ cgi_redirect("reportlist");
1039
+ }
10151040
return;
10161041
}
10171042
zTitle = db_column_malloc(&q, 0);
10181043
zSql = db_column_malloc(&q, 1);
10191044
zOwner = db_column_malloc(&q, 2);
@@ -1041,29 +1066,31 @@
10411066
struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
10421067
const char *zQS = PD("QUERY_STRING","");
10431068
10441069
db_multi_exec("PRAGMA empty_result_callbacks=ON");
10451070
style_set_current_feature("report");
1046
- /* style_finish_page() should provide escaping via %h formatting */
1047
- if( zQS[0] ){
1048
- style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
1049
- style_submenu_element("Reports","%R/reportlist?%s",zQS);
1050
- } else {
1051
- style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1052
- style_submenu_element("Reports","%R/reportlist");
1053
- }
1054
- if( g.perm.Admin
1055
- || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1056
- style_submenu_element("Edit", "rptedit?rn=%d", rn);
1057
- }
1058
- if( g.perm.TktFmt ){
1059
- style_submenu_element("SQL", "rptsql?rn=%d",rn);
1060
- }
1061
- if( g.perm.NewTkt ){
1062
- style_submenu_element("New Ticket", "%R/tktnew");
1063
- }
1064
- style_header("%s", zTitle);
1071
+ if ( pageWrap ) {
1072
+ /* style_finish_page() should provide escaping via %h formatting */
1073
+ if( zQS[0] ){
1074
+ style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
1075
+ style_submenu_element("Reports","%R/reportlist?%s",zQS);
1076
+ } else {
1077
+ style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1078
+ style_submenu_element("Reports","%R/reportlist");
1079
+ }
1080
+ if( g.perm.Admin
1081
+ || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1082
+ style_submenu_element("Edit", "rptedit?rn=%d", rn);
1083
+ }
1084
+ if( g.perm.TktFmt ){
1085
+ style_submenu_element("SQL", "rptsql?rn=%d",rn);
1086
+ }
1087
+ if( g.perm.NewTkt ){
1088
+ style_submenu_element("New Ticket", "%R/tktnew");
1089
+ }
1090
+ style_header("%s", zTitle);
1091
+ }
10651092
output_color_key(zClrKey, 1,
10661093
"border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
10671094
@ <table border="1" cellpadding="2" cellspacing="0" class="report sortable"
10681095
@ data-column-types='' data-init-sort='0'>
10691096
sState.rn = rn;
@@ -1076,11 +1103,13 @@
10761103
@ <p class="reportError">Error: %h(zErr1)</p>
10771104
}else if( zErr2 ){
10781105
@ <p class="reportError">Error: %h(zErr2)</p>
10791106
}
10801107
style_table_sorter();
1081
- style_finish_page();
1108
+ if ( pageWrap ) {
1109
+ style_finish_page();
1110
+ }
10821111
}else{
10831112
report_restrict_sql(&zErr1);
10841113
db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
10851114
report_unrestrict_sql();
10861115
cgi_set_content_type("text/plain");
10871116
--- src/report.c
+++ src/report.c
@@ -27,10 +27,19 @@
27
28 #ifndef SQLITE_RECURSIVE
29 # define SQLITE_RECURSIVE 33
30 #endif
31
 
 
 
 
 
 
 
 
 
32 /*
33 ** WEBPAGE: reportlist
34 **
35 ** Main menu for Tickets.
36 */
@@ -982,12 +991,23 @@
982 ** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
983 ** then the output consists of lines of tab-separated fields instead of
984 ** an HTML table.
985 */
986 void rptview_page(void){
 
 
 
 
 
 
 
 
 
 
 
987 int count = 0;
988 int rn, rc;
989 char *zSql;
990 char *zTitle;
991 char *zOwner;
992 char *zClrKey;
993 int tabs;
@@ -996,13 +1016,16 @@
996 char *zErr2 = 0;
997
998 login_check_credentials();
999 if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
1000 tabs = P("tablist")!=0;
 
 
 
1001 db_prepare(&q,
1002 "SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE rn=%d",
1003 atoi(PD("rn","0")));
1004 rc = db_step(&q);
1005 if( rc!=SQLITE_ROW ){
1006 db_finalize(&q);
1007 db_prepare(&q,
1008 "SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE title GLOB %Q",
@@ -1009,11 +1032,13 @@
1009 P("title"));
1010 rc = db_step(&q);
1011 }
1012 if( rc!=SQLITE_ROW ){
1013 db_finalize(&q);
1014 cgi_redirect("reportlist");
 
 
1015 return;
1016 }
1017 zTitle = db_column_malloc(&q, 0);
1018 zSql = db_column_malloc(&q, 1);
1019 zOwner = db_column_malloc(&q, 2);
@@ -1041,29 +1066,31 @@
1041 struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1042 const char *zQS = PD("QUERY_STRING","");
1043
1044 db_multi_exec("PRAGMA empty_result_callbacks=ON");
1045 style_set_current_feature("report");
1046 /* style_finish_page() should provide escaping via %h formatting */
1047 if( zQS[0] ){
1048 style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
1049 style_submenu_element("Reports","%R/reportlist?%s",zQS);
1050 } else {
1051 style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1052 style_submenu_element("Reports","%R/reportlist");
1053 }
1054 if( g.perm.Admin
1055 || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1056 style_submenu_element("Edit", "rptedit?rn=%d", rn);
1057 }
1058 if( g.perm.TktFmt ){
1059 style_submenu_element("SQL", "rptsql?rn=%d",rn);
1060 }
1061 if( g.perm.NewTkt ){
1062 style_submenu_element("New Ticket", "%R/tktnew");
1063 }
1064 style_header("%s", zTitle);
 
 
1065 output_color_key(zClrKey, 1,
1066 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1067 @ <table border="1" cellpadding="2" cellspacing="0" class="report sortable"
1068 @ data-column-types='' data-init-sort='0'>
1069 sState.rn = rn;
@@ -1076,11 +1103,13 @@
1076 @ <p class="reportError">Error: %h(zErr1)</p>
1077 }else if( zErr2 ){
1078 @ <p class="reportError">Error: %h(zErr2)</p>
1079 }
1080 style_table_sorter();
1081 style_finish_page();
 
 
1082 }else{
1083 report_restrict_sql(&zErr1);
1084 db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
1085 report_unrestrict_sql();
1086 cgi_set_content_type("text/plain");
1087
--- src/report.c
+++ src/report.c
@@ -27,10 +27,19 @@
27
28 #ifndef SQLITE_RECURSIVE
29 # define SQLITE_RECURSIVE 33
30 #endif
31
32 /* Settings that can be used to control ticket reports */
33 /*
34 ** SETTING: ticket-search-empty-report-number width=10 default=0
35 **
36 ** If this setting has an integer value of N, then when the ticket
37 ** search page query is blank, the report with rn=N is shown.
38 ** If N is zero, then no report is shown.
39 */
40
41 /*
42 ** WEBPAGE: reportlist
43 **
44 ** Main menu for Tickets.
45 */
@@ -982,12 +991,23 @@
991 ** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
992 ** then the output consists of lines of tab-separated fields instead of
993 ** an HTML table.
994 */
995 void rptview_page(void){
996 rptview_page_content(0, 1, 1);
997 }
998
999 /*
1000 ** Render a report.
1001 */
1002 void rptview_page_content(
1003 int rn, /* Report number. If 0, retrieve from rn query parameter. */
1004 int pageWrap, /* If true, render full page; otherwise, just the report */
1005 int redirectMissing /* If true and report not found, go to reportlist */
1006 ){
1007 int count = 0;
1008 int rc;
1009 char *zSql;
1010 char *zTitle;
1011 char *zOwner;
1012 char *zClrKey;
1013 int tabs;
@@ -996,13 +1016,16 @@
1016 char *zErr2 = 0;
1017
1018 login_check_credentials();
1019 if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
1020 tabs = P("tablist")!=0;
1021 if ( rn==0 ) {
1022 rn = atoi(PD("rn","0"));
1023 }
1024 db_prepare(&q,
1025 "SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE rn=%d",
1026 rn);
1027 rc = db_step(&q);
1028 if( rc!=SQLITE_ROW ){
1029 db_finalize(&q);
1030 db_prepare(&q,
1031 "SELECT title, sqlcode, owner, cols, rn FROM reportfmt WHERE title GLOB %Q",
@@ -1009,11 +1032,13 @@
1032 P("title"));
1033 rc = db_step(&q);
1034 }
1035 if( rc!=SQLITE_ROW ){
1036 db_finalize(&q);
1037 if (redirectMissing) {
1038 cgi_redirect("reportlist");
1039 }
1040 return;
1041 }
1042 zTitle = db_column_malloc(&q, 0);
1043 zSql = db_column_malloc(&q, 1);
1044 zOwner = db_column_malloc(&q, 2);
@@ -1041,29 +1066,31 @@
1066 struct GenerateHTML sState = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1067 const char *zQS = PD("QUERY_STRING","");
1068
1069 db_multi_exec("PRAGMA empty_result_callbacks=ON");
1070 style_set_current_feature("report");
1071 if ( pageWrap ) {
1072 /* style_finish_page() should provide escaping via %h formatting */
1073 if( zQS[0] ){
1074 style_submenu_element("Raw","%R/%s?tablist=1&%s",g.zPath,zQS);
1075 style_submenu_element("Reports","%R/reportlist?%s",zQS);
1076 } else {
1077 style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1078 style_submenu_element("Reports","%R/reportlist");
1079 }
1080 if( g.perm.Admin
1081 || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1082 style_submenu_element("Edit", "rptedit?rn=%d", rn);
1083 }
1084 if( g.perm.TktFmt ){
1085 style_submenu_element("SQL", "rptsql?rn=%d",rn);
1086 }
1087 if( g.perm.NewTkt ){
1088 style_submenu_element("New Ticket", "%R/tktnew");
1089 }
1090 style_header("%s", zTitle);
1091 }
1092 output_color_key(zClrKey, 1,
1093 "border=\"0\" cellpadding=\"3\" cellspacing=\"0\" class=\"report\"");
1094 @ <table border="1" cellpadding="2" cellspacing="0" class="report sortable"
1095 @ data-column-types='' data-init-sort='0'>
1096 sState.rn = rn;
@@ -1076,11 +1103,13 @@
1103 @ <p class="reportError">Error: %h(zErr1)</p>
1104 }else if( zErr2 ){
1105 @ <p class="reportError">Error: %h(zErr2)</p>
1106 }
1107 style_table_sorter();
1108 if ( pageWrap ) {
1109 style_finish_page();
1110 }
1111 }else{
1112 report_restrict_sql(&zErr1);
1113 db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
1114 report_unrestrict_sql();
1115 cgi_set_content_type("text/plain");
1116
+7 -1
--- src/tkt.c
+++ src/tkt.c
@@ -1636,12 +1636,18 @@
16361636
** Usage: /tktsrch?s=PATTERN
16371637
**
16381638
** Full-text search of all current tickets
16391639
*/
16401640
void tkt_srchpage(void){
1641
+ int rn;
16411642
login_check_credentials();
16421643
style_set_current_feature("tkt");
16431644
style_header("Ticket Search");
16441645
ticket_standard_submenu(T_ALL_BUT(T_SRCH));
1645
- search_screen(SRCH_TKT, 0);
1646
+ if ( !search_screen(SRCH_TKT, 0) ) {
1647
+ rn = db_get_int("ticket-search-empty-report-number",0);
1648
+ if ( rn ) {
1649
+ rptview_page_content(rn, 0, 0);
1650
+ }
1651
+ }
16461652
style_finish_page();
16471653
}
16481654
--- src/tkt.c
+++ src/tkt.c
@@ -1636,12 +1636,18 @@
1636 ** Usage: /tktsrch?s=PATTERN
1637 **
1638 ** Full-text search of all current tickets
1639 */
1640 void tkt_srchpage(void){
 
1641 login_check_credentials();
1642 style_set_current_feature("tkt");
1643 style_header("Ticket Search");
1644 ticket_standard_submenu(T_ALL_BUT(T_SRCH));
1645 search_screen(SRCH_TKT, 0);
 
 
 
 
 
1646 style_finish_page();
1647 }
1648
--- src/tkt.c
+++ src/tkt.c
@@ -1636,12 +1636,18 @@
1636 ** Usage: /tktsrch?s=PATTERN
1637 **
1638 ** Full-text search of all current tickets
1639 */
1640 void tkt_srchpage(void){
1641 int rn;
1642 login_check_credentials();
1643 style_set_current_feature("tkt");
1644 style_header("Ticket Search");
1645 ticket_standard_submenu(T_ALL_BUT(T_SRCH));
1646 if ( !search_screen(SRCH_TKT, 0) ) {
1647 rn = db_get_int("ticket-search-empty-report-number",0);
1648 if ( rn ) {
1649 rptview_page_content(rn, 0, 0);
1650 }
1651 }
1652 style_finish_page();
1653 }
1654
--- test/tester.tcl
+++ test/tester.tcl
@@ -351,10 +351,11 @@
351351
ssl-ca-location \
352352
ssl-identity \
353353
tclsh \
354354
th1-setup \
355355
th1-uri-regexp \
356
+ ticket-search-empty-report-number \
356357
user-color-map \
357358
uv-sync \
358359
web-browser]
359360
360361
fossil test-th-eval "hasfeature legacyMvRm"
361362
--- test/tester.tcl
+++ test/tester.tcl
@@ -351,10 +351,11 @@
351 ssl-ca-location \
352 ssl-identity \
353 tclsh \
354 th1-setup \
355 th1-uri-regexp \
 
356 user-color-map \
357 uv-sync \
358 web-browser]
359
360 fossil test-th-eval "hasfeature legacyMvRm"
361
--- test/tester.tcl
+++ test/tester.tcl
@@ -351,10 +351,11 @@
351 ssl-ca-location \
352 ssl-identity \
353 tclsh \
354 th1-setup \
355 th1-uri-regexp \
356 ticket-search-empty-report-number \
357 user-color-map \
358 uv-sync \
359 web-browser]
360
361 fossil test-th-eval "hasfeature legacyMvRm"
362

Keyboard Shortcuts

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