Implemented period editing in studyplan editor

This commit is contained in:
PMKuipers 2023-07-28 23:43:11 +02:00
parent 009ec66c10
commit 19cc98a893
6 changed files with 224 additions and 58 deletions

View File

@ -8,7 +8,7 @@
import {SimpleLine} from './simpleline'; import {SimpleLine} from './simpleline';
import {get_strings} from 'core/str'; import {get_strings} from 'core/str';
import {load_strings} from './string-helper'; import {load_strings, format_date} from './string-helper';
import {call} from 'core/ajax'; import {call} from 'core/ajax';
import notification from 'core/notification'; import notification from 'core/notification';
import {svgarcpath} from './svgarc'; import {svgarcpath} from './svgarc';
@ -706,7 +706,17 @@ export default {
}; };
}, },
computed: { computed: {
startdate(){
return format_date(this.value.course.startdate);
},
enddate(){
if(this.value.course.enddate){
return format_date(this.value.course.enddate);
}
else {
return this.text.noenddate;
}
}
}, },
created(){ created(){
const self = this; const self = this;
@ -749,7 +759,7 @@ export default {
<b-col md="1"> <b-col md="1">
<span <span
:title="text['coursetiming_'+value.course.timing]" :title="text['coursetiming_'+value.course.timing]"
v-b-popover.hover.top="value.course.startdate+' - '+value.course.enddate" v-b-popover.hover.top="startdate+' - '+enddate"
:class="'r-timing-indicator timing-'+value.course.timing"></span> :class="'r-timing-indicator timing-'+value.course.timing"></span>
</b-col> </b-col>
<b-col md="11"> <b-col md="11">
@ -819,7 +829,7 @@ export default {
</div> </div>
<div :class="'r-timing-'+value.course.timing"> <div :class="'r-timing-'+value.course.timing">
{{text['coursetiming_'+value.course.timing]}}<br> {{text['coursetiming_'+value.course.timing]}}<br>
{{ value.course.startdate }} - {{ value.course.enddate }} {{ startdate }} - {{ enddate }}
</div> </div>
</div> </div>
</template> </template>
@ -1152,6 +1162,17 @@ export default {
} }
return status; return status;
},
startdate(){
return format_date(this.value.course.startdate);
},
enddate(){
if(this.value.course.enddate){
return format_date(this.value.course.enddate);
}
else {
return this.text.noenddate;
}
} }
}, },
created(){ created(){
@ -1234,7 +1255,7 @@ export default {
<b-col md="1"> <b-col md="1">
<span <span
:title="text['coursetiming_'+value.course.timing]" :title="text['coursetiming_'+value.course.timing]"
v-b-popover.hover.top="value.course.startdate+' - '+value.course.enddate" v-b-popover.hover.top="startdate+' - '+enddate"
:class="'r-timing-indicator timing-'+value.course.timing"></span> :class="'r-timing-indicator timing-'+value.course.timing"></span>
</b-col> </b-col>
<b-col md="11"> <b-col md="11">
@ -1279,7 +1300,7 @@ export default {
</div> </div>
<div :class="'r-timing-'+value.course.timing"> <div :class="'r-timing-'+value.course.timing">
{{ text['coursetiming_'+value.course.timing] }}<br> {{ text['coursetiming_'+value.course.timing] }}<br>
{{ value.course.startdate }} - {{ value.course.enddate }} {{ startdate }} - {{ enddate }}
</div> </div>
</div> </div>
</template> </template>

View File

@ -10,13 +10,14 @@ import {SimpleLine} from "./simpleline";
import {call} from 'core/ajax'; import {call} from 'core/ajax';
import notification from 'core/notification'; import notification from 'core/notification';
import {get_strings} from 'core/str'; import {get_strings} from 'core/str';
import {load_stringkeys, load_strings} from './string-helper'; import {load_stringkeys, load_strings, format_date} from './string-helper';
import {objCopy,transportItem} from './studyplan-processor'; import {objCopy,transportItem} from './studyplan-processor';
import Debugger from './debugger'; import Debugger from './debugger';
import {download,upload} from './downloader'; import {download,upload} from './downloader';
const STUDYPLAN_EDITOR_FIELDS = ['name','shortname','description','context_id', const STUDYPLAN_EDITOR_FIELDS = ['name','shortname','description','context_id',
'slots','startdate','enddate','aggregation','aggregation_config']; 'slots','startdate','enddate','aggregation','aggregation_config'];
const PERIOD_EDITOR_FIELDS = ['fullname','shortname','startdate','enddate'];
export default { export default {
STUDYPLAN_EDITOR_FIELDS: STUDYPLAN_EDITOR_FIELDS, // make copy available in plugin STUDYPLAN_EDITOR_FIELDS: STUDYPLAN_EDITOR_FIELDS, // make copy available in plugin
@ -140,6 +141,13 @@ export default {
setting_bistate_accept_pending_submitted: 'setting_bistate_accept_pending_submitted', setting_bistate_accept_pending_submitted: 'setting_bistate_accept_pending_submitted',
settingdesc_bistate_accept_pending_submitted: 'settingdesc_bistate_accept_pending_submitted', settingdesc_bistate_accept_pending_submitted: 'settingdesc_bistate_accept_pending_submitted',
}, },
period_edit: {
edit: 'period_edit',
fullname: 'studyplan_name',
shortname: 'studyplan_shortname',
startdate: 'studyplan_startdate',
enddate: 'studyplan_enddate',
},
studyplan_associate: { studyplan_associate: {
associations: 'associations', associations: 'associations',
associated_cohorts: 'associated_cohorts', associated_cohorts: 'associated_cohorts',
@ -1044,6 +1052,120 @@ export default {
` `
}); });
/*******************
*
* Period editor
*
*************/
Vue.component('t-period-edit', {
props: {
'value' :{
type: Object,
default(){ return null;},
},
'type' :{
type: String,
default() { return "link";},
},
'variant' : {
type: String,
default() { return "";},
}
},
data() {
return {
show: false,
editdata: {
fullname: '',
shortname: '',
startdate: (new Date()).getFullYear() + '-08-01',
enddate: ((new Date()).getFullYear()+1) + '-08-01',
},
text: strings.period_edit,
};
},
created() {
},
mounted() {
},
updated() {
},
computed: {
},
methods: {
editStart(){
objCopy(this.editdata,this.value,PERIOD_EDITOR_FIELDS);
this.show = true;
},
editFinish(){
const self = this;
let args = { 'id': this.value.id };
let method = 'local_treestudyplan_edit_period';
objCopy(args,this.editdata,PERIOD_EDITOR_FIELDS);
call([{
methodname: method,
args: args
}])[0].done(function(response){
objCopy(self.value,response,PERIOD_EDITOR_FIELDS);
self.$emit('input',self.value);
}).fail(notification.exception);
},
}
,
template:
`
<span class='t-period-edit'>
<b-button :variant="variant" v-if='type == "button"' @click.prevent='editStart()'
><slot><i class='fa fa-pencil'></i></slot></b-button>
<a variant="variant" v-else href='#' @click.prevent='editStart()'
><slot><i class='fa fa-pencil'></i></slot></a>
<b-modal
v-model="show"
size="lg"
ok-variant="primary"
:title="text.period_edit"
@ok="editFinish()"
:ok-disabled="Math.min(editdata.fullname.length,editdata.shortname.length) == 0"
>
<b-container>
<b-row>
<b-col cols="4">{{ text.fullname}}</b-col>
<b-col cols="8">
<b-form-input v-model="editdata.fullname"
:state='editdata.fullname.length>0'
></b-form-input>
</b-col>
</b-row>
<b-row>
<b-col cols="4">{{ text.shortname}}</b-col>
<b-col cols="8">
<b-form-input v-model="editdata.shortname"
:state='editdata.shortname.length>0'
></b-form-input>
</b-col>
</b-row>
<b-row>
<b-col cols="4">{{ text.studyplan_startdate}}</b-col>
<b-col cols="8">
<b-form-datepicker v-model="editdata.startdate"></b-form-datepicker>
</b-col>
</b-row>
<b-row>
<b-col cols="4">{{ text.studyplan_enddate}}</b-col>
<b-col cols="8">
<b-form-datepicker v-model="editdata.enddate" ></b-form-datepicker>
</b-col>
</b-row>
</b-container>
</b-modal>
</span>
`
});
/* /*
* T-STUDYPLAN * T-STUDYPLAN
*/ */
@ -1384,6 +1506,7 @@ export default {
<s-studyline-header-period <s-studyline-header-period
v-if="index > 0" v-if="index > 0"
v-model="page.perioddesc[index-1]" v-model="page.perioddesc[index-1]"
><t-period-edit v-model="page.perioddesc[index-1]"></t-period-edit
></s-studyline-header-period> ></s-studyline-header-period>
<div class="s-studyline-header-filter"></div> <div class="s-studyline-header-filter"></div>
</template> </template>
@ -2315,7 +2438,19 @@ export default {
} else { } else {
return "exclamation-circle"; return "exclamation-circle";
} }
},
startdate(){
return format_date(this.value.course.startdate);
},
enddate(){
if(this.value.course.enddate){
return format_date(this.value.course.enddate);
}
else {
return this.text.noenddate;
}
} }
}, },
methods: { methods: {
hasGrades() { hasGrades() {
@ -2376,7 +2511,7 @@ export default {
<b-col md="1"> <b-col md="1">
<span <span
:title="text['coursetiming_'+value.course.timing]" :title="text['coursetiming_'+value.course.timing]"
v-b-popover.hover.top="value.course.startdate+' - '+value.course.enddate" v-b-popover.hover.top="startdate+' - '+enddate"
:class="'t-timing-indicator timing-'+value.course.timing"></span> :class="'t-timing-indicator timing-'+value.course.timing"></span>
</b-col> </b-col>
<b-col md="11"> <b-col md="11">
@ -2412,7 +2547,7 @@ export default {
<div class="r-course-detail-header-right"> <div class="r-course-detail-header-right">
<div :class="'r-timing-'+value.course.timing"> <div :class="'r-timing-'+value.course.timing">
{{text['coursetiming_'+value.course.timing]}}<br> {{text['coursetiming_'+value.course.timing]}}<br>
{{ value.course.startdate }} - {{ value.course.enddate }} {{ startdate }} - {{ enddate }}
</div> </div>
</div> </div>
</template> </template>

View File

@ -64,57 +64,60 @@ export function ProcessStudyplans(studyplans){
*/ */
export function ProcessStudyplan(studyplan){ export function ProcessStudyplan(studyplan){
let connections = {}; let connections = {};
for(const il in studyplan.studylines) { for(const ip in studyplan.pages){
const line = studyplan.studylines[il]; const page = studyplan.pages[ip];
for(const il in page.studylines) {
const line = page.studylines[il];
for(const is in line.slots ) { for(const is in line.slots ) {
const slot = line.slots[is]; const slot = line.slots[is];
if(slot.competencies !== undefined){ if(slot.competencies !== undefined){
for(const ic in slot.competencies){ for(const ic in slot.competencies){
const itm = slot.competencies[ic]; const itm = slot.competencies[ic];
for(const idx in itm.connections.in) { for(const idx in itm.connections.in) {
const conn = itm.connections.in[idx]; const conn = itm.connections.in[idx];
if(conn.id in connections){ if(conn.id in connections){
itm.connections[idx] = connections[conn.id]; itm.connections[idx] = connections[conn.id];
} else { } else {
connections[conn.id] = conn; connections[conn.id] = conn;
}
} }
} for(const idx in itm.connections.out) {
for(const idx in itm.connections.out) { const conn = itm.connections.out[idx];
const conn = itm.connections.out[idx];
if(conn.id in connections){ if(conn.id in connections){
itm.connections[idx] = connections[conn.id]; itm.connections[idx] = connections[conn.id];
} else { } else {
connections[conn.id] = conn; connections[conn.id] = conn;
}
} }
} }
} }
}
if(slot.filters !== undefined){ if(slot.filters !== undefined){
for(const ix in slot.filters){ for(const ix in slot.filters){
const itm = slot.filters[ix]; const itm = slot.filters[ix];
for(const idx in itm.connections.in) { for(const idx in itm.connections.in) {
const conn = itm.connections.in[idx]; const conn = itm.connections.in[idx];
if(conn.id in connections){ if(conn.id in connections){
itm.connections[idx] = connections[conn.id]; itm.connections[idx] = connections[conn.id];
} else { } else {
connections[conn.id] = conn; connections[conn.id] = conn;
}
} }
} for(const idx in itm.connections.out) {
for(const idx in itm.connections.out) { const conn = itm.connections.out[idx];
const conn = itm.connections.out[idx];
if(conn.id in connections){ if(conn.id in connections){
itm.connections[idx] = connections[conn.id]; itm.connections[idx] = connections[conn.id];
} else { } else {
connections[conn.id] = conn; connections[conn.id] = conn;
}
} }
} }
} }

View File

@ -4,7 +4,7 @@
/*eslint-env es6*/ /*eslint-env es6*/
// Put this file in path/to/plugin/amd/src // Put this file in path/to/plugin/amd/src
import {load_strings} from './string-helper'; import {load_strings, format_date} from './string-helper';
export default { export default {
studyplanTiming(a) { studyplanTiming(a) {
@ -60,17 +60,11 @@ export default {
return timing; return timing;
}, },
startdate(){ startdate(){
const opts = { return format_date(this.value.pages[0].startdate);
year: 'numeric', month: 'short', day: 'numeric'
};
return new Date(this.value.pages[0].startdate).toLocaleDateString(document.documentElement.lang,opts);
}, },
enddate(){ enddate(){
if(this.value.enddate){ if(this.value.enddate){
const opts = { return format_date(this.value.pages[0].enddate);
year: 'numeric', month: 'short', day: 'numeric'
};
return new Date(this.value.pages[0].enddate).toLocaleDateString(document.documentElement.lang,opts);
} }
else { else {
return this.text.noenddate; return this.text.noenddate;
@ -162,7 +156,12 @@ export default {
} }
}, },
computed: { computed: {
startdate(){
return format_date(this.value.startdate);
},
enddate(){
return format_date(this.value.enddate);
}
}, },
data() { data() {
return { return {
@ -170,7 +169,11 @@ export default {
}, },
template: ` template: `
<div class="s-studyline-header-period" ref="main" <div class="s-studyline-header-period" ref="main"
><abbr v-b-tooltip.hover :title="value.fullname">{{ value.shortname }}</abbr> ><p><abbr v-b-tooltip.hover :title="value.fullname">{{ value.shortname }}</abbr>
<slot></slot><p
><p class="datespan">
<span class="date">{{ startdate }}</span> - <span class="date">{{ enddate }}</span>
</p>
</div> </div>
`, `,
}); });

View File

@ -583,6 +583,10 @@ a.t-item-course-config {
border-bottom-style: solid; border-bottom-style: solid;
} }
.s-studyline-header-period .datespan{
font-size: 9px;
}
.t-studyline-slot.rightmost, .t-studyline-slot.rightmost,
.r-studyline-slot.rightmost { .r-studyline-slot.rightmost {

View File

@ -1,6 +1,6 @@
<?php <?php
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494) $plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
$plugin->version = 2023072701; // YYYYMMDDHH (year, month, day, iteration) $plugin->version = 2023072801; // YYYYMMDDHH (year, month, day, iteration)
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11) $plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11)
$plugin->dependencies = [ $plugin->dependencies = [