Added option to remove timing from periods

This commit is contained in:
PMKuipers 2024-03-10 23:09:33 +01:00
parent 3002a866bb
commit 310f042772
17 changed files with 117 additions and 62 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
define("local_treestudyplan/util/date-helper",["exports"],(function(_exports){function format_date(d,short){d instanceof Date||("number"==typeof d&&(d*=1e3),d=new Date(d));let monthformat="short";return!0===short?monthformat="numeric":!1===short&&(monthformat="long"),d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})}function studyplanDates(plan){let earliestStart=null,latestEnd=null,openEnded=!1;for(const ix in plan.pages){const page=plan.pages[ix],s=new Date(page.startdate);if(page.enddate||(openEnded=!0),(!earliestStart||s<earliestStart)&&(earliestStart=s),page.enddate){const e=new Date(page.enddate);(!latestEnd||e>latestEnd)&&(latestEnd=e)}}return{start:earliestStart,end:openEnded?null:latestEnd}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_days=function(datestr,days){const date=new Date(datestr);return function(date){const d=new Date(date);let month=""+(d.getMonth()+1),day=""+d.getDate();const year=d.getFullYear();month.length<2&&(month="0"+month);day.length<2&&(day="0"+day);return[year,month,day].join("-")}(new Date(date.getTime()+864e5*days))},_exports.datespaninfo=function(first,last){first instanceof Date||(first=new Date(first));last instanceof Date||(last=new Date(last));first.setHours(0),first.setMinutes(0),first.setSeconds(0),first.setMilliseconds(0),last.setHours(23),last.setMinutes(59),last.setSeconds(59),last.setMilliseconds(999);const dayspan=Math.round((last-first+1)/864e5),years=Math.floor(dayspan/365),ydaysleft=dayspan%365,weeks=Math.floor(ydaysleft/7);return{first:first,last:last,totaldays:dayspan,years:years,weeks:weeks,days:ydaysleft%7,formatted:{first:format_date(first),last:format_date(last)}}},_exports.format_date=format_date,_exports.format_datetime=function(d,short){d instanceof Date||("number"==typeof d&&(d*=1e3),d=new Date(d));let monthformat="short";!0===short?monthformat="numeric":!1===short&&(monthformat="long");return d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})+" "+d.toLocaleTimeString(document.documentElement.lang,{timeStyle:"short"})},_exports.studyplanDates=studyplanDates,_exports.studyplanPageTiming=function(page){const now=(new Date).getTime(),start=new Date(page.startdate),end=page.enddate?new Date(page.enddate):null;return start<now?end&&now>end?"past":"present":"future"},_exports.studyplanTiming=function(plan){const now=(new Date).getTime(),dates=studyplanDates(plan);return dates.start<now?dates.end&&now>dates.end?"past":"present":"future"}}));
define("local_treestudyplan/util/date-helper",["exports"],(function(_exports){function format_date(d,short){d instanceof Date||("number"==typeof d&&(d*=1e3),d=new Date(d));let monthformat="short";return!0===short?monthformat="numeric":!1===short&&(monthformat="long"),d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})}function studyplanDates(plan){let earliestStart=null,latestEnd=null,openEnded=!1;for(const ix in plan.pages){const page=plan.pages[ix],s=new Date(page.startdate);if(page.enddate||(openEnded=!0),(!earliestStart||s<earliestStart)&&(earliestStart=s),page.enddate){const e=new Date(page.enddate);(!latestEnd||e>latestEnd)&&(latestEnd=e)}}return{start:earliestStart,end:openEnded?null:latestEnd}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_days=function(datestr,days){const date=new Date(datestr);return function(date){const d=new Date(date);let month=""+(d.getMonth()+1),day=""+d.getDate();const year=d.getFullYear();month.length<2&&(month="0"+month);day.length<2&&(day="0"+day);return[year,month,day].join("-")}(new Date(date.getTime()+864e5*days))},_exports.datespaninfo=function(first,last){first instanceof Date||(first=new Date(first));last instanceof Date||(last=new Date(last));first.setHours(0),first.setMinutes(0),first.setSeconds(0),first.setMilliseconds(0),last.setHours(23),last.setMinutes(59),last.setSeconds(59),last.setMilliseconds(999);const dayspan=Math.round((last-first+1)/864e5),years=Math.floor(dayspan/365),ydaysleft=dayspan%365,weeks=Math.floor(ydaysleft/7);return{first:first,last:last,totaldays:dayspan,years:years,weeks:weeks,days:ydaysleft%7,formatted:{first:format_date(first),last:format_date(last)}}},_exports.format_date=format_date,_exports.format_datetime=function(d,short){d instanceof Date||("number"==typeof d&&(d*=1e3),d=new Date(d));let monthformat="short";!0===short?monthformat="numeric":!1===short&&(monthformat="long");return d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})+" "+d.toLocaleTimeString(document.documentElement.lang,{timeStyle:"short"})},_exports.studyplanDates=studyplanDates,_exports.studyplanPageTiming=function(page){const now=(new Date).getTime();if(page.timeless)return"present";const start=new Date(page.startdate),end=page.enddate?new Date(page.enddate):null;return start<now?end&&now>end?"past":"present":"future"},_exports.studyplanTiming=function(plan){const now=(new Date).getTime();if(!plan.pages&&0==plan.pages.length||plan.pages[0].timeless)return"present";const dates=studyplanDates(plan);return dates.start<now?dates.end&&now>dates.end?"past":"present":"future"}}));
//# sourceMappingURL=date-helper.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -1318,7 +1318,7 @@ export default {
></b-form-input>
</b-col>
</b-row>
<b-row>
<b-row v-if="!value.timeless">
<b-col cols="4">{{ text.studyplan_startdate}}</b-col>
<b-col cols="8">
<b-form-datepicker
@ -1329,7 +1329,7 @@ export default {
></b-form-datepicker>
</b-col>
</b-row>
<b-row>
<b-row v-if="!value.timeless">
<b-col cols="4">{{ text.studyplan_enddate}}</b-col>
<b-col cols="8">
<b-form-datepicker
@ -1708,13 +1708,13 @@ export default {
return show;
},
periodEdited(pi) {
const prev = this.$refs["periodeditor-" + (pi.period - 1)][0];
if(prev) {
prev.refresh();
const prev = this.$refs["periodeditor-" + (pi.period - 1)];
if(prev && prev[0]) {
prev[0].refresh();
}
const next = this.$refs["periodeditor-" + (pi.period + 1)][0];
if(next) {
next.refresh();
const next = this.$refs["periodeditor-" + (pi.period + 1)];
if(next && next[0]) {
next[0].refresh();
}
},
add_day(date,days) {
@ -2544,6 +2544,10 @@ export default {
},
course_period_matches() {
const self=this;
if (self.page.timeless) {
// Always return true in timeless mode.
return true ;
}
if(self.value && self.value.type == 'course'){
self.datechanger.coursespan = datespaninfo(self.value.course.startdate,self.value.course.enddate);
self.datechanger.periodspan = datespaninfo(self.period.startdate,self.endperiod.enddate);
@ -2576,30 +2580,35 @@ export default {
validate_course_period() {
const self = this;
debug.info("Validating course and period");
if(!(self.course_period_matches)){
debug.info("Course timing does not match period timing");
if (! self.page.timeless) {
debug.info("Validating course and period");
if(!(self.course_period_matches)){
debug.info("Course timing does not match period timing");
if(self.value.course.canupdatecourse){
if(!self.hidden || !self.datechanger.globals.default){
// Periods do not match, pop up the date change request
this.$bvModal.show('t-course-timing-matching-'+this.id);
} else if (self.datechanger.globals.defaultvalue){
// go for it without asking
self.change_course_period();
if(self.value.course.canupdatecourse){
if(!self.hidden || !self.datechanger.globals.default){
// Periods do not match, pop up the date change request
this.$bvModal.show('t-course-timing-matching-'+this.id);
} else if (self.datechanger.globals.defaultvalue){
// go for it without asking
self.change_course_period();
}
}
else {
// user is not able to change course timing - show a warning
if(!self.hidden || !self.datechanger.globals.hidewarn){
this.$bvModal.show('t-course-timing-warning-'+this.id);
}
}
}
else {
// user is not able to change course timing - show a warning
if(!self.hidden || !self.datechanger.globals.hidewarn){
this.$bvModal.show('t-course-timing-warning-'+this.id);
}
debug.info("Course timing matches period",self.datechanger);
}
}
else {
debug.info("Course timing matches period",self.datechanger);
debug.info("Skipping course timing check because of timeless mode",self.datechanger);
}
},
},
has_filter() {
const slots = this.page.slots;
},
@ -4202,7 +4211,7 @@ export default {
self.loadingcourses = true;
call([{
methodname: 'local_treestudyplan_map_categories',
args: { studyplanid: self.studyplanid}
args: { studyplan_id: self.studyplanid}
}])[0].then(function(response){
self.courses = response;
self.loadingcourses = false;

View File

@ -59,6 +59,14 @@ export default {
};
},
computed: {
timeless() {
const plan = this.value;
if (!plan.pages || plan.pages.length == 0 || plan.pages[0].timeless) {
return true;
} else {
return false;
}
},
timing(){
return studyplanTiming(this.value);
},
@ -110,7 +118,7 @@ export default {
</div>
<slot></slot>
<template #footer>
<span :class="'t-timing-'+timing" v-html="dates.start + ' - '+ dates.end"></span>
<span v-if="!timeless" :class="'t-timing-'+timing" v-html="dates.start + ' - '+ dates.end"></span>
<span class="s-studyplan-card-buttons">
<slot name='footer'></slot>
<s-studyplan-details
@ -290,7 +298,8 @@ export default {
</span>
</b-tooltip>
<slot></slot
><p class="s-studyline-header-period-datespan small">
><p v-if="value.startdate > 0"
class="s-studyline-header-period-datespan small">
<span class="date">{{ startdate }}</span> - <span class="date">{{ enddate }}</span>
</p>
<div v-if="current" class='s-studyline-period-highlight'></div>

View File

@ -134,6 +134,7 @@ export function studyplanDates(plan) {
let earliestStart = null;
let latestEnd = null;
let openEnded = false;
for(const ix in plan.pages) {
const page = plan.pages[ix];
const s = new Date(page.startdate);
@ -165,6 +166,12 @@ export function studyplanDates(plan) {
*/
export function studyplanTiming(plan) {
const now = new Date().getTime();
// If timeless or no timing info is available, all plans are present
if (!plan.pages && plan.pages.length == 0 || plan.pages[0].timeless) {
return 'present';
}
const dates = studyplanDates(plan);
if(dates.start < now){
@ -185,6 +192,10 @@ export function studyplanTiming(plan) {
*/
export function studyplanPageTiming(page) {
const now = new Date().getTime();
if (page.timeless) {
return "present";
}
const start = new Date(page.startdate);
const end = (page.enddate)?(new Date(page.enddate)):null;

View File

@ -195,19 +195,21 @@ class studyplan_editform extends formbase {
);
if ($customdata->create) {
// Only add these fields if a new studyplan is created, to easily initialize the first page
$field = 'startdate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
$field = 'enddate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
$timeless = \get_config("local_treestudyplan","timelessperiods");
if ( !$timeless) {
// Only add these fields if a new studyplan is created, to easily initialize the first page
$field = 'startdate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
$field = 'enddate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
}
$field = 'periods';
$mform->addElement('text_integer',$field,
get_string('studyplan_slots','local_treestudyplan'),

View File

@ -159,21 +159,24 @@ class studyplanpage_editform extends formbase {
[]);
$mform->addRule($field, null, 'required', null, 'client');
$field = 'startdate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
$timeless = \get_config("local_treestudyplan","timelessperiods");
if ( !$timeless) {
$field = 'startdate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
$field = 'enddate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
$field = 'enddate';
$mform->addElement('date_selector',$field,
get_string('studyplan_startdate','local_treestudyplan'),
[]);
$mform->addRule($field, null, 'required', null, 'client');
}
$field = 'periods';
$mform->addElement('text_integer',$field,
get_string('studyplan_slots','local_treestudyplan'),
get_string( ($timeless)?'studyplan_slots':'studyplan_periods','local_treestudyplan'),
["unsigned" => true, "nonzero" => true]);
$mform->setType($field, PARAM_INT);
$mform->addRule($field, null, 'required', null, 'client');

View File

@ -238,6 +238,7 @@ class period {
"period" => new \external_value(PARAM_INT, 'period sequence'),
"startdate" => new \external_value(PARAM_TEXT, 'start date of period'),
"enddate" => new \external_value(PARAM_TEXT, 'end date of period'),
"timeless" => new \external_value(PARAM_BOOL, 'Page does not include time information'),
], 'Period info', $value);
}
@ -246,13 +247,15 @@ class period {
* @return array Webservice data model
*/
public function model() {
$timeless = get_config("local_treestudyplan","timelessperiods");
return [
'id' => $this->r->id,
'fullname' => $this->r->fullname,
'shortname' => $this->r->shortname,
'period' => $this->r->period,
'startdate' => $this->r->startdate,
'enddate' => $this->r->enddate,
'startdate' => ($timeless)?0:$this->r->startdate,
'enddate' => ($timeless)?0:$this->r->enddate,
'timeless' => $timeless,
];
}

View File

@ -192,6 +192,7 @@ class studyplanpage {
"enddate" => new \external_value(PARAM_TEXT, 'end date of studyplan'),
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
"perioddesc" => period::page_structure(),
"timeless" => new \external_value(PARAM_BOOL, 'Page does not in'),
], 'Studyplan page basic info', $value);
}
@ -210,6 +211,7 @@ class studyplanpage {
'enddate' => $this->r->enddate,
'timing' => $this->timing(),
"perioddesc" => period::page_model($this),
'timeless' => \get_config("local_treestudyplan","timelessperiods"),
];
}
@ -229,6 +231,7 @@ class studyplanpage {
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
"studylines" => new \external_multiple_structure(studyline::editor_structure()),
"perioddesc" => period::page_structure(),
"timeless" => new \external_value(PARAM_BOOL, 'Page does not include time information'),
], 'Studyplan page full structure', $value);
}
@ -250,6 +253,7 @@ class studyplanpage {
'timing' => $this->timing(),
'studylines' => [],
"perioddesc" => period::page_model($this),
'timeless' => \get_config("local_treestudyplan","timelessperiods"),
];
$children = studyline::find_page_children($this);

View File

@ -114,8 +114,10 @@ $string["settingdesc_enableplansharing"] = 'Allow students to share access to th
$string["setting_limitcourselist"] = 'Limit course list to studyplan category';
$string["settingdesc_limitcourselist"] = 'Limit the list of available courses for a studyplan to the category the studyplan is located in.';
$string["setting_enablecoach"] = 'Enable coach rolae';
$string["setting_enablecoach"] = 'Enable coach role';
$string["settingdesc_enablecoach"] = 'The coach role allows one coach specific access to one studyplan with limited access to modify it.';
$string["setting_timelessperiods"] = 'Timeless periods and pages';
$string["settingdesc_timelessperiods"] = 'Do not include timing info in periods or pages';
$string["setting_courseprogressbar"] = 'Show progress bar in course';
$string["settingdesc_courseprogressbar"] = 'Show a progress bar in the course popup';
@ -123,6 +125,7 @@ $string["settingdesc_courseprogressbar"] = 'Show a progress bar in the course po
$string["setting_infofields_heading"] = 'Extra course information fields';
$string["settingdesc_infofields_heading"] = 'Select up to 5 fields or custom fields to add to the course popup';
$string["infofield_position_above"] = 'Above course results';
$string["infofield_position_below"] = 'Below course results';
$string["infofield_position_header"] = 'Header ';
@ -165,7 +168,8 @@ $string["studyplan_idnumber_ph"] = '';
$string["studyplan_description"] = 'Description';
$string["studyplan_description_ph"] = '';
$string["studyplan_details"] = 'About';
$string["studyplan_slots"] = 'Number of periods in plan';
$string["studyplan_slots"] = 'Number of columns in plan';
$string["studyplan_periods"] = 'Number of periods in plan';
$string["studyplan_startdate"] = 'Start date of plan';
$string["studyplan_enddate"] = 'End date of plan';
$string["studyplan_noneselected"] = "Pick a study plan to start editing";

View File

@ -117,6 +117,8 @@ $string["setting_limitcourselist"] = 'Cursusenlijst beperken tot categorie';
$string["settingdesc_limitcourselist"] = 'Beperk de lijst met beschikbare cursussen om in een studieplan te slepen tot de cateogrie waarin het studieplan zich bevindt.';
$string["setting_enablecoach"] = 'Coach rol inschakelen';
$string["settingdesc_enablecoach"] = 'Een coach kan aan een specifiek studieplan gekoppeld worden om deze te bewerken en studentresultaten te bekijken.';
$string["setting_timelessperiods"] = 'Tabbladen en periodes zonder tijd';
$string["settingdesc_timelessperiods"] = 'Gebruik geen tijdinformatie in perioden en tabbladen';
$string["setting_courseprogressbar"] = 'Toon voortgangsbalk in cursus';
$string["settingdesc_courseprogressbar"] = 'Laat een voortgangsbalk zien in de cursuspopup';
@ -166,7 +168,8 @@ $string["studyplan_idnumber_ph"] = '';
$string["studyplan_description"] = 'Beschrijving';
$string["studyplan_details"] = 'Meer info';
$string["studyplan_description_ph"] = '';
$string["studyplan_slots"] = 'Aantal periodes in studieplan';
$string["studyplan_slots"] = 'Aantal kolommen in studieplan';
$string["studyplan_periods"] = 'Aantal periodes in studieplan';
$string["studyplan_startdate"] = 'Startdatum';
$string["studyplan_enddate"] = 'Einddatum';
$string["studyplan_noneselected"] = "Kies een studieplan uit de lijst";

View File

@ -113,6 +113,13 @@ if ($hassiteconfig) {
true,
));
//get_config("local_treestudyplan","timelessperiods")
$page->add(new admin_setting_configcheckbox('local_treestudyplan/timelessperiods',
get_string('setting_timelessperiods', 'local_treestudyplan'),
get_string('settingdesc_timelessperiods', 'local_treestudyplan'),
false,
));
//get_config("local_treestudyplan","limitcourselist")
$page->add(new admin_setting_configcheckbox('local_treestudyplan/limitcourselist',
get_string('setting_limitcourselist', 'local_treestudyplan'),

View File

@ -22,7 +22,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
$plugin->version = 2024031002; // YYYYMMDDHH (year, month, day, iteration).
$plugin->version = 2024031003; // YYYYMMDDHH (year, month, day, iteration).
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
$plugin->release = "1.1.6";