[LON-CAPA-cvs] cvs: rat / lonpage.pm lonwrapper.pm loncom/homework structuretags.pm loncom/interface lonhtmlcommon.pm lonmenu.pm

raeburn raeburn at source.lon-capa.org
Sun Aug 24 17:43:23 EDT 2025


raeburn		Sun Aug 24 21:43:23 2025 EDT

  Modified files:              
    /loncom/interface	lonhtmlcommon.pm lonmenu.pm 
    /loncom/homework	structuretags.pm 
    /rat	lonwrapper.pm lonpage.pm 
  Log:
  - Bug 6623. Countdown timer post-due date will show time until grace period 
    ends, when grace parameter in effect. 
  
  
-------------- next part --------------
Index: loncom/interface/lonhtmlcommon.pm
diff -u loncom/interface/lonhtmlcommon.pm:1.423 loncom/interface/lonhtmlcommon.pm:1.424
--- loncom/interface/lonhtmlcommon.pm:1.423	Sat Aug 23 21:23:43 2025
+++ loncom/interface/lonhtmlcommon.pm	Sun Aug 24 21:43:22 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common html routines
 #
-# $Id: lonhtmlcommon.pm,v 1.423 2025/08/23 21:23:43 raeburn Exp $
+# $Id: lonhtmlcommon.pm,v 1.424 2025/08/24 21:43:22 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1380,6 +1380,8 @@
     #                     the first network action.
     #                  2. The time required between the page load-start and the actual
     #                     initial javascript execution that got clientTime.
+    # dateType      - Either due (i.e., regular duedate), or grace (i.e., post-due
+    #                 but before end of grace period). 
     # These are used as follows:
     #   The difference between clientTime and serverTime are used to
     #   correct for differences in clock settings between the browser's system and the
@@ -1394,8 +1396,12 @@
 
     my $dueDateLayout = &mt('Due in: {dn} {dl} {hnn}{sep}{mnn}{sep}{snn} [_1]',
                             "<span id='submitearly'></span>");
+    my $overdue = '- '.&mt('Overdue');
+    my $endGraceLayout = &mt('Closes in: {dn} {dl} {hnn}{sep}{mnn}{sep}{snn} [_1]',
+                            "<span id='submitearly'>$overdue</span>");
     my $early = '- <b>'.&mt('Submit Early').'</b>';
     my $pastdue = '- <b>'.&mt('Past Due').'</b>';
+    my $grace_ended = '- <b>'.&mt('Past Overdue').'</b>';
     return <<"JAVASCRIPT";
 
     var documentReadyTime;
