Fossil

Check-in [675274612d]
Login

Check-in [675274612d]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Use drop-down menus to select the user on the /reports pages.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | andygoth-user-reports
Files: files | file ages | folders
SHA1: 675274612dc320046b8887070218ba9fc9238f65
User & Date: drh 2015-05-18 22:05:38.387
Context
2015-05-18
22:18
Pull in the memory allocation fix from trunk. ... (check-in: 879958277a user: drh tags: andygoth-user-reports)
22:05
Use drop-down menus to select the user on the /reports pages. ... (check-in: 675274612d user: drh tags: andygoth-user-reports)
20:00
Fix the display of /reports?view=byweek with an invalid user. ... (check-in: 5fa4d0125c user: drh tags: andygoth-user-reports)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/statrep.c.
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
  int iterations = 0;                /* # of active time periods. */
  int n = 0;                         /* Number of entries in azYear */
  char **azYear = 0;                 /* Year dropdown menu */
  int rowCount = 0;
  int total = 0;

  stats_report_init_view();
  db_prepare(&q,

             "SELECT DISTINCT substr(date(mtime),1,4) AS y"
             "  FROM v_reports"
             " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
             " GROUP BY y ORDER BY y DESC", zUserName);
  while( SQLITE_ROW == db_step(&q) ){
    azYear = fossil_realloc(azYear, sizeof(char*)*(n+2));
    azYear[n] = fossil_strdup(db_column_text(&q,0));
    azYear[n+1] = azYear[n];
    if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) isValidYear = 1;
    n += 2;
  }
  db_finalize(&q);
  if( !isValidYear ){
    if( n ){
      zYear = azYear[0];
    }else{
      zYear = db_text("1970","SELECT substr(date('now'),1,4);");
    }
  }
  style_submenu_multichoice("y", n/2, (const char**)azYear, 0);
  cgi_printf("<br/>");
  db_prepare(&q,
             "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
             "       count(*) AS n "
             "  FROM v_reports "
             " WHERE %Q=substr(date(mtime),1,4) "
             "   AND mtime < current_timestamp "







|
>
|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<







575
576
577
578
579
580
581
582
583
584
585
586
587









588


589
590


591
592
593
594
595
596
597
  int iterations = 0;                /* # of active time periods. */
  int n = 0;                         /* Number of entries in azYear */
  char **azYear = 0;                 /* Year dropdown menu */
  int rowCount = 0;
  int total = 0;

  stats_report_init_view();
  style_submenu_sql("y", "Year:",
     "WITH RECURSIVE a(b) AS ("
     "  SELECT substr(date('now'),1,4) UNION ALL"
     "  SELECT b-1 FROM a"
     "   WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)"
     ") SELECT b, b FROM a ORDER BY b DESC");









  if( zYear==0 || strlen(zYear)!=4 ){


    zYear = db_text("1970","SELECT substr(date('now'),1,4);");
  }


  cgi_printf("<br/>");
  db_prepare(&q,
             "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
             "       count(*) AS n "
             "  FROM v_reports "
             " WHERE %Q=substr(date(mtime),1,4) "
             "   AND mtime < current_timestamp "
751
752
753
754
755
756
757
758






759
760
761
762
763
764
765
      azView[nView++] = aViewType[i].zName;
    }
    style_submenu_multichoice("view", nView/2, azView, 0);
    if( eType!=RPT_BYFILE ){
      style_submenu_multichoice("type", ArraySize(azType)/2, azType, 0);
    }
    if( eType!=RPT_BYUSER ){
      style_submenu_entry("u", "User:", 12, 0);






    }
  }
  style_submenu_element("Stats", "Stats", "%R/stat");
  url_reset(&url);
  style_header("Activity Reports");
  switch( eType ){
    case RPT_BYYEAR: 







|
>
>
>
>
>
>







739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
      azView[nView++] = aViewType[i].zName;
    }
    style_submenu_multichoice("view", nView/2, azView, 0);
    if( eType!=RPT_BYFILE ){
      style_submenu_multichoice("type", ArraySize(azType)/2, azType, 0);
    }
    if( eType!=RPT_BYUSER ){
      style_submenu_sql("u","User:",
         "SELECT '', 'All Users' UNION ALL "
         "SELECT x, x FROM ("
         "  SELECT DISTINCT trim(coalesce(euser,user)) AS x FROM event %s"
         "  ORDER BY 1 COLLATE nocase) WHERE x!=''",
         eType==RPT_BYFILE ? "WHERE type='ci'" : ""
      );
    }
  }
  style_submenu_element("Stats", "Stats", "%R/stat");
  url_reset(&url);
  style_header("Activity Reports");
  switch( eType ){
    case RPT_BYYEAR: 
Changes to src/style.c.
283
284
285
286
287
288
289











290























291
292
293
294
295
296
297
  aSubmenuCtrl[nSubmenuCtrl].zName = zName;
  aSubmenuCtrl[nSubmenuCtrl].iSize = nChoice;
  aSubmenuCtrl[nSubmenuCtrl].azChoice = azChoice;
  aSubmenuCtrl[nSubmenuCtrl].isDisabled = isDisabled;
  aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
  nSubmenuCtrl++;
}




































