--- loncom/interface/slotrequest.pm	2025/03/20 17:59:20	1.150
+++ loncom/interface/slotrequest.pm	2025/03/31 13:55:06	1.151
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler for requesting to have slots added to a students record
 #
-# $Id: slotrequest.pm,v 1.150 2025/03/20 17:59:20 raeburn Exp $
+# $Id: slotrequest.pm,v 1.151 2025/03/31 13:55:06 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -63,6 +63,10 @@ sub start_page {
         if ($bread_crumbs_component) {
             $args->{bread_crumbs_component} = $bread_crumbs_component;
         }
+        if ((($env{'form.requestattempt'}) || ($env{'form.context'} eq 'user')) && 
+             ($env{'form.symb'})) {
+            $args->{'bread_crumbs_nomenu'} = 1;
+        }
     }
     if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {
         my %loaditems = (
@@ -769,7 +773,7 @@ sub release_all_slot {
         if (!$result) {
             $r->print('<p class="LC_error">'.&mt($msg).'</p>');
         } else {
-	    $r->print("<p>$msg</p>");
+	    $r->print($msg);
         }
 	$r->rflush();
     }
@@ -1061,7 +1065,8 @@ sub release_reservation {
             if ($mgr eq 'F') {
                 $msg = &mt('Released Reservation for user: [_1]',"$uname:$udom");
             } else {
-                $msg = '<span style="font-weight: bold;">'.&mt('Released reservation: [_1]',$description).'</span><br /><br />';
+                $msg = '<p style="font-weight: bold;">'.
+                       &mt('Released reservation: [_1]',$description).'</p>';
                 my $person = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                 my $subject = &mt('Reservation change: [_1]',$description);
                 my $msgbody = &mt('Reservation released by [_1] for [_2].',$person,$description);
@@ -1446,7 +1451,7 @@ sub show_choices {
         return;
     }
     if (!@{$available}) {
-        $output = '<span class="LC_info">'.&mt('No available times.').'</span>';
+        $output = '<p class="LC_info">'.&mt('No available times.').'</p>';
         if ($env{'form.command'} ne 'manageresv') {
             my $target = &return_target();
             $output .= ' <a href="/adm/flip?postdata=return:" target="'.$target.'">'.
@@ -1457,6 +1462,10 @@ sub show_choices {
         } else {
             return $output;
         }
+    } elsif ($env{'form.command'} ne 'manageresv') {
+        my $title = &Apache::lonnet::gettitle($symb);
+        my $headertext = &mt('Manage Reservation(s) for [_1]',$title);
+        $output .= '<h2 class="LC_heading_3">'.$headertext.'</h2>';
     }
     if (@{$available} > 1) {
         my $numavailable = scalar(@{$available});
@@ -1522,18 +1531,22 @@ ENDSCRIPT
         $output .=
             '<div id="LC_slotfilter_'.$num.'" style="display:'.$showfilter.'">'.
             '<form method="post" name="'.$chooserform.'" action="">'.
-            '<table><tr><td>'.&mt('Open after').'</td><td>'.
+            '<table class="LC_manage_reservations"><tr><th>'.&mt('Open after').'</th><td>'.
             &Apache::lonhtmlcommon::date_setter($chooserform,'start',$starttime,'','','','','','','',1,1).
-            '</td></tr><tr><td>'.&mt('Closed before').'</td><td>'.
+            '</td></tr><tr><th>'.&mt('Closed before').'</th><td>'.
             &Apache::lonhtmlcommon::date_setter($chooserform,'end',$endtime,'','','','','','','',1,1).
             '</td></tr></table><br />'.
             '<input type="button" name="slotfilter" value="Search for reservable slots" onclick="updateSlotDisplay(this.form,'."'$num'".');" />'.
             '</form></div><div id="LC_slotsearch_'.$num.'" style="display:none"><hr />';
     }
     if ($env{'form.command'} eq 'manageresv') {
-        $output .= '<table border="0">';
+        $output .= '<table border="0" class="LC_manage_reservations">'.
+                   '<tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th></tr>';
     } else {
-        $output .= &Apache::loncommon::start_data_table();
+        $output .= &Apache::loncommon::start_data_table().
+                   &Apache::loncommon::start_data_table_header_row().
+                   '<th>'.&mt('Action').'</th><th>'.&mt('Name').'</th>'.
+                   &Apache::loncommon::end_data_table_header_row();
     }
     foreach my $slot (@{$available}) {
 	my $description=&get_description($slot,$slots->{$slot});
@@ -3445,6 +3458,61 @@ sub slot_reservationmsg_options {
     return %options;
 }
 
+sub get_user_breadcrumbs {
+    my ($symb) = @_;
+    my ($mapurl, $rid, $resurl) = &Apache::lonnet::decode_symb($symb);
+    return [] unless (&Apache::lonnet::symbverify($symb,$resurl));
+    my $coursetitle = $env{'course.'.$env{'request.course.id'}.'.description'};
+    my $maptitle = &Apache::lonnet::gettitle($mapurl);
+    my $restitle = &Apache::lonnet::gettitle($symb);
+    my $crstype = &Apache::loncommon::course_type();
+    my ($ltiscope,$ltiuri);
+    my (@crumbs,@mapcrumbs);
+    if (($env{'request.course.id'}) && ($env{'request.lti.login'})) {
+        ($ltiscope,$ltiuri) =
+            &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'},
+                       $env{'course.'.$env{'request.course.id'}.'.domain'},
+                       $env{'course.'.$env{'request.course.id'}.'.num'});
+    }
+    if (($resurl ne '/adm/navmaps') && ($mapurl ne '') &&
+        (!(($crstype eq 'Placement') && !$env{'request.role.adv'}))) {
+        unless ($ltiscope eq 'resource') {
+            if (($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) &&
+                !(($ltiscope eq 'map') && (&Apache::lonnet::clutter($resurl) eq $ltiuri))) {
+                my $navmap = Apache::lonnavmaps::navmap->new();
+                if (ref($navmap)) {
+                    @mapcrumbs = $navmap->recursed_crumbs($mapurl,$restitle);
+                }
+            }
+        }
+    }
+    unless ((($crstype eq 'Placement') && (!$env{'request.role.adv'})) ||
+             ($ltiscope eq 'map') || ($ltiscope eq 'resource')) {
+             @crumbs = ({text  => $crstype.' Contents',
+                         href  => "javascript:gopost('/adm/navmaps','')"});
+    }
+    if ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) {
+        if (@mapcrumbs) {
+            push(@crumbs,@mapcrumbs);
+        } elsif (!(($crstype eq 'Placement') && (!$env{'request.role.adv'})) &&
+                 ($ltiscope ne 'map') && ($ltiscope ne 'resource')) {
+            push(@crumbs, {text  => '...',
+                           no_mt => 1});
+        }
+    }
+    unless ((($crstype eq 'Placement') && (!$env{'request.role.adv'})) || (@mapcrumbs) ||
+            (!$maptitle) || ($maptitle eq 'default.sequence') ||
+            ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) ||
+            ($ltiscope eq 'resource')) {
+        push(@crumbs, {text => $maptitle, no_mt => 1,
+                       href => &Apache::lonnet::clutter($mapurl).'?navmap=1'});
+    }
+    if ($restitle && !@mapcrumbs) {
+        push(@crumbs,{text => $restitle, no_mt => 1});
+    }
+    return \@crumbs;
+}
+
 sub handler {
     my $r=shift;
 
@@ -3458,7 +3526,7 @@ sub handler {
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'});
 
     my %crumb_titles = &slot_command_titles();
-    my ($brcrum,$bread_crumbs_component);
+    my ($symb,$brcrum,$bread_crumbs_component);
 
     my $vgr=&Apache::lonnet::allowed('vgr',$env{'request.course.id'});
     my $mgr=&Apache::lonnet::allowed('mgr',$env{'request.course.id'});
@@ -3488,6 +3556,12 @@ sub handler {
             $title = 'Manage Reservations';
             $brcrum =[{href=>"/adm/slotrequest?command=manageresv",text=>$title}];
         }
+        if ($env{'form.requestattempt'}) {
+            $symb=&unescape($env{'form.symb'});
+            if ($symb) {
+                $brcrum = &get_user_breadcrumbs($symb);
+            }
+        }
         my ($cnum,$cdom)=&get_course();
         %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
         $consumed_uniqueperiods = &get_consumed_uniqueperiods(\%slots);
@@ -3507,19 +3581,32 @@ sub handler {
     } elsif ($env{'form.command'} eq 'release') {
         if ($env{'form.context'} eq 'usermanage') {
             $brcrum =[{href=>"/adm/slotrequest?command=manageresv",
-                       text=>$crumb_titles{'showslots'}}];
+                       text=>$crumb_titles{'manageresv'}}];
             $title = 'Manage Reservations';
             if (ref($brcrum) eq 'ARRAY') {
                 push(@{$brcrum},{href=>"/adm/slotrequest?command=$env{'form.command'}",text=>$crumb_titles{$env{'form.command'}}});
             }
+        } elsif ($env{'form.context'} eq 'user') {
+             if ($env{'form.symb'}) {
+                 $symb=&unescape($env{'form.symb'});
+                 $brcrum = &get_user_breadcrumbs($symb);
+             } else {
+                 $brcrum =[];
+             }
+        }
+    } elsif (($env{'form.command'} eq 'get') && ($env{'form.context'} eq 'user')) {
+        if ($env{'form.symb'}) {
+            $symb=&unescape($env{'form.symb'});
+            $brcrum = &get_user_breadcrumbs($symb);
+        } else {
+            $brcrum =[];
         }
     } else {
         $brcrum =[];
     }
-    my ($symb,$js,$available,$allavailable,$got_slots);
+    my ($js,$available,$allavailable,$got_slots);
     $available = [];
     if ($env{'form.requestattempt'}) {
-        $symb=&unescape($env{'form.symb'});
         @{$got_slots}=&check_for_reservation($symb,'allslots');
     }
     if (($env{'form.requestattempt'}) || ($env{'form.command'} eq 'manageresv')) {
@@ -3566,7 +3653,7 @@ sub handler {
     } elsif (($env{'form.command'} eq 'slotlog') && ($vgr eq 'F')) {
         &show_reservations_log($r);
     } else {
-	my $symb=&unescape($env{'form.symb'});
+	$symb = &unescape($env{'form.symb'});
 	if (!defined($symb)) {
 	    &fail($r,'not_valid');
 	    return OK;
@@ -3591,9 +3678,9 @@ sub handler {
 	    return OK;
 	}
 	if ($env{'form.requestattempt'}) {
-            $r->print('<div class="LC_left_float">'); 
-	    $r->print(&show_choices($symb,undef,undef,undef,\%slots,$consumed_uniqueperiods,$available,$got_slots));
-            $r->print('</div><div style="padding:0;clear:both;margin:0;border:0"></div>');
+            $r->print('<div class="LC_left_float">'.
+	              &show_choices($symb,undef,0,undef,\%slots,$consumed_uniqueperiods,$available,$got_slots).
+                      '</div><div style="padding:0;clear:both;margin:0;border:0"></div>');
 	} elsif ($env{'form.command'} eq 'release') {
 	    &release_slot($r,$symb);
 	} elsif ($env{'form.command'} eq 'get') {