Added corecompletion detailinfo for teacher/editor
This commit is contained in:
parent
0cf5619117
commit
5d12a6c653
2 changed files with 436 additions and 117 deletions
|
@ -163,6 +163,7 @@ export default {
|
||||||
class='r-report-tabs'>
|
class='r-report-tabs'>
|
||||||
<b-list-group-item
|
<b-list-group-item
|
||||||
v-for="(studyplan,planindex) in value"
|
v-for="(studyplan,planindex) in value"
|
||||||
|
:key="studyplan.id"
|
||||||
:active="displayedstudyplan && studyplan.id == displayedstudyplan.id"
|
:active="displayedstudyplan && studyplan.id == displayedstudyplan.id"
|
||||||
button
|
button
|
||||||
@click="selectedstudyplan = studyplan"
|
@click="selectedstudyplan = studyplan"
|
||||||
|
@ -539,7 +540,7 @@ export default {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//TAG: Item Course
|
||||||
Vue.component('r-item-course', {
|
Vue.component('r-item-course', {
|
||||||
props: {
|
props: {
|
||||||
value :{
|
value :{
|
||||||
|
@ -685,6 +686,7 @@ export default {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//TAG: Selected activities dispaly
|
||||||
Vue.component('r-item-studentgrades',{
|
Vue.component('r-item-studentgrades',{
|
||||||
props: {
|
props: {
|
||||||
value : {
|
value : {
|
||||||
|
@ -780,6 +782,7 @@ export default {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//TAG: Core completion version of student course info
|
||||||
Vue.component('r-item-studentcompletion',{
|
Vue.component('r-item-studentcompletion',{
|
||||||
props: {
|
props: {
|
||||||
value : {
|
value : {
|
||||||
|
@ -899,7 +902,7 @@ export default {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//TODO: Implement corecompletion
|
||||||
Vue.component('r-item-teachercourse', {
|
Vue.component('r-item-teachercourse', {
|
||||||
props: {
|
props: {
|
||||||
value :{
|
value :{
|
||||||
|
@ -1028,49 +1031,6 @@ export default {
|
||||||
return "dot-circle-o";
|
return "dot-circle-o";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
is_grading_needed(grade){
|
|
||||||
if(grade.grading){
|
|
||||||
if(grade.grading.ungraded){
|
|
||||||
return 'ungraded';
|
|
||||||
}
|
|
||||||
else if(grade.grading.graded){
|
|
||||||
if(Number(grade.grading.graded) == Number(grade.grading.students)){
|
|
||||||
return 'allgraded';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 'graded';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 'unsubmitted';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 'unknown';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grading_icon(grade){
|
|
||||||
return this.determine_grading_icon(this.is_grading_needed(grade));
|
|
||||||
},
|
|
||||||
includeChanged(newValue,g){
|
|
||||||
call([{
|
|
||||||
methodname: 'local_treestudyplan_include_grade',
|
|
||||||
args: { 'grade_id': g.id,
|
|
||||||
'item_id': this.value.id,
|
|
||||||
'include': newValue,
|
|
||||||
'required': g.required,
|
|
||||||
}
|
|
||||||
}])[0].fail(notification.exception);
|
|
||||||
},
|
|
||||||
requiredChanged(newValue,g){
|
|
||||||
call([{
|
|
||||||
methodname: 'local_treestudyplan_include_grade',
|
|
||||||
args: { 'grade_id': g.id,
|
|
||||||
'item_id': this.value.id,
|
|
||||||
'include': g.selected,
|
|
||||||
'required': newValue,
|
|
||||||
}
|
|
||||||
}])[0].fail(notification.exception);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<b-card no-body :class="'r-item-competency '+ (value.course.amteacher?'r-course-am-teacher':'')">
|
<b-card no-body :class="'r-item-competency '+ (value.course.amteacher?'r-course-am-teacher':'')">
|
||||||
|
@ -1106,10 +1066,11 @@ export default {
|
||||||
<div>
|
<div>
|
||||||
<h1><a :href="(!guestmode)?('/course/view.php?id='+value.course.id):undefined" target="_blank"
|
<h1><a :href="(!guestmode)?('/course/view.php?id='+value.course.id):undefined" target="_blank"
|
||||||
><i class="fa fa-graduation-cap"></i> {{ value.course.fullname }}</a>
|
><i class="fa fa-graduation-cap"></i> {{ value.course.fullname }}</a>
|
||||||
<a v-if="value.course.canselectgradables" href='#'
|
<r-item-teacher-gradepicker v-model="value.course"
|
||||||
v-b-modal="'r-item-course-config-'+value.id"
|
v-if="value.course.grades && value.course.grades.length > 0"
|
||||||
@click.prevent.stop=''
|
:useRequiredGrades="useRequiredGrades"
|
||||||
><i class='fa fa-cog'></i></a>
|
:plan="plan"
|
||||||
|
></r-item-teacher-gradepicker>
|
||||||
</h1>
|
</h1>
|
||||||
{{ value.course.context.path.join(" / ")}}
|
{{ value.course.context.path.join(" / ")}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1125,18 +1086,210 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<r-item-teachergrades
|
||||||
|
v-if='!!value.course.grades && value.course.grades.length > 0'
|
||||||
|
v-model='value.course'
|
||||||
|
:useRequiredGrades="useRequiredGrades"
|
||||||
|
></r-item-teachergrades>
|
||||||
|
<r-item-teachercompletion
|
||||||
|
v-if='!!value.course.completion'
|
||||||
|
v-model='value.course.completion'
|
||||||
|
:course='value.course'
|
||||||
|
></r-item-teachercompletion>
|
||||||
|
</b-modal>
|
||||||
|
|
||||||
|
</b-card>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: Selecte activities to use in grade overview
|
||||||
|
Vue.component('r-item-teacher-gradepicker', {
|
||||||
|
props: {
|
||||||
|
value : {
|
||||||
|
type: Object,
|
||||||
|
default: function(){ return {};},
|
||||||
|
},
|
||||||
|
useRequiredGrades: {
|
||||||
|
type: Boolean,
|
||||||
|
default(){ return null;}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<a v-if="value.canselectgradables" href='#'
|
||||||
|
v-b-modal="'r-item-course-config-'+value.id"
|
||||||
|
@click.prevent.stop=''
|
||||||
|
><i class='fa fa-cog'></i>
|
||||||
|
<b-modal v-if='value.canselectgradables'
|
||||||
|
:id="'r-item-course-config-'+value.id"
|
||||||
|
:title="value.displayname + ' - ' + value.fullname"
|
||||||
|
ok-only
|
||||||
|
scrollable
|
||||||
|
>
|
||||||
|
<template #modal-header>
|
||||||
|
<div>
|
||||||
|
<h1><a :href="'/course/view.php?id='+value.id" target="_blank"
|
||||||
|
><i class="fa fa-graduation-cap"></i> {{ value.fullname }}</a></h1>
|
||||||
|
{{ value.course.context.path.join(" / ")}} / {{value.displayname}}
|
||||||
|
</div>
|
||||||
|
<div class="r-course-detail-header-right">
|
||||||
|
<div :class="'r-timing-'+value.timing">
|
||||||
|
{{text['coursetiming_'+value.timing]}}<br>
|
||||||
|
{{ value.startdate }} - {{ value.enddate }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<b-form-group
|
||||||
|
:label="text.select_grades"
|
||||||
|
><ul class="t-item-module-children">
|
||||||
|
<li class="t-item-course-gradeinfo">
|
||||||
|
<span class='t-item-course-chk-lbl'>{{text.grade_include}}</span
|
||||||
|
><span v-if="useRequiredGrades" class='t-item-course-chk-lbl'>{{text.grade_require}}</span>
|
||||||
|
</li>
|
||||||
|
<li class="t-item-course-gradeinfo" v-for="g in value.grades">
|
||||||
|
<b-form-checkbox inline
|
||||||
|
@change="includeChanged($event,g)" v-model="g.selected"
|
||||||
|
></b-form-checkbox>
|
||||||
|
<b-form-checkbox v-if="useRequiredGrades" inline :disabled="!g.selected"
|
||||||
|
@change="requiredChanged($event,g)" v-model="g.required"
|
||||||
|
></b-form-checkbox>
|
||||||
|
<span :title="g.typename" v-html="g.icon"></span><a
|
||||||
|
:href="g.link" target="_blank">{{g.name}}</a>
|
||||||
|
<s-edit-mod
|
||||||
|
:title="value.fullname"
|
||||||
|
@saved="(fd) => g.name = fd.get('name')"
|
||||||
|
v-if="g.cmid > 0"
|
||||||
|
:cmid="g.cmid"
|
||||||
|
:coursectxid="value.ctxid"
|
||||||
|
genericonly></s-edit-mod>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</b-form-group>
|
||||||
|
</b-modal></a>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: Selected activities dispaly
|
||||||
|
Vue.component('r-item-teachergrades',{
|
||||||
|
props: {
|
||||||
|
value : {
|
||||||
|
type: Object,
|
||||||
|
default: function(){ return {};},
|
||||||
|
},
|
||||||
|
useRequiredGrades: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
txt: {
|
||||||
|
grading: strings.grading,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
pendingsubmission(){
|
||||||
|
let result = false;
|
||||||
|
for(const ix in this.value.grades){
|
||||||
|
const g = this.value.grades[ix];
|
||||||
|
if(g.pendingsubmission){
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
filtered_grades(){
|
||||||
|
return this.value.grades.filter(g => g.selected);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
determine_grading_icon(gradingstate){
|
||||||
|
switch(gradingstate){
|
||||||
|
default: // "nogrades":
|
||||||
|
return "circle-o";
|
||||||
|
case "ungraded":
|
||||||
|
return "exclamation-circle";
|
||||||
|
case "unknown":
|
||||||
|
return "question-circle-o";
|
||||||
|
case "graded":
|
||||||
|
return "check";
|
||||||
|
case "allgraded":
|
||||||
|
return "check";
|
||||||
|
case "unsubmitted":
|
||||||
|
return "dot-circle-o";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grading_icon(grade){
|
||||||
|
return this.determine_grading_icon(this.is_grading_needed(grade));
|
||||||
|
},
|
||||||
|
is_grading_needed(grade){
|
||||||
|
if(grade.grading){
|
||||||
|
if(grade.grading.ungraded){
|
||||||
|
return 'ungraded';
|
||||||
|
}
|
||||||
|
else if(grade.grading.graded){
|
||||||
|
if(Number(grade.grading.graded) == Number(grade.grading.students)){
|
||||||
|
return 'allgraded';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'graded';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'unsubmitted';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
includeChanged(newValue,g){
|
||||||
|
call([{
|
||||||
|
methodname: 'local_treestudyplan_include_grade',
|
||||||
|
args: { 'grade_id': g.id,
|
||||||
|
'item_id': this.value.id,
|
||||||
|
'include': newValue,
|
||||||
|
'required': g.required,
|
||||||
|
}
|
||||||
|
}])[0].fail(notification.exception);
|
||||||
|
},
|
||||||
|
requiredChanged(newValue,g){
|
||||||
|
call([{
|
||||||
|
methodname: 'local_treestudyplan_include_grade',
|
||||||
|
args: { 'grade_id': g.id,
|
||||||
|
'item_id': this.value.id,
|
||||||
|
'include': g.selected,
|
||||||
|
'required': newValue,
|
||||||
|
}
|
||||||
|
}])[0].fail(notification.exception);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div>
|
||||||
<table class="r-item-course-grade-details">
|
<table class="r-item-course-grade-details">
|
||||||
<tr v-for="g in filtered_grades">
|
<tr v-for="g in filtered_grades">
|
||||||
<td><span class="r-activity-icon" :title="g.typename" v-html="g.icon"></span
|
<td><span class="r-activity-icon" :title="g.typename" v-html="g.icon"></span
|
||||||
><a
|
><a
|
||||||
:href="(!guestmode)?(teachermode?g.gradinglink:g.link):undefined"
|
:href="g.gradinglink"
|
||||||
target="_blank" :title="g.name">{{g.name}}</a>
|
target="_blank" :title="g.name">{{g.name}}</a>
|
||||||
<s-edit-mod
|
<s-edit-mod
|
||||||
:title="value.course.fullname"
|
:title="value.fullname"
|
||||||
@saved="(fd) => g.name = fd.get('name')"
|
@saved="(fd) => g.name = fd.get('name')"
|
||||||
v-if="g.cmid > 0"
|
v-if="g.cmid > 0"
|
||||||
:cmid="g.cmid"
|
:cmid="g.cmid"
|
||||||
:coursectxid="value.course.ctxid"
|
:coursectxid="value.ctxid"
|
||||||
genericonly></s-edit-mod>
|
genericonly></s-edit-mod>
|
||||||
<abbr v-if="useRequiredGrades && g.required" :title="text.required_goal"
|
<abbr v-if="useRequiredGrades && g.required" :title="text.required_goal"
|
||||||
:class="'s-required ' + is_grading_needed(g)"
|
:class="'s-required ' + is_grading_needed(g)"
|
||||||
|
@ -1152,59 +1305,131 @@ export default {
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</b-modal>
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
<b-modal v-if='value.course.canselectgradables'
|
//TODO: Core completion version of student course info
|
||||||
:id="'r-item-course-config-'+value.id"
|
Vue.component('r-item-teachercompletion',{
|
||||||
:title="value.course.displayname + ' - ' + value.course.fullname"
|
props: {
|
||||||
|
value : {
|
||||||
|
type: Object,
|
||||||
|
default: function(){ return {};},
|
||||||
|
},
|
||||||
|
guestmode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
course: {
|
||||||
|
type: Object,
|
||||||
|
default: function(){ return {};},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: {
|
||||||
|
completion_incomplete: "completion_incomplete",
|
||||||
|
completion_failed: "completion_failed",
|
||||||
|
completion_pending: "completion_pending",
|
||||||
|
completion_progress: "completion_progress",
|
||||||
|
completion_completed: "completion_completed",
|
||||||
|
completion_good: "completion_good",
|
||||||
|
completion_excellent: "completion_excellent",
|
||||||
|
view_feedback: "view_feedback",
|
||||||
|
coursetiming_past: "coursetiming_past",
|
||||||
|
coursetiming_present: "coursetiming_present",
|
||||||
|
coursetiming_future: "coursetiming_future",
|
||||||
|
required_goal: "required_goal",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
const self = this;
|
||||||
|
// Get text strings for condition settings
|
||||||
|
let stringkeys = [];
|
||||||
|
for(const key in this.text){
|
||||||
|
stringkeys.push({ key: key, component: 'local_treestudyplan'});
|
||||||
|
}
|
||||||
|
get_strings(stringkeys).then(function(strings){
|
||||||
|
let i = 0;
|
||||||
|
for(const key in self.text){
|
||||||
|
self.text[key] = strings[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
completion_icon(completion) {
|
||||||
|
switch(completion){
|
||||||
|
case "progress":
|
||||||
|
return "exclamation-circle";
|
||||||
|
case "complete":
|
||||||
|
return "check-circle";
|
||||||
|
case "complete-pass":
|
||||||
|
return "check-circle";
|
||||||
|
case "complete-fail":
|
||||||
|
return "times-circle";
|
||||||
|
default: // case "incomplete"
|
||||||
|
return "circle-o";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
completion_tag(cgroup){
|
||||||
|
return cgroup.completion?'completed':'incomplete';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<table class="r-item-course-grade-details">
|
||||||
|
<template v-for='cgroup in value.conditions'>
|
||||||
|
<tr>
|
||||||
|
<th colspan='2'>{{cgroup.title}}</th>
|
||||||
|
<th><r-progress-circle
|
||||||
|
:value='cgroup.progress'
|
||||||
|
:max='cgroup.count'
|
||||||
|
:class="'r-completion-'+cgroup.status"
|
||||||
|
:title="text['completion_'+cgroup.status]"
|
||||||
|
></r-progress-circle></th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for='ci in cgroup.items'>
|
||||||
|
<td><span v-if='guestmode'>{{ci.title}}</span>
|
||||||
|
<span v-else v-html='ci.details.criteria'></span>
|
||||||
|
<abbr v-if="ci.details.requirement" :title="ci.details.requirement"
|
||||||
|
:class="'s-required ' + ci.status"
|
||||||
|
><i class='fa fa-questionmark' ></i
|
||||||
|
></abbr>
|
||||||
|
<td><span :class="' r-completion-'+ci.status">{{ci.grade}}</span></td>
|
||||||
|
<td><i :class="'fa fa-'+completion_icon(ci.status)+' r-completion-'+ci.status"
|
||||||
|
:title="text['completion_'+ci.status]"></i>
|
||||||
|
<i v-if='ci.pending' :title="text['completion_pending']"
|
||||||
|
class="r-pendingsubmission fa fa-clock-o"></i>
|
||||||
|
</td>
|
||||||
|
<td v-if="ci.feedback">
|
||||||
|
<a v-b-modal="'r-grade-feedback-'+ci.id"
|
||||||
|
href="#"
|
||||||
|
>{{ text["view_feedback"]}}</a>
|
||||||
|
<b-modal
|
||||||
|
:id="'r-grade-feedback-'+ci.id"
|
||||||
|
size="sm"
|
||||||
ok-only
|
ok-only
|
||||||
|
centered
|
||||||
scrollable
|
scrollable
|
||||||
>
|
>
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<div>
|
<h2><i class="fa fa-graduation-cap"></i>{{ course.fullname }}</h2><br>
|
||||||
<h1><a :href="'/course/view.php?id='+value.course.id" target="_blank"
|
<span class="r-activity-icon" :title="ci.typename" v-html="ci.icon"></span>{{ci.name}}
|
||||||
><i class="fa fa-graduation-cap"></i> {{ value.course.fullname }}</a></h1>
|
|
||||||
{{ value.course.context.path.join(" / ")}} / {{value.course.displayname}}
|
|
||||||
</div>
|
|
||||||
<div class="r-course-detail-header-right">
|
|
||||||
<div :class="'r-timing-'+value.course.timing">
|
|
||||||
{{text['coursetiming_'+value.course.timing]}}<br>
|
|
||||||
{{ value.course.startdate }} - {{ value.course.enddate }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<b-form-group
|
<span v-html="ci.feedback"></span>
|
||||||
:label="text.select_grades"
|
|
||||||
><ul class="t-item-module-children">
|
|
||||||
<li class="t-item-course-gradeinfo">
|
|
||||||
<span class='t-item-course-chk-lbl'>{{text.grade_include}}</span
|
|
||||||
><span v-if="useRequiredGrades" class='t-item-course-chk-lbl'>{{text.grade_require}}</span>
|
|
||||||
</li>
|
|
||||||
<li class="t-item-course-gradeinfo" v-for="g in value.course.grades">
|
|
||||||
<b-form-checkbox inline
|
|
||||||
@change="includeChanged($event,g)" v-model="g.selected"
|
|
||||||
></b-form-checkbox>
|
|
||||||
<b-form-checkbox v-if="useRequiredGrades" inline :disabled="!g.selected"
|
|
||||||
@change="requiredChanged($event,g)" v-model="g.required"
|
|
||||||
></b-form-checkbox>
|
|
||||||
<span :title="g.typename" v-html="g.icon"></span><a
|
|
||||||
:href="g.link" target="_blank">{{g.name}}</a>
|
|
||||||
<s-edit-mod
|
|
||||||
:title="value.course.fullname"
|
|
||||||
@saved="(fd) => g.name = fd.get('name')"
|
|
||||||
v-if="g.cmid > 0"
|
|
||||||
:cmid="g.cmid"
|
|
||||||
:coursectxid="value.course.ctxid"
|
|
||||||
genericonly></s-edit-mod>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</b-form-group>
|
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
</td>
|
||||||
</b-card>
|
</tr>
|
||||||
|
</template>
|
||||||
|
</table>
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Vue.component('r-grading-bar',{
|
Vue.component('r-grading-bar',{
|
||||||
props: {
|
props: {
|
||||||
value : {
|
value : {
|
||||||
|
|
|
@ -55,11 +55,12 @@ class corecompletioninfo {
|
||||||
return new \external_single_structure([
|
return new \external_single_structure([
|
||||||
"title" => new \external_value(PARAM_TEXT,'name of subitem',VALUE_OPTIONAL),
|
"title" => new \external_value(PARAM_TEXT,'name of subitem',VALUE_OPTIONAL),
|
||||||
"link" => new \external_value(PARAM_TEXT, 'optional link to more details',VALUE_OPTIONAL),
|
"link" => new \external_value(PARAM_TEXT, 'optional link to more details',VALUE_OPTIONAL),
|
||||||
// ADD BELOW IF NEEDED - try using name, description and link fields first
|
"details" => new \external_single_structure([
|
||||||
/*
|
"type" => new \external_value(PARAM_RAW, 'type',VALUE_OPTIONAL),
|
||||||
"required_grade" => new \external_value(PARAM_TEXT, 'required_grade',VALUE_OPTIONAL),
|
"criteria" => new \external_value(PARAM_RAW, 'criteria',VALUE_OPTIONAL),
|
||||||
"course_link" => course_info::simple_structure(VALUE_OPTIONAL),
|
"requirement" => new \external_value(PARAM_RAW, 'requirement',VALUE_OPTIONAL),
|
||||||
*/
|
"status" => new \external_value(PARAM_RAW, 'status',VALUE_OPTIONAL),
|
||||||
|
]),
|
||||||
], 'completion type',$value);
|
], 'completion type',$value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,11 +93,6 @@ class corecompletioninfo {
|
||||||
"status" => new \external_value(PARAM_RAW, 'status',VALUE_OPTIONAL),
|
"status" => new \external_value(PARAM_RAW, 'status',VALUE_OPTIONAL),
|
||||||
]),
|
]),
|
||||||
"link" => new \external_value(PARAM_TEXT, 'optional link to more details',VALUE_OPTIONAL),
|
"link" => new \external_value(PARAM_TEXT, 'optional link to more details',VALUE_OPTIONAL),
|
||||||
// ADD BELOW IF NEEDED - try using name, description and link fields first
|
|
||||||
/*
|
|
||||||
"required_grade" => new \external_value(PARAM_TEXT, 'required_grade',VALUE_OPTIONAL),
|
|
||||||
"course_link" => course_info::simple_structure(VALUE_OPTIONAL),
|
|
||||||
*/
|
|
||||||
"completed" => new \external_value(PARAM_BOOL, 'simple completed or not'),
|
"completed" => new \external_value(PARAM_BOOL, 'simple completed or not'),
|
||||||
"status" => new \external_value(PARAM_TEXT, 'extended completion status ["incomplete","progress","complete", "complete-pass","complete-fail"]'),
|
"status" => new \external_value(PARAM_TEXT, 'extended completion status ["incomplete","progress","complete", "complete-pass","complete-fail"]'),
|
||||||
"pending" => new \external_value(PARAM_BOOL, 'optional pending state, for submitted but not yet reviewed activities',VALUE_OPTIONAL),
|
"pending" => new \external_value(PARAM_BOOL, 'optional pending state, for submitted but not yet reviewed activities',VALUE_OPTIONAL),
|
||||||
|
@ -164,28 +160,126 @@ class corecompletioninfo {
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach($criterias as $criteria){
|
foreach($criterias as $criteria){
|
||||||
$iinfo = [
|
// Unfortunately, we cannot easily get the criteria details with get_details() without having a
|
||||||
"title" => $criteria->get_title_detailed(),
|
// user completion object involved, so'we'll have to retrieve the details per completion type
|
||||||
|
// See moodle/completion/criteria/completion_criteria_*.php::get_details() for the code that is
|
||||||
|
// in the code below is based on
|
||||||
|
|
||||||
|
if($type == COMPLETION_CRITERIA_TYPE_SELF){
|
||||||
|
$details = [
|
||||||
|
"type" => $criteria->get_title(),
|
||||||
|
"criteria" => $criteria->get_title(),
|
||||||
|
"requirement" => get_string('markingyourselfcomplete', 'completion'),
|
||||||
|
"status" => "",
|
||||||
];
|
];
|
||||||
|
|
||||||
//TODO: MAKE SURE THIS DATA IS FILLED
|
|
||||||
|
|
||||||
if($type == COMPLETION_CRITERIA_TYPE_ACTIVITY){
|
|
||||||
// If it's an activity completion, add the relevant activity
|
|
||||||
//$cm = $this->modinfo->get_cm($criterias->moduleinstance);
|
|
||||||
// retrieve data for this object
|
|
||||||
//$data = $completion->get_data($cm, false, $userid);
|
|
||||||
}
|
}
|
||||||
else if ($type == COMPLETION_CRITERIA_TYPE_COURSE){
|
else if ($type == COMPLETION_CRITERIA_TYPE_DATE){
|
||||||
// If it's a (sub) course dependency, add the course as a link
|
$details = [
|
||||||
|
"type" => get_string('datepassed', 'completion'),
|
||||||
|
"criteria" => get_string('remainingenroleduntildate', 'completion'),
|
||||||
|
"requirement" => userdate($criteria->timeend, '%d %B %Y'),
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else if ($type == COMPLETION_CRITERIA_TYPE_UNENROL){
|
||||||
|
$details = [
|
||||||
|
"type" => get_string('unenrolment', 'completion'),
|
||||||
|
"criteria" => get_string('unenrolment', 'completion'),
|
||||||
|
"requirement" => get_string('unenrolingfromcourse', 'completion'),
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY){
|
||||||
|
$cm = $this->modinfo->get_cm($criteria->moduleinstance);
|
||||||
|
$details = [
|
||||||
|
"type" => $criteria->get_title(),
|
||||||
|
"criteria" => "", // Will be built in a moment by code copied from completion_criteria_activity.php
|
||||||
|
"requirement" => "", // Will be built momentarily by code copied from completion_criteria_activity.php
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
|
if ($cm->has_view()) {
|
||||||
|
$details['criteria'] = \html_writer::link($cm->url, $cm->get_formatted_name());
|
||||||
|
} else {
|
||||||
|
$details['criteria'] = $cm->get_formatted_name();
|
||||||
|
}
|
||||||
|
// Build requirements
|
||||||
|
$details['requirement'] = array();
|
||||||
|
|
||||||
|
if ($cm->completion == COMPLETION_TRACKING_MANUAL) {
|
||||||
|
$details['requirement'][] = get_string('markingyourselfcomplete', 'completion');
|
||||||
|
} elseif ($cm->completion == COMPLETION_TRACKING_AUTOMATIC) {
|
||||||
|
if ($cm->completionview) {
|
||||||
|
$modulename = core_text::strtolower(get_string('modulename', $criteria->module));
|
||||||
|
$details['requirement'][] = get_string('viewingactivity', 'completion', $modulename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($cm->completiongradeitemnumber)) {
|
||||||
|
$details['requirement'][] = get_string('achievinggrade', 'completion');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cm->completionpassgrade) {
|
||||||
|
$details['requirement'][] = get_string('achievingpassinggrade', 'completion');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$details['requirement'] = implode(', ', $details['requirement']);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ($type == COMPLETION_CRITERIA_TYPE_DURATION){
|
||||||
|
$details = [
|
||||||
|
"type" => get_string('periodpostenrolment', 'completion'),
|
||||||
|
"criteria" => get_string('remainingenroledfortime', 'completion'),
|
||||||
|
"requirement" => get_string('xdays', 'completion', ceil($criteria->enrolperiod / (60*60*24))),
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else if ($type == COMPLETION_CRITERIA_TYPE_GRADE){
|
||||||
|
$details = [
|
||||||
|
"type" => get_string('coursegrade', 'completion'),
|
||||||
|
"criteria" => get_string('graderequired', 'completion'),
|
||||||
|
// TODO: convert to selected representation (letter, percentage, etc)
|
||||||
|
"requirement" => format_float($criteria->gradepass, $decimalpoints),
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
else if ($type == COMPLETION_CRITERIA_TYPE_ROLE){
|
else if ($type == COMPLETION_CRITERIA_TYPE_ROLE){
|
||||||
// If it needs approval by a role, it probably already is in the title
|
$criteria = $criteria->get_title();
|
||||||
|
|
||||||
|
$details = [
|
||||||
|
"type" => get_string('manualcompletionby', 'completion'),
|
||||||
|
"criteria" => $criteria,
|
||||||
|
"requirement" => get_string('markedcompleteby', 'completion', $criteria),
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
else if ($type == COMPLETION_CRITERIA_TYPE_COURSE){
|
||||||
|
$prereq = get_course($criteria->courseinstance);
|
||||||
|
$coursecontext = \context_course::instance($prereq->id, MUST_EXIST);
|
||||||
|
$fullname = format_string($prereq->fullname, true, array('context' => $coursecontext));
|
||||||
|
$details = [
|
||||||
|
"type" => $criteria->get_title(),
|
||||||
|
"criteria" => '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$criteria->courseinstance.'">'.s($fullname).'</a>',
|
||||||
|
"requirement" => get_string('coursecompleted', 'completion'),
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Moodle added a criteria type
|
||||||
|
$details = [
|
||||||
|
"type" => "",
|
||||||
|
"criteria" => "",
|
||||||
|
"requirement" => "",
|
||||||
|
"status" => "",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// only add the items list if we actually have items...
|
// only add the items list if we actually have items...
|
||||||
$cinfo["items"][] = $iinfo;
|
$cinfo["items"][] = [
|
||||||
|
"id" => $criteria->id,
|
||||||
|
"title" => $criteria->get_title_detailed(),
|
||||||
|
"details" => $details,
|
||||||
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$info['conditions'][] = $cinfo;
|
$info['conditions'][] = $cinfo;
|
||||||
|
|
Loading…
Reference in a new issue