--- loncom/interface/loncoursequeueadmin.pm 2022/12/01 01:28:26 1.64
+++ loncom/interface/loncoursequeueadmin.pm 2022/12/03 00:34:38 1.65
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Utilities to administer domain course requests and course self-enroll requests
#
-# $Id: loncoursequeueadmin.pm,v 1.64 2022/12/01 01:28:26 raeburn Exp $
+# $Id: loncoursequeueadmin.pm,v 1.65 2022/12/03 00:34:38 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -411,7 +411,7 @@ sub send_selfserve_notification {
sub display_queued_requests {
my ($context,$dom,$cnum,$secondary) = @_;
- my ($namespace,$formaction,$nextelement,%requesthash);
+ my ($namespace,$formaction,$nextelement,%requesthash,%reqstatus);
if ($context eq 'course') {
$formaction = '/adm/createuser';
$namespace = 'selfenrollrequests';
@@ -484,13 +484,15 @@ sub display_queued_requests {
($entry) = (&unescape($item) =~ /^($match_username)_approval$/);
} elsif ($context eq 'othdomqueue') {
if (ref($requesthash{$item}) eq 'HASH') {
- next unless ($requesthash{'status&'.$item} eq 'pending');
my ($puname,$pudom,$prole,$psec) = split(/:/,$item);
$timestamp = $requesthash{$item}{'timestamp'};
my $adj = $requesthash{$item}{'adj'};
$entry = join(':',$puname,$pudom,$prole,$adj,
&escape($requesthash{$item}{'requester'}),
$psec);
+ } elsif ($item =~ /^status&/) {
+ my ($dummy,$key) = split(/&/,$item,2);
+ $reqstatus{$key} = $requesthash{$item};
}
} elsif ($context eq 'othdomaction') {
next unless ($item =~ /^pending:/);
@@ -539,13 +541,13 @@ sub display_queued_requests {
$output .= '
'.&mt('Requests for LON-CAPA accounts queued pending approval by a Domain Coordinator').' ';
} elsif ($context eq 'othdomqueue') {
if ($secondary eq 'domain') {
- $output .= ''.&mt('Domain role assignments for users from another domain, queued pending approval').' ';
+ $output .= ''.&mt('Domain role assignments for users from another domain which were/are queued for approval').' ';
} elsif ($secondary eq 'author') {
- $output .= ''.&mt('Co-author role assignments for users from another domain, queued pending approval').' ';
+ $output .= ''.&mt('Co-author role assignments for users from another domain which were/are queued for approval').' ';
} elsif ($secondary eq 'course') {
- $output .= ''.&mt('Course role assignments for users from another domain, queued pending approval').' ';
+ $output .= ''.&mt('Course role assignments for users from another domain which were/are queued for approval').' ';
} elsif ($secondary eq 'community') {
- $output .= ''.&mt('Community role assignments for users from another domain, queued pending approval').' ';
+ $output .= ''.&mt('Community role assignments for users from another domain which were/are queued for approval').' ';
}
} elsif ($context eq 'othdomaction') {
if ($secondary eq 'user') {
@@ -555,9 +557,13 @@ sub display_queued_requests {
}
} else {
$output .= ''.&mt('Course/Community requests queued pending approval by a Domain Coordinator').' ';
- }
- $output .= &build_queue_display($dom,$context,\%queue_by_date,$secondary).
- ' ';
+ }
+ if ($context eq 'othdomqueue') {
+ $output .= &queued_role_display($secondary,\%queue_by_date,\%reqstatus);
+ } else {
+ $output .= &build_queue_display($dom,$context,\%queue_by_date,$secondary).
+ ' ';
+ }
if ($context eq 'pending') {
$output .= ' '."\n".
@@ -579,13 +585,13 @@ sub display_queued_requests {
$output .= &mt('There are currently no requests for LON-CAPA accounts awaiting approval.');
} elsif ($context eq 'othdomqueue') {
if ($secondary eq 'domain') {
- $output .= &mt('There are currently no domain role assignment(s) for user(s) from another domain queued pending approval');
+ $output .= &mt('There are currently no domain role assignment(s) for user(s) from another domain which were/are queued for approval');
} elsif ($secondary eq 'author') {
- $output .= &mt('There are currently no co-author role assignment(s) for user(s) from another domain queued pending approval');
+ $output .= &mt('There are currently no co-author role assignment(s) for user(s) from another domain which were/are queued for approval');
} elsif ($secondary eq 'course') {
- $output .= &mt('There are currently no course role assignment(s) for user(s) from another domain queued pending approval');
+ $output .= &mt('There are currently no course role assignment(s) for user(s) from another domain which were/are queued for approval');
} elsif ($secondary eq 'community') {
- $output .= &mt('There are currently no community role assignment(s) for user(s) from another domain queued pending approval');
+ $output .= &mt('There are currently no community role assignment(s) for user(s) from another domain which were/are queued for approval');
}
} elsif ($context eq 'othdomaction') {
if ($secondary eq 'user') {
@@ -605,16 +611,13 @@ sub build_queue_display {
my ($dom,$context,$queue,$secondary) = @_;
return unless (ref($queue) eq 'HASH');
my (%crstypes,%roles_by_context,$output);
- if ($context eq 'othdomqueue') {
- $output = &print_filter_menu($context);
- }
$output .= &Apache::loncommon::start_data_table().
&Apache::loncommon::start_data_table_header_row();
unless (($context eq 'pending') || ($context eq 'displaypending') ||
- ($context eq 'helpdesk') || ($context eq 'othdomqueue')) {
+ ($context eq 'helpdesk')) {
$output .= ''.&mt('Action').' ';
}
- unless (($context eq 'othdomqueue') || (($context eq 'othdomaction') && ($secondary eq 'user'))) {
+ unless (($context eq 'othdomaction') && ($secondary eq 'user')) {
$output .= ''.&mt('Requestor').' ';
}
if ($context eq 'course') {
@@ -625,14 +628,6 @@ sub build_queue_display {
} elsif ($context eq 'requestusername') {
$output .= ''.&mt('Date requested').' '.
''.&mt('Details').' ';
- } elsif ($context eq 'othdomqueue') {
- $output .= ''.&mt('Date requested').' '.
- ''.&mt('Role').' ';
- if ($secondary eq 'course') {
- $output .= ''.&mt('Section').' ';
- }
- $output .= ''.&mt('Requested for').' '.
- ''.&mt('Approval needed from').' ';
} elsif ($context eq 'othdomaction') {
$output .= ''.&mt('Date requested').' '.
''.&mt('Role type').' '.
@@ -698,25 +693,6 @@ sub build_queue_display {
"'$dom','$request','$queued'".');">'.$request.'';
$namelink = $request;
}
- } elsif ($context eq 'othdomqueue') {
- my ($uname,$udom,$role,$adj,$requester,$sec) = split(/:/,$request);
- if ($adj eq 'user') {
- $adjudicator = &mt('Role Assignee');
- } elsif ($adj eq 'domain') {
- $adjudicator = &mt("[_1] in user's domain",
- &Apache::lonnet::plaintext('dc'));
- }
- my $crstype;
- $showrole = &Apache::lonnet::plaintext($role,$crstype);
- unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
- $namelink = &Apache::loncommon::plainname($uname,$udom)." ($uname:$udom)";
- }
- if ($secondary eq 'course') {
- $showsec = $sec;
- if ($showsec eq '') {
- $showsec = &mt('none');
- }
- }
} elsif ($context eq 'othdomaction') {
my ($status,$extent,$role,$crstype);
my ($info,$requester) = map { &unescape($_); } split(/:/,$request);
@@ -816,7 +792,7 @@ sub build_queue_display {
$ownername,$ownerdom);
}
unless (($context eq 'pending') || ($context eq 'displaypending') ||
- ($context eq 'helpdesk') || ($context eq 'othdomqueue')) {
+ ($context eq 'helpdesk')) {
$row = ''.
' '.&mt('Approve').' '.
''.(' 'x2).
@@ -825,7 +801,7 @@ sub build_queue_display {
' '.&mt('Decide Later').
' ';
}
- unless (($context eq 'othdomqueue') || ($context eq 'othdomaction')) {
+ unless ($context eq 'othdomaction') {
$row .= ''.$namelink.' '."\n";
}
if ($context eq 'course') {
@@ -836,14 +812,6 @@ sub build_queue_display {
} elsif ($context eq 'requestusername') {
$row .= ''.$showtime.' '."\n".
''.$detailslink.' '."\n";
- } elsif ($context eq 'othdomqueue') {
- $row .= ''.$showtime.' '."\n".
- ''.$showrole.' '."\n";
- if ($secondary eq 'course') {
- $row .= ''.$showsec.' '."\n";
- }
- $row .= ''.$namelink.' '."\n".
- ''.$adjudicator.' '."\n";
} elsif ($context eq 'othdomaction') {
if ($secondary eq 'domain') {
$row .= ''.$showrequester.' '."\n";
@@ -874,10 +842,311 @@ sub build_queue_display {
return $output;
}
-sub print_filter_menu {
- my ($context) = @_;
+sub queued_role_display {
+ my ($context,$queue,$status) = @_;
+ return unless ((ref($queue) eq 'HASH') && (ref($status) eq 'HASH'));
+ my (%curr,$minshown,$maxshown,$more_records,$crstype,$viewablesec,$output);
+ my $formname = 'changequeue';
+ if ($context eq 'course') {
+ $crstype = &Apache::loncommon::course_type();
+ my ($permission,$allowed) =
+ &Apache::lonuserutils::get_permission($context,$crstype);
+ $viewablesec = &Apache::lonuserutils::viewable_section($permission);
+ my %saveable_parameters = ('show' => 'scalar',);
+ &Apache::loncommon::store_course_settings('roles_req',
+ \%saveable_parameters);
+ &Apache::loncommon::restore_course_settings('roles_req',
+ \%saveable_parameters);
+ }
+
+# Create navigation javascript
+ my $jsnav = &queued_log_js($formname);
+
+ $output = (<
+//
+
+ENDSCRIPT
+
+ my $now = time();
+ my $defstart = $now - (7*24*3600); #7 days ago
+ my %defaults = (
+ page => '1',
+ show => '10',
+ role => 'any',
+ chgstatus => 'any',
+ chgadj => 'any',
+ rolereq_start_date => $defstart,
+ rolereq_end_date => $now,
+ );
+ $more_records = 0;
+ my %lt = &othdomrole_contexts();
+
+ foreach my $item ('show','page','role','chgstatus','chgadj') {
+ $curr{$item} = $env{'form.'.$item};
+ }
+ ($curr{'rolereq_start_date'},$curr{'rolereq_end_date'}) =
+ &Apache::lonuserutils::get_dates_from_form('rolereq_start_date','rolereq_end_date');
+ foreach my $key (keys(%defaults)) {
+ if ($curr{$key} eq '') {
+ $curr{$key} = $defaults{$key};
+ }
+ }
+ $minshown = 1;
+ my $count = 0;
+ if ($curr{'show'} =~ /\D/) {
+ $curr{'page'} = 1;
+ } else {
+ $maxshown = $curr{'page'} * $curr{'show'};
+ if ($curr{'page'} > 1) {
+ $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'};
+ }
+ }
+ $output .= &print_filter_menu($context,'changequeue',\%curr,$crstype);
+
+ my $showntableheader = 0;
+
+ # Table Header
+ my $tableheader =
+ &Apache::loncommon::start_data_table().
+ &Apache::loncommon::start_data_table_header_row().
+ ''.&mt('Date requested').' '.
+ ''.&mt('Role').' ';
+ if ($context eq 'course') {
+ $tableheader .= ''.&mt('Section').' ';
+ }
+ $tableheader .= ''.&mt('Requested for').' '.
+ ''.&mt('Request status').' '.
+ ''.&mt('Adjudicator').' '.
+ &Apache::loncommon::end_data_table_header_row();
+
+ my @sortedtimes = sort {$a <=> $b} (keys(%{$queue}));
+ my $count = 0;
+ foreach my $item (@sortedtimes) {
+ next if (($item < $curr{'rolereq_start_date'}) ||
+ ($item > $curr{'rolereq_end_date'}));
+ if (ref($queue->{$item}) eq 'ARRAY') {
+ foreach my $request (sort(@{$queue->{$item}})) {
+ if ($curr{'show'} !~ /\D/) {
+ if ($count >= $curr{'page'} * $curr{'show'}) {
+ $more_records = 1;
+ last;
+ }
+ }
+ my ($showtime,$showsec,$namelink,$showrole,$showadj,
+ $showstatus,$id);
+ $showtime = &Apache::lonlocal::locallocaltime($item);
+ my ($uname,$udom,$role,$adj,$requester,$sec) = split(/:/,$request);
+ $id = join(':',($uname,$udom,$role));
+ if ($context eq 'course') {
+ $id .= ':'.$sec;
+ }
+ if ($curr{'role'} ne 'any') {
+ if ($curr{'role'} eq 'cr') {
+ next unless ($role =~ m{^cr/});
+ } else {
+ next unless ($role eq $curr{'role'});
+ }
+ }
+ if ($curr{'chgstatus'} ne 'any') {
+ next if ($status->{$id} ne $curr{'chgstatus'});
+ }
+ if ($curr{'chgadj'} ne 'any') {
+ next if ($adj ne $curr{'chgadj'});
+ }
+ if (($context eq 'course') && ($viewablesec ne '')) {
+ next if ($sec ne $viewablesec);
+ }
+ $count ++;
+ next if ($count < $minshown);
+ unless ($showntableheader) {
+ $output .= $tableheader;
+ $showntableheader = 1;
+ }
+ $showrole = &Apache::lonnet::plaintext($role,$crstype);
+ $showstatus = $lt{$status->{$id}};
+ $showadj = $lt{$adj};
+ unless (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
+ $namelink = &Apache::loncommon::plainname($uname,$udom)." ($uname:$udom)";
+ }
+ if ($context eq 'course') {
+ $showsec = $sec;
+ if ($showsec eq '') {
+ $showsec = &mt('none');
+ }
+ }
+ $output .= &Apache::loncommon::start_data_table_row()."\n".
+ ''.$showtime.' '."\n".
+ ''.$showrole.' '."\n";
+ if ($context eq 'course') {
+ $output .= ''.$showsec.' '."\n";
+ }
+ $output .= ''.$namelink.' '."\n".
+ ''.$showstatus.' '."\n".
+ ''.$showadj.' '."\n".
+ &Apache::loncommon::end_data_table_row()."\n";
+ }
+ }
+ }
+
+ if ($showntableheader) { # Table footer, if content displayed above
+ $output .= &Apache::loncommon::end_data_table().
+ &queued_role_navlinks(\%curr,$more_records);
+ } else { # No content displayed above
+ $output .= ''.
+ &mt('There are no records to display.').
+ '
';
+ }
+ $output .= ' ';
+ return $output;
+}
+
+sub queued_log_js {
+ my ($formname) = @_;
+ return <<"ENDSCRIPT";
+
+function chgPage(caller) {
+ if (caller == 'previous') {
+ document.$formname.page.value --;
+ }
+ if (caller == 'next') {
+ document.$formname.page.value ++;
+ }
+ document.$formname.submit();
return;
}
+ENDSCRIPT
+}
+
+sub queued_role_navlinks {
+ my ($curr,$more_records) = @_;
+ return unless(ref($curr) eq 'HASH');
+ # Navigation Buttons
+ my $nav_links;
+ if (($curr->{'page'} > 1) || ($more_records)) {
+ $nav_links = '';
+ if (($curr->{'page'} > 1) && ($curr->{'show'} !~ /\D/)) {
+ $nav_links .= ' ';
+ }
+ if ($more_records) {
+ $nav_links .= ' ';
+ }
+ $nav_links .= '
';
+ }
+ return $nav_links;
+}
+
+sub print_filter_menu {
+ my ($context,$formname,$curr,$crstype) = @_;
+
+ my $nolink = 1;
+ my $output = ''.
+ ''.&mt('Changes/page:').' '.
+ &Apache::lonmeta::selectbox('show',$curr->{'show'},undef,
+ (&mt('all'),5,10,20,50,100,1000,10000)).
+ ' ';
+ my $startform =
+ &Apache::lonhtmlcommon::date_setter($formname,'rolereq_start_date',
+ $curr->{'rolereq_start_date'},undef,
+ undef,undef,undef,undef,undef,undef,$nolink);
+ my $endform =
+ &Apache::lonhtmlcommon::date_setter($formname,'rolereq_end_date',
+ $curr->{'rolereq_end_date'},undef,
+ undef,undef,undef,undef,undef,undef,$nolink);
+ my %lt = &othdomrole_contexts();
+ $output .= ''.&mt('Time window in which role was requested').': '.
+ ''.&mt('After:').
+ ' '.$startform.' '.
+ ''.&mt('Before:').' '.
+ ''.$endform.'
'.
+ ' '.
+ ' '.
+ ''.&mt('Requested role').': '.
+ '{'role'} eq 'any') {
+ $output .= ' selected="selected"';
+ }
+ $output .= '>'.&mt('Any').' '."\n";
+ my @roles = &Apache::lonuserutils::roles_by_context($context,1,$crstype);
+ foreach my $role (@roles) {
+ my $plrole;
+ if ($role eq 'cr') {
+ $plrole = &mt('Custom Role');
+ } else {
+ $plrole=&Apache::lonnet::plaintext($role,$crstype);
+ }
+ my $selstr = '';
+ if ($role eq $curr->{'role'}) {
+ $selstr = ' selected="selected"';
+ }
+ $output .= ' '.$plrole.' ';
+ }
+ $output .= ' '.
+ ' '.
+ ''.
+ &mt('Request status').': '.
+ ''.
+ '{'chgstatus'} eq 'any') {
+ $output .= ' selected="selected"';
+ }
+ $output .= '>'.&mt('Any').' '."\n";
+ my @possstatus = ('pending','approved','rejected');
+ foreach my $statustype (@possstatus) {
+ my $selstr = '';
+ if ($curr->{'chgstatus'} eq $statustype) {
+ $selstr = ' selected="selected"';
+ }
+ $output .= ''.$lt{$statustype}.' '."\n";
+ }
+ $output .= ' '.
+ ' '.
+ ''.
+ &mt('Adjudicator').': '.
+ ''.
+ '{'adj'} eq 'any') {
+ $output .= ' selected="selected"';
+ }
+ $output .= '>'.&mt('Any').' '."\n";
+ my @possadj = ('domain','user');
+ foreach my $adjtype (@possadj) {
+ my $selstr = '';
+ if ($curr->{'chgadj'} eq $adjtype) {
+ $selstr = ' selected="selected"';
+ }
+ $output .= ''.$lt{$adjtype}.' '."\n";
+ }
+ $output .= ' '
+ .'
';
+
+ # Update Display button
+ $output .= ''.
+ ' '.
+ '
'.
+ ' ';
+ return $output;
+}
+
+sub othdomrole_contexts {
+ my %lt = &Apache::lonlocal::texthash(
+ pending => 'Queued',
+ approved => 'Approved',
+ rejected => 'Rejected',
+ user => 'User who acquires role',
+ );
+ $lt{'domain'} = &mt("[_1] in user's domain",
+ &Apache::lonnet::plaintext('dc'));
+ return %lt;
+}
sub update_request_queue {
my ($context,$cdom,$cnum,$coursedesc) = @_;