From 6b7c3acb3b3cd34a48378f84d1075f319c7ba3db Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Tue, 5 Mar 2024 17:52:52 -0600 Subject: [PATCH] Fill in empty dates with valid dates for date picker groups. This builds on #2348, and was requested by @Alex-Jordan in that pull request (see https://github.com/openwebwork/webwork2/pull/2348#pullrequestreview-1918156425). This makes it so that if a date is not filled in, then it will be filled by javascript with a date as needed to ensure it satisfies the usual date requirements on open, reduced scoring, close, and answer dates. The class value is taken into account for this when editing a set for users. This applies on both the problem set detail page and the user detail page. This javascript is also used on the sets manager page when editing set dates where this change does not apply, but it is designed to still work without conflict there. --- htdocs/js/DatePicker/datepicker.js | 37 ++++++++++++------- .../Instructor/ProblemSetDetail.pm | 3 +- .../UserDetail/set_date_table.html.ep | 3 +- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/htdocs/js/DatePicker/datepicker.js b/htdocs/js/DatePicker/datepicker.js index 767d5ce99b..154cd22dbc 100644 --- a/htdocs/js/DatePicker/datepicker.js +++ b/htdocs/js/DatePicker/datepicker.js @@ -25,17 +25,35 @@ const groupRules = [ open_rule, - document.querySelector('input[id="' + name + '.due_date_id"]'), - document.querySelector('input[id="' + name + '.answer_date_id"]') + document.getElementById(`${name}.due_date_id`), + document.getElementById(`${name}.answer_date_id`) ]; - const reduced_rule = document.querySelector('input[id="' + name + '.reduced_scoring_date_id"]'); + const reduced_rule = document.getElementById(`${name}.reduced_scoring_date_id`); if (reduced_rule) groupRules.splice(1, 0, reduced_rule); + // Compute the time difference between the current browser timezone and the course timezone. + // flatpickr gives the time in the browser's timezone, and this is used to adjust to the course timezone. + // Note that this is in seconds. + const timezoneAdjustment = + new Date(new Date().toLocaleString('en-US')).getTime() - + new Date( + new Date().toLocaleString('en-US', { timeZone: open_rule.dataset.timezone ?? 'America/New_York' }) + ).getTime(); + + const classValues = groupRules.map( + (rule) => + new Date( + parseInt(document.getElementsByName(`${rule.name}.class_value`)[0]?.dataset.classValue || '0') * + 1000 - + timezoneAdjustment + ) + ); + const update = () => { for (let i = 1; i < groupRules.length; ++i) { - const prevFieldDate = groupRules[i - 1].parentNode._flatpickr.selectedDates[0]; - const thisFieldDate = groupRules[i].parentNode._flatpickr.selectedDates[0]; + const prevFieldDate = groupRules[i - 1]?.parentNode._flatpickr.selectedDates[0] || classValues[i - 1]; + const thisFieldDate = groupRules[i]?.parentNode._flatpickr.selectedDates[0] || classValues[i]; if (prevFieldDate && thisFieldDate && prevFieldDate > thisFieldDate) { groupRules[i].parentNode._flatpickr.setDate(prevFieldDate, true); } @@ -47,15 +65,6 @@ luxon.Settings.defaultLocale = rule.dataset.locale ?? 'en'; - // Compute the time difference between the current browser timezone and the course timezone. - // flatpickr gives the time in the browser's timezone, and this is used to adjust to the course timezone. - // Note that this is in seconds. - const timezoneAdjustment = - new Date(new Date().toLocaleString('en-US')).getTime() - - new Date( - new Date().toLocaleString('en-US', { timeZone: rule.dataset.timezone ?? 'America/New_York' }) - ).getTime(); - const fp = flatpickr(rule.parentNode, { allowInput: true, enableTime: true, diff --git a/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm b/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm index 0fbde8b7a1..96e3ab4f94 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -1015,7 +1015,8 @@ sub fieldHTML ($c, $userID, $setID, $problemID, $globalRecord, $userRecord, $fie size => $properties{size} || 5, class => 'form-control-plaintext form-control-sm', 'aria-labelledby' => "$recordType.$recordID.$field.label", - $field =~ /date/ || $field eq 'restricted_release' || $field eq 'source_file' ? (dir => 'ltr') : () + $field =~ /date/ || $field eq 'restricted_release' || $field eq 'source_file' ? (dir => 'ltr') : (), + data => { class_value => $globalValue } ) : '' ) if $forUsers; diff --git a/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep b/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep index 01a2496e96..12fabb25df 100644 --- a/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep +++ b/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep @@ -46,7 +46,8 @@ id => "set.$setID.$field.class_value", readonly => undef, dir => 'ltr', class => 'form-control-plaintext form-control-sm w-auto', size => 16, - defined $userRecord ? ('aria-labelledby' => "set.$setID.${field}_id") : () =%> + defined $userRecord ? ('aria-labelledby' => "set.$setID.${field}_id") : (), + data => { class_value => $globalRecord->$field } =%> % } % if (defined $userRecord) {