/*
** Compare two submenu items for sorting purposes
*/
static int submenuCompare(const void *a, const void *b){
  const struct Submenu *A = (const struct Submenu*)a;
  const struct Submenu *B = (const struct Submenu*)b;







>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
  aSubmenuCtrl[nSubmenuCtrl].zName = zName;
  aSubmenuCtrl[nSubmenuCtrl].iSize = nChoice;
  aSubmenuCtrl[nSubmenuCtrl].azChoice = azChoice;
  aSubmenuCtrl[nSubmenuCtrl].isDisabled = isDisabled;
  aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
  nSubmenuCtrl++;
}
void style_submenu_sql(
  const char *zName,       /* Query parameter name */
  const char *zLabel,      /* Label on the control */
  const char *zFormat,     /* Format string for SQL command for choices */
  ...                      /* Arguments to the format string */
){
  Stmt q;
  int n = 0;
  int nAlloc = 0;
  char **az = 0;
  va_list ap;

  va_start(ap, zFormat);
  db_vprepare(&q, 0, zFormat, ap);
  va_end(ap);
  while( SQLITE_ROW==db_step(&q) ){
    if( n+2>=nAlloc ){
      nAlloc += nAlloc + 20;
      az = fossil_realloc(az, sizeof(char*)*nAlloc);
    }
    az[n++] = fossil_strdup(db_column_text(&q,0));
    az[n++] = fossil_strdup(db_column_text(&q,1));
  }
  db_finalize(&q);
  if( n>0 ){
    aSubmenuCtrl[nSubmenuCtrl].zName = zName;
    aSubmenuCtrl[nSubmenuCtrl].zLabel = zLabel;
    aSubmenuCtrl[nSubmenuCtrl].iSize = n/2;
    aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char**)az;
    aSubmenuCtrl[nSubmenuCtrl].isDisabled = 0;
    aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
    nSubmenuCtrl++;
  }
}
   

/*
** Compare two submenu items for sorting purposes
*/
static int submenuCompare(const void *a, const void *b){
  const struct Submenu *A = (const struct Submenu*)a;
  const struct Submenu *B = (const struct Submenu*)b;
512
513
514
515
516
517
518



519
520
521
522
523
524
525
               zDisabled
            );
            break;
          }
          case FF_MULTI: {
            int j;
            const char *zVal = P(zQPN);



            cgi_printf(
               "<select class='submenuctrl' size='1' name='%s'%s "
               "onchange='gebi(\"f01\").submit();'>\n",
               zQPN, zDisabled
            );
            for(j=0; j<aSubmenuCtrl[i].iSize*2; j+=2){
              const char *zQPV = aSubmenuCtrl[i].azChoice[j];







>
>
>







546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
               zDisabled
            );
            break;
          }
          case FF_MULTI: {
            int j;
            const char *zVal = P(zQPN);
            if( aSubmenuCtrl[i].zLabel ){
              cgi_printf("&nbsp;%h", aSubmenuCtrl[i].zLabel);
            }
            cgi_printf(
               "<select class='submenuctrl' size='1' name='%s'%s "
               "onchange='gebi(\"f01\").submit();'>\n",
               zQPN, zDisabled
            );
            for(j=0; j<aSubmenuCtrl[i].iSize*2; j+=2){
              const char *zQPV = aSubmenuCtrl[i].azChoice[j];