@@ -1403,14 +1409,21 @@
 \$(document).ready(function() {
    if (typeof(dueDate) != "undefined") {
        documentReadyTime = (new Date()).getTime();
+      var dateLayout = "$dueDateLayout";
+      var pastDueText = "$pastdue";
+      if ((typeof(dueDateType) != "undefined") &&
+          (dueDateType == 'grace')) {
+          dateLayout = "$endGraceLayout";
+          pastDueText = "$grace_ended";
+      }
       \$("#duedatecountdown").countdown({until: dueDate, compact: true,
-         layout: "$dueDateLayout",
+         layout: dateLayout,
          onTick: function (periods) {
             var latencyEstimate = (documentReadyTime - clientTime) * 2;
             if(\$.countdown.periodsToSeconds(periods) < (300 + latencyEstimate)) {
                \$("#submitearly").html("$early");
                if (\$.countdown.periodsToSeconds(periods) < 1) {
-                    \$("#submitearly").html("$pastdue");
+                    \$("#submitearly").html(pastDueText);
                }
             }
             if(\$.countdown.periodsToSeconds(periods) < (60 + latencyEstimate)) {
@@ -1785,15 +1798,22 @@
 
 ##
 #   Set the dueDate variable...note this is done in the timezone
-#   of the browser.
+#   of the browser. If past-due, but grace period is in effect
+#   date set is for the end of the grace period.
 #
 # @param epoch relative time at which the problem is due.
 #
 # @return the javascript fragment to set the date:
 #
 sub set_due_date {
-    my $dueStamp = shift;
+    my ($dueStamp,$is_grace_end) = @_;
     my $duems    = $dueStamp * 1000; # Javascript Date object needs ms not seconds.
+    my $date_type;
+    if ($is_grace_end) {
+        $date_type = 'grace';
+    } else {
+        $date_type = 'due';
+    }
 
     my $now = time()*1000;
 
@@ -1810,6 +1830,7 @@
 var serverTime    = $now;
 var clientTime    = (new Date()).getTime();
 var dueDate       = new Date(serverDueDate + (clientTime - serverTime));
+var dueDateType   = '$date_type';
 
   //]]>
 </script>
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.562 loncom/interface/lonmenu.pm:1.563
--- loncom/interface/lonmenu.pm:1.562	Tue Mar 25 01:02:59 2025
+++ loncom/interface/lonmenu.pm	Sun Aug 24 21:43:22 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.562 2025/03/25 01:02:59 raeburn Exp $
+# $Id: lonmenu.pm,v 1.563 2025/08/24 21:43:22 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -3606,7 +3606,7 @@
         }
         my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
         my @interval=&Apache::lonnet::EXT("resource.0.interval");
-        my ($timelimit,$usesdone,$donebuttontext,$proctor,$secret);
+        my ($timelimit,$usesdone,$donebuttontext,$proctor,$secret,$overduedate);
         if (@interval > 1) {
             ($timelimit,my $donesuffix) = split(/_/,$interval[0],2);
             if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
@@ -3623,10 +3623,13 @@
                     $hastimeleft = 1;
                 }
             }
+        } elsif ($duedate < time) {
+            $overduedate = &Apache::lonhomework::overdue_date('0');
         }
         if (($duedate && $duedate > time) ||
             (!$duedate && $hastimeleft) ||
-            ($slot_name ne '' && $slothastime)) {
+            ($slot_name ne '' && $slothastime) ||
+            (($duedate < time) && ($overduedate > time))) {
             my ($collapse,$expand,$alttxt,$title,$currdisp,$donebutton);
             if ((@interval > 1 && $hastimeleft) ||
                 ($type eq 'Task' && $slothastime)) {
@@ -3646,6 +3649,9 @@
                 $title = $alttxt.' ';
             }
             my $desc = &mt('Countdown to due date/time');
+            if (($duedate < time) && ($overduedate > time)) {
+                $desc = &mt('Countdown to end of grace period');
+            }
 
             return <<END;
 $donebutton
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.594 loncom/homework/structuretags.pm:1.595
--- loncom/homework/structuretags.pm:1.594	Thu Aug 21 16:21:41 2025
+++ loncom/homework/structuretags.pm	Sun Aug 24 21:43:23 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: structuretags.pm,v 1.594 2025/08/21 16:21:41 raeburn Exp $
+# $Id: structuretags.pm,v 1.595 2025/08/24 21:43:23 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2133,6 +2133,12 @@
                     my $time_left = $resource_due - time();
                     if ($resource_due && ($time_left > 0) && ($target eq 'web')) {
                         $result .= &Apache::lonhtmlcommon::set_due_date($resource_due);
+                    } elsif (($resource_due && $time_left <=0) && ($target eq 'web')) {
+                        my $overduedate = &Apache::lonhomework::overdue_date('0');
+                        if (($overduedate) && ($overduedate > time())) {
+                            $result .=
+                                &Apache::lonhtmlcommon::set_due_date($overduedate,1);
+                        }
                     }
                 }
             }
Index: rat/lonwrapper.pm
diff -u rat/lonwrapper.pm:1.86 rat/lonwrapper.pm:1.87
--- rat/lonwrapper.pm:1.86	Sun Dec 31 21:45:03 2023
+++ rat/lonwrapper.pm	Sun Aug 24 21:43:23 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Wrapper for external and binary files as standalone resources
 #
-# $Id: lonwrapper.pm,v 1.86 2023/12/31 21:45:03 raeburn Exp $
+# $Id: lonwrapper.pm,v 1.87 2025/08/24 21:43:23 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -124,14 +124,25 @@
         if ($status eq 'CAN_ANSWER') {
             if ($resource_due) {
                 my $time_left = $resource_due - time();
-                if ($resource_due && ($time_left > 0)) {
+                my $overduedate;
+                if ($time_left <=0) {
+                    $overduedate = &Apache::lonhomework::overdue_date('0');
+                }
+                if (($resource_due && ($time_left > 0)) ||
+                    ($overduedate && ($overduedate > time()))) {
                     $countdown ='
 <script type="text/javascript">
 // <![CDATA['."\n".
                              &Apache::lonhtmlcommon::countdown().'
 // ]]>
-</script>'."\n".
-                    &Apache::lonhtmlcommon::set_due_date($resource_due);
+</script>'."\n";
+                    if ($resource_due && ($time_left > 0)) {
+                        $countdown .=
+                            &Apache::lonhtmlcommon::set_due_date($resource_due);
+                    } else {
+                        $countdown .=
+                            &Apache::lonhtmlcommon::set_due_date($overduedate,1);
+                    }
                 }
             }
         } else {
Index: rat/lonpage.pm
diff -u rat/lonpage.pm:1.145 rat/lonpage.pm:1.146
--- rat/lonpage.pm:1.145	Wed Mar 19 14:44:03 2025
+++ rat/lonpage.pm	Sun Aug 24 21:43:23 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Page Handler
 #
-# $Id: lonpage.pm,v 1.145 2025/03/19 14:44:03 raeburn Exp $
+# $Id: lonpage.pm,v 1.146 2025/08/24 21:43:23 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -200,7 +200,8 @@
 # ------------------------------------------------------------- Countdown Timer
                   my $now = time;
                   my ($pagefirstaccess,%hastimeleft,%countdowndisp,%donebutton,
-                      %donebtnextra,%buttonbytime,$donetime,$symbtosetdone);
+                      %donebtnextra,%buttonbytime,$donetime,$symbtosetdone,
+                      %hasgracetimeleft);
                   my ($pagesymb,$courseid,$domain,$name)=&Apache::lonnet::whichuser();
                   unless ($pagesymb) {
                       $pagesymb=&Apache::lonnet::symbread($requrl);
@@ -581,6 +582,7 @@
                                               }
                                               my $duedate = &Apache::lonnet::EXT("resource.0.duedate",$symb);
                                               my @interval=&Apache::lonnet::EXT("resource.0.interval",$symb);
+                                              my $overduedate;
                                               if (@interval > 1) {
                                                   my $first_access;
                                                   if ($interval[1] eq 'map') {
@@ -604,10 +606,13 @@
                                                           }
                                                       }
                                                   }
+                                              } else {
+                                                  $overduedate = &Apache::lonhomework::overdue_date('0',$symb);
                                               }
                                               if (($duedate && $duedate > $now) ||
                                                   (!$duedate && $timerhastime > 0) ||
-                                                  ($slot_name ne '' && $slothastime)) {
+                                                  ($slot_name ne '' && $slothastime) ||
+                                                  (($duedate < $now) && ($overduedate > $now))) {
                                                   if ((@interval > 1 && $timerhastime) ||
                                                       ($type eq 'Task' && $slothastime)) {
                                                       $countdowndisp{$symb} = 'inline';
@@ -638,9 +643,12 @@
                                                       } else {
                                                           $hastimeleft{$symb} = $slothastime;
                                                       }
-                                                  } else {
+                                                  } elsif ($duedate && ($duedate > $now)) {
                                                       $hastimeleft{$symb} = $duedate - $now;
                                                       $countdowndisp{$symb} = 'none';
+                                                  } elsif (($duedate < $now) && ($overduedate > $now)) {
+                                                      $hasgracetimeleft{$symb} = $overduedate - $now;
+                                                      $countdowndisp{$symb} = 'none';
                                                   }
                                                   unless ($donebutton{$symb}) {
                                                       $donebutton{$symb} = 0;
@@ -785,6 +793,32 @@
                                   }
                                   &add_countdown_timer($currdisp,$donebuttontime,$donebuttonextras);
                               }
+                          } elsif (keys(%hasgracetimeleft)) {
+                              my (%uniquetimes,%uniquedisplays);
+                              foreach my $item (values(%hasgracetimeleft)) {
+                                  if (exists($uniquetimes{$item})) {
+                                      $uniquetimes{$item} ++;
+                                  } else {
+                                      $uniquetimes{$item} = 1;
+                                  }
+                              }
+                              if (scalar(keys(%uniquetimes)) == 1) {
+                                  my (%uniquedisplays,%uniquedones,$currdisp);
+                                  if (keys(%countdowndisp)) {
+                                      foreach my $item (values(%countdowndisp)) {
+                                          if (exists($uniquedisplays{$item})) {
+                                              $uniquedisplays{$item} ++;
+                                          } else {
+                                              $uniquedisplays{$item} = 1;
+                                          }
+                                      }
+                                      my @countdowndisplay = keys(%uniquedisplays);
+                                      if (scalar(@countdowndisplay) == 1) {
+                                          $currdisp = $countdowndisplay[0];
+                                      }
+                                  }
+                                  &add_countdown_timer($currdisp,'','','grace');
+                              }
                           }
                           my $pagebuttonshide;
                           if (keys(%buttonshide)) {
@@ -1173,7 +1207,7 @@
 }
 
 sub add_countdown_timer {
-    my ($currdisp,$donebuttontime,$donebuttonextras) = @_;
+    my ($currdisp,$donebuttontime,$donebuttonextras,$countdowntype) = @_;
     my ($collapse,$expand,$alttxt,$title,$donebutton);
     if ($currdisp eq 'inline') {
         $collapse = '► ';
@@ -1198,6 +1232,9 @@
         $title = $alttxt.' ';
     }
     my $desc = &mt('Countdown to due date/time');
+    if ($countdowntype eq 'grace') {
+        $desc = &mt('Countdown to end of grace period');
+    }
     my $output = <<END;
 $donebutton
 <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">


More information about the LON-CAPA-cvs mailing list