Finished custom fields in course popup. Added optional progress bar in course popup bar. Added progress circles to manual aggregation.
This commit is contained in:
parent
5544d57f6b
commit
bfcd41dd81
2
amd/build/report-viewer-components.min.js
vendored
2
amd/build/report-viewer-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/simpleline/simpleline.min.js
vendored
2
amd/build/simpleline/simpleline.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/studyplan-editor-components.min.js
vendored
2
amd/build/studyplan-editor-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/treestudyplan-components.min.js
vendored
2
amd/build/treestudyplan-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/util/date-helper.min.js
vendored
2
amd/build/util/date-helper.min.js
vendored
|
@ -1,3 +1,3 @@
|
||||||
define("local_treestudyplan/util/date-helper",["exports"],(function(_exports){function format_date(d,short){d instanceof Date||(d=new Date(d));let monthformat="short";return short&&(monthformat="numeric"),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.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||(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.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"}}));
|
||||||
|
|
||||||
//# sourceMappingURL=date-helper.min.js.map
|
//# sourceMappingURL=date-helper.min.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1099,6 +1099,26 @@ export default {
|
||||||
else {
|
else {
|
||||||
return this.text.noenddate;
|
return this.text.noenddate;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
courseprogress() {
|
||||||
|
if (!this.value.course.enrolled) {
|
||||||
|
return 0;
|
||||||
|
} else if(this.value.course.completion) {
|
||||||
|
return (this.value.course.completion.progress / this.value.course.completion.count);
|
||||||
|
} else if(this.value.course.competency) {
|
||||||
|
return (this.value.course.competency.progress / this.value.course.competency.count);
|
||||||
|
} else if(this.value.course.grades) {
|
||||||
|
return (this.gradeprogress(this.value.course.grades) / this.value.course.grades.length);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasprogressinfo() {
|
||||||
|
if (!this.value.course.enrolled) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return (this.value.course.completion || this.value.course.competency || this.value.course.grades);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created(){
|
created(){
|
||||||
|
@ -1138,6 +1158,16 @@ export default {
|
||||||
return "check";
|
return "check";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
gradeprogress(grades) {
|
||||||
|
let progress = 0;
|
||||||
|
for (const ix in grades) {
|
||||||
|
const g = grades[ix];
|
||||||
|
if (["completed","excellent","good"].includes(g.completion)) {
|
||||||
|
progress++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return progress;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<div :class="'r-item-competency completion-'+value.completion">
|
<div :class="'r-item-competency completion-'+value.completion">
|
||||||
|
@ -1156,24 +1186,10 @@ export default {
|
||||||
class="r-course-result fa fa-exclamation-triangle t-not-enrolled-alert"
|
class="r-course-result fa fa-exclamation-triangle t-not-enrolled-alert"
|
||||||
:title="text.student_not_tracked"></i>
|
:title="text.student_not_tracked"></i>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if='value.course.completion'>
|
<template v-else-if='hasprogressinfo'>
|
||||||
<r-progress-circle v-if='["failed", "progress","incomplete"].includes(value.completion)'
|
<r-progress-circle v-if='["failed", "progress","incomplete"].includes(value.completion)'
|
||||||
:value='value.course.completion.progress'
|
:value='courseprogress'
|
||||||
:max='value.course.completion.count'
|
:max='1'
|
||||||
:min='0'
|
|
||||||
:class="'r-course-result r-completion-'+value.completion"
|
|
||||||
:icon='circle_icon(value.completion)'
|
|
||||||
:title="text['completion_'+value.completion]"
|
|
||||||
></r-progress-circle>
|
|
||||||
<i v-else v-b-popover.top
|
|
||||||
:class="'r-course-result fa fa-'+completion_icon(value.completion)+
|
|
||||||
' r-completion-'+value.completion"
|
|
||||||
:title="text['completion_'+value.completion]"></i>
|
|
||||||
</template>
|
|
||||||
<template v-else-if='value.course.competency'>
|
|
||||||
<r-progress-circle v-if='["failed", "progress","incomplete"].includes(value.completion)'
|
|
||||||
:value='value.course.competency.progress'
|
|
||||||
:max='value.course.competency.count'
|
|
||||||
:min='0'
|
:min='0'
|
||||||
:class="'r-course-result r-completion-'+value.completion"
|
:class="'r-course-result r-completion-'+value.completion"
|
||||||
:icon='circle_icon(value.completion)'
|
:icon='circle_icon(value.completion)'
|
||||||
|
@ -1205,48 +1221,59 @@ export default {
|
||||||
ok-only
|
ok-only
|
||||||
centered
|
centered
|
||||||
scrollable
|
scrollable
|
||||||
|
header-class="r-item-course-header"
|
||||||
>
|
>
|
||||||
<template #modal-header>
|
<template #modal-header >
|
||||||
<div>
|
<div class="r-item-course-header-details">
|
||||||
<h1><a :href="(!guestmode)?('/course/view.php?id='+value.course.id):undefined" target="_blank"
|
<div>
|
||||||
><i class="fa fa-graduation-cap"></i> {{ value.course.fullname }}</a></h1>
|
<h1><a :href="(!guestmode)?('/course/view.php?id='+value.course.id):undefined" target="_blank"
|
||||||
{{ value.course.context.path.join(" / ")}}
|
><i class="fa fa-graduation-cap"></i> {{ value.course.fullname }}</a></h1>
|
||||||
</div>
|
{{ value.course.context.path.join(" / ")}}
|
||||||
<div class="r-course-detail-header-right">
|
|
||||||
<div class="r-completion-detail-header">
|
|
||||||
<template v-if='!value.course.enrolled'>
|
|
||||||
{{text.not_enrolled}}
|
|
||||||
<i v-b-popover.top
|
|
||||||
class="r-course-result fa fa-exclamation-triangle t-not-enrolled-alert"
|
|
||||||
:title="text.student_not_tracked"></i>
|
|
||||||
</template>
|
|
||||||
<template v-else-if='value.course.completion'>
|
|
||||||
{{text['completion_'+value.completion]}}
|
|
||||||
<r-progress-circle v-if='["failed","progress","incomplete"].includes(value.completion)'
|
|
||||||
:value='value.course.completion.progress'
|
|
||||||
:max='value.course.completion.count'
|
|
||||||
:min='0'
|
|
||||||
:title="text['completion_'+value.completion]"
|
|
||||||
:class="'r-progress-circle-popup r-completion-'+value.completion"
|
|
||||||
:icon='circle_icon(value.completion)'
|
|
||||||
></r-progress-circle
|
|
||||||
><i v-else v-b-popover.top
|
|
||||||
:class="'fa fa-'+completion_icon(value.completion)+
|
|
||||||
' r-progress-icon-popup r-completion-'+value.completion"
|
|
||||||
:title="text['completion_'+value.completion]"></i>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
{{text['completion_'+value.completion]}}
|
|
||||||
<i :class="'fa fa-'+completion_icon(value.completion)+' r-completion-'+value.completion"
|
|
||||||
:title="text['completion_'+value.completion]"></i>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
<div :class="'r-timing-'+value.course.timing">
|
<div class="r-course-detail-header-right">
|
||||||
{{text['coursetiming_'+value.course.timing]}}<br>
|
<div class="r-completion-detail-header">
|
||||||
{{ startdate }} - {{ enddate }}
|
<template v-if='!value.course.enrolled'>
|
||||||
|
{{text.not_enrolled}}
|
||||||
|
<i v-b-popover.top
|
||||||
|
class="r-course-result fa fa-exclamation-triangle t-not-enrolled-alert"
|
||||||
|
:title="text.student_not_tracked"></i>
|
||||||
|
</template>
|
||||||
|
<template v-else-if='hasprogressinfo'>
|
||||||
|
<r-progress-circle v-if='["failed", "progress","incomplete"].includes(value.completion)'
|
||||||
|
:value='courseprogress'
|
||||||
|
:max='1'
|
||||||
|
:min='0'
|
||||||
|
:class="'r-course-result r-completion-'+value.completion"
|
||||||
|
:icon='circle_icon(value.completion)'
|
||||||
|
:title="text['completion_'+value.completion]"
|
||||||
|
></r-progress-circle>
|
||||||
|
<i v-else v-b-popover.top
|
||||||
|
:class="'r-course-result fa fa-'+completion_icon(value.completion)+
|
||||||
|
' r-completion-'+value.completion"
|
||||||
|
:title="text['completion_'+value.completion]"></i>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{text['completion_'+value.completion]}}
|
||||||
|
<i :class="'fa fa-'+completion_icon(value.completion)+' r-completion-'+value.completion"
|
||||||
|
:title="text['completion_'+value.completion]"></i>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div :class="'r-timing-'+value.course.timing">
|
||||||
|
{{text['coursetiming_'+value.course.timing]}}<br>
|
||||||
|
{{ startdate }} - {{ enddate }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<s-progress-bar
|
||||||
|
v-if='value.course.showprogressbar && hasprogressinfo'
|
||||||
|
v-model="courseprogress"
|
||||||
|
></s-progress-bar>
|
||||||
</template>
|
</template>
|
||||||
|
<s-course-extrafields
|
||||||
|
v-if="value.course.extrafields"
|
||||||
|
v-model="value.course.extrafields"
|
||||||
|
position="above"
|
||||||
|
></s-course-extrafields>
|
||||||
<r-item-studentgrades
|
<r-item-studentgrades
|
||||||
v-if='!!value.course.grades && value.course.grades.length > 0'
|
v-if='!!value.course.grades && value.course.grades.length > 0'
|
||||||
v-model='value'
|
v-model='value'
|
||||||
|
@ -1261,6 +1288,11 @@ export default {
|
||||||
v-model='value.course.competency'
|
v-model='value.course.competency'
|
||||||
:item='value'
|
:item='value'
|
||||||
></r-item-student-course-competency>
|
></r-item-student-course-competency>
|
||||||
|
<s-course-extrafields
|
||||||
|
v-if="value.course.extrafields"
|
||||||
|
v-model="value.course.extrafields"
|
||||||
|
position="below"
|
||||||
|
></s-course-extrafields>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
</b-card></div>
|
</b-card></div>
|
||||||
`,
|
`,
|
||||||
|
@ -1958,6 +1990,11 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<s-course-extrafields
|
||||||
|
v-if="value.course.extrafields"
|
||||||
|
v-model="value.course.extrafields"
|
||||||
|
position="above"
|
||||||
|
></s-course-extrafields>
|
||||||
<r-item-teachergrades
|
<r-item-teachergrades
|
||||||
v-if='!!value.course.grades && value.course.grades.length > 0'
|
v-if='!!value.course.grades && value.course.grades.length > 0'
|
||||||
v-model='value.course'
|
v-model='value.course'
|
||||||
|
@ -1973,6 +2010,11 @@ export default {
|
||||||
v-model='value.course.competency'
|
v-model='value.course.competency'
|
||||||
:item='value'
|
:item='value'
|
||||||
></r-item-teacher-course-competency>
|
></r-item-teacher-course-competency>
|
||||||
|
<s-course-extrafields
|
||||||
|
v-if="value.course.extrafields"
|
||||||
|
v-model="value.course.extrafields"
|
||||||
|
position="below"
|
||||||
|
></s-course-extrafields>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
|
||||||
</b-card>
|
</b-card>
|
||||||
|
@ -2045,6 +2087,7 @@ export default {
|
||||||
{{ value.course.startdate }} - {{ value.course.enddate }}
|
{{ value.course.startdate }} - {{ value.course.enddate }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<s-
|
||||||
</template>
|
</template>
|
||||||
<b-form-group
|
<b-form-group
|
||||||
:label="text.select_grades"
|
:label="text.select_grades"
|
||||||
|
|
|
@ -152,9 +152,11 @@ export class SimpleLine {
|
||||||
this.mutationObserver = new MutationObserver(function(mutations_list) {
|
this.mutationObserver = new MutationObserver(function(mutations_list) {
|
||||||
mutations_list.forEach(function(mutation) {
|
mutations_list.forEach(function(mutation) {
|
||||||
mutation.removedNodes.forEach(function(removed_node) {
|
mutation.removedNodes.forEach(function(removed_node) {
|
||||||
if(removed_node == this.start || removed_node == this.end) {
|
if (this){
|
||||||
console.warning("Element removed",removed_node);
|
if(removed_node == this.start || removed_node == this.end) {
|
||||||
this.remove();
|
console.warning("Element removed",removed_node);
|
||||||
|
this.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3194,6 +3194,11 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<s-course-extrafields
|
||||||
|
v-if="value.course.extrafields"
|
||||||
|
v-model="value.course.extrafields"
|
||||||
|
position="above"
|
||||||
|
></s-course-extrafields>
|
||||||
<t-item-course-grades
|
<t-item-course-grades
|
||||||
v-if='!!value.course.grades && value.course.grades.length > 0'
|
v-if='!!value.course.grades && value.course.grades.length > 0'
|
||||||
v-model='value' :plan="plan"
|
v-model='value' :plan="plan"
|
||||||
|
@ -3208,7 +3213,11 @@ export default {
|
||||||
v-model='value.course.competency'
|
v-model='value.course.competency'
|
||||||
:item='value'
|
:item='value'
|
||||||
></t-item-course-competency>
|
></t-item-course-competency>
|
||||||
|
<s-course-extrafields
|
||||||
|
v-if="value.course.extrafields"
|
||||||
|
v-model="value.course.extrafields"
|
||||||
|
position="below"
|
||||||
|
></s-course-extrafields>
|
||||||
<template #modal-footer="{ ok, cancel, hide }" >
|
<template #modal-footer="{ ok, cancel, hide }" >
|
||||||
<a href='#' @click='$emit("deleterq")' class="text-danger"
|
<a href='#' @click='$emit("deleterq")' class="text-danger"
|
||||||
><i class="fa fa-trash"></i>
|
><i class="fa fa-trash"></i>
|
||||||
|
|
|
@ -21,6 +21,9 @@ export default {
|
||||||
},
|
},
|
||||||
details: {
|
details: {
|
||||||
details: "studyplan_details",
|
details: "studyplan_details",
|
||||||
|
},
|
||||||
|
extrafields: {
|
||||||
|
show: "show@core"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Create new eventbus for interaction between item components
|
// Create new eventbus for interaction between item components
|
||||||
|
@ -51,27 +54,7 @@ export default {
|
||||||
end: (dates.end)?format_date(dates.end):this.text.noenddate,
|
end: (dates.end)?format_date(dates.end):this.text.noenddate,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
width_completed() {
|
|
||||||
if(this.value.progress) {
|
|
||||||
return this.value.progress * 100;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
width_incomplete() {
|
|
||||||
if(this.value.progress) {
|
|
||||||
return (1-this.value.progress) * 100;
|
|
||||||
} else {
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
percentage_complete() {
|
|
||||||
if(this.value.progress) {
|
|
||||||
return Math.round(this.value.progress * 100) + "%";
|
|
||||||
} else {
|
|
||||||
return "0%";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onOpenClick(e) {
|
onOpenClick(e) {
|
||||||
|
@ -97,20 +80,10 @@ export default {
|
||||||
<div class='s-studyplan-card-idnumber' v-if='value.idnumber'>
|
<div class='s-studyplan-card-idnumber' v-if='value.idnumber'>
|
||||||
{{ text.idnumber }}: {{ value.idnumber }}
|
{{ text.idnumber }}: {{ value.idnumber }}
|
||||||
</div>
|
</div>
|
||||||
<div class='s-studyplan-card-progress' v-if='value.progress !== undefined && value.progress !== null'>
|
<s-progress-bar
|
||||||
<div class="s-studyplan-card-progressbar"
|
v-if='value.progress !== undefined && value.progress !== null'
|
||||||
><span v-if="width_completed > 0"
|
v-model="value.progress"
|
||||||
:style="{width: width_completed+'%'}"
|
></s-progress-bar>
|
||||||
class='s-studyplan-card-progress-segment s-studyplan-card-progress-completed'
|
|
||||||
></span
|
|
||||||
><span :style="{width: width_incomplete+'%'}"
|
|
||||||
class='s-studyplan-card-progress-segment s-studyplan-card-progress-incomplete'
|
|
||||||
></span
|
|
||||||
></div>
|
|
||||||
<div class="s-studyplan-card-progresstext">
|
|
||||||
{{ percentage_complete}} {{ text.completed.toLowerCase() }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -131,6 +104,71 @@ export default {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Vue.component('s-progress-bar', {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
default() { return 0;}
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
default() { return 1;}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: strings.studyplancard
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
width_completed() {
|
||||||
|
if(this.value) {
|
||||||
|
const v = ( (this.value - this.min) / (this.max - this.min));
|
||||||
|
return v * 100;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
width_incomplete() {
|
||||||
|
if(this.value) {
|
||||||
|
const v = ( (this.value - this.min) / (this.max - this.min));
|
||||||
|
return (1-v) * 100;
|
||||||
|
} else {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
percentage_complete() {
|
||||||
|
if(this.value) {
|
||||||
|
const v = ( (this.value - this.min) / (this.max - this.min));
|
||||||
|
return Math.round(v * 100) + "%";
|
||||||
|
} else {
|
||||||
|
return "0%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div class='s-studyplan-card-progress' >
|
||||||
|
<div class="s-studyplan-card-progressbar"
|
||||||
|
><span v-if="width_completed > 0"
|
||||||
|
:style="{width: width_completed+'%'}"
|
||||||
|
class='s-studyplan-card-progress-segment s-studyplan-card-progress-completed'
|
||||||
|
></span
|
||||||
|
><span :style="{width: width_incomplete+'%'}"
|
||||||
|
class='s-studyplan-card-progress-segment s-studyplan-card-progress-incomplete'
|
||||||
|
></span
|
||||||
|
></div>
|
||||||
|
<div class="s-studyplan-card-progresstext">
|
||||||
|
{{ percentage_complete}} {{ text.completed.toLowerCase() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* S-STUDYLINE-HEADER-HEADING
|
* S-STUDYLINE-HEADER-HEADING
|
||||||
* The only reasing this is not a simple empty div, is the fact that the header height
|
* The only reasing this is not a simple empty div, is the fact that the header height
|
||||||
|
@ -293,5 +331,73 @@ export default {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Vue.component('s-course-extrafields', {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
type: String,
|
||||||
|
default() { return "info"; }
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
type: String,
|
||||||
|
default() { return "below"; }
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default() { return "";}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: strings.extrafields,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
fields() {
|
||||||
|
const fields = [];
|
||||||
|
for (const ix in this.value) {
|
||||||
|
const field = this.value[ix];
|
||||||
|
if (field.position == this.position && field.value && field.value.length > 0) {
|
||||||
|
fields.push(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
displaydate(field) {
|
||||||
|
return format_date(field.value,false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<div :class="'s-course-extrafields ' + ((fields.length>0)?position:'empty')">
|
||||||
|
<table v-if="fields.length > 0">
|
||||||
|
<tr v-for="field in fields">
|
||||||
|
<td><span class='title' v-if='field.title'>{{ field.title}}</span></td>
|
||||||
|
<td>
|
||||||
|
<span v-if='field.type == "date"' class="value date">{{ displaydate(field) }}</span>
|
||||||
|
<span v-else-if='field.type == "checkbox"'
|
||||||
|
:class="'value ' + (field.checked?'true':'false')">{{ field.value }}</span>
|
||||||
|
<span v-else-if='field.type == "textarea"'>
|
||||||
|
<a class='text-info' href='#' v-b-modal="field.courseid+'_'+field.fieldname">{{text.show}}...</a>
|
||||||
|
<b-modal
|
||||||
|
:id="field.courseid+'_'+field.fieldname"
|
||||||
|
:title="field.title""
|
||||||
|
scrollable
|
||||||
|
centered
|
||||||
|
ok-only
|
||||||
|
><span v-html="field.value"></span
|
||||||
|
></b-modal>
|
||||||
|
</span>
|
||||||
|
<span v-else class="value"><span v-html="field.value"></span></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -10,8 +10,10 @@ export function format_date(d,short){
|
||||||
}
|
}
|
||||||
|
|
||||||
let monthformat = "short";
|
let monthformat = "short";
|
||||||
if(short){
|
if(short === true){
|
||||||
monthformat = "numeric";
|
monthformat = "numeric";
|
||||||
|
} else if (short === false) {
|
||||||
|
monthformat = "long";
|
||||||
}
|
}
|
||||||
return d.toLocaleDateString(document.documentElement.lang,{
|
return d.toLocaleDateString(document.documentElement.lang,{
|
||||||
year: 'numeric', month: monthformat, day: 'numeric'
|
year: 'numeric', month: monthformat, day: 'numeric'
|
||||||
|
|
|
@ -768,9 +768,6 @@ class badgeinfo {
|
||||||
INNER JOIN {badge_criteria_param} p on p.critid = crit.id
|
INNER JOIN {badge_criteria_param} p on p.critid = crit.id
|
||||||
WHERE p.value = :courseid AND crit.criteriatype $ctypesql $conditions";
|
WHERE p.value = :courseid AND crit.criteriatype $ctypesql $conditions";
|
||||||
|
|
||||||
debug::write("Sql query courses: ");
|
|
||||||
debug::write($sql);
|
|
||||||
debug::print_r($sqlparams);
|
|
||||||
|
|
||||||
$courserelids = $DB->get_fieldset_sql($sql, $sqlparams);
|
$courserelids = $DB->get_fieldset_sql($sql, $sqlparams);
|
||||||
|
|
||||||
|
@ -782,9 +779,6 @@ class badgeinfo {
|
||||||
INNER JOIN {competency_coursecomp} cc on cc.competencyid = p.value
|
INNER JOIN {competency_coursecomp} cc on cc.competencyid = p.value
|
||||||
WHERE cc.courseid = :courseid AND crit.criteriatype $ctypesql $conditions";
|
WHERE cc.courseid = :courseid AND crit.criteriatype $ctypesql $conditions";
|
||||||
|
|
||||||
debug::write("Sql query through competencies: ");
|
|
||||||
debug::write($sql);
|
|
||||||
debug::print_r($sqlparams);
|
|
||||||
|
|
||||||
$competencyrelids = $DB->get_fieldset_sql($sql,$sqlparams);
|
$competencyrelids = $DB->get_fieldset_sql($sql,$sqlparams);
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,11 @@ class courseinfo {
|
||||||
if (strlen($idnumber) > 0) {
|
if (strlen($idnumber) > 0) {
|
||||||
return $this->course->idnumber;
|
return $this->course->idnumber;
|
||||||
}
|
}
|
||||||
|
} else if ($displayfield == "fullname") {
|
||||||
|
$fullname = trim(preg_replace("/\s+/u", " ", $this->course->fullname));
|
||||||
|
if (strlen($fullname) > 0) {
|
||||||
|
return $fullname;
|
||||||
|
}
|
||||||
} else if (strpos( $displayfield , "customfield_") === 0) {
|
} else if (strpos( $displayfield , "customfield_") === 0) {
|
||||||
$fieldname = substr($displayfield, strlen("customfield_"));
|
$fieldname = substr($displayfield, strlen("customfield_"));
|
||||||
|
|
||||||
|
@ -292,7 +297,7 @@ class courseinfo {
|
||||||
"canselectgradables" => new \external_value(PARAM_BOOL, 'Requesting user can change selected gradables'),
|
"canselectgradables" => new \external_value(PARAM_BOOL, 'Requesting user can change selected gradables'),
|
||||||
"numenrolled" => new \external_value(PARAM_INT, 'number of students from this studyplan enrolled in the course'),
|
"numenrolled" => new \external_value(PARAM_INT, 'number of students from this studyplan enrolled in the course'),
|
||||||
"tag" => new \external_value(PARAM_TEXT, 'Tag'),
|
"tag" => new \external_value(PARAM_TEXT, 'Tag'),
|
||||||
"extrafields" => self::extrafields_structure();
|
"extrafields" => self::extrafields_structure(),
|
||||||
], 'referenced course information', $value);
|
], 'referenced course information', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,16 +324,15 @@ class courseinfo {
|
||||||
'context' => $contextinfo->model(),
|
'context' => $contextinfo->model(),
|
||||||
'ctxid' => $this->coursecontext->id,
|
'ctxid' => $this->coursecontext->id,
|
||||||
'timing' => $timing,
|
'timing' => $timing,
|
||||||
'startdate' => date("Y-m-d", $this->course->startdate, ),
|
'startdate' => date("Y-m-d", $this->course->startdate),
|
||||||
'enddate' => date("Y-m-d", $this->course->enddate),
|
'enddate' => date("Y-m-d", $this->course->enddate),
|
||||||
'amteacher' => $this->am_teacher(),
|
'amteacher' => $this->am_teacher(),
|
||||||
'canupdatecourse' => \has_capability("moodle/course:update", $this->coursecontext),
|
'canupdatecourse' => \has_capability("moodle/course:update", $this->coursecontext),
|
||||||
'canselectgradables' => $this->i_can_select_gradables(),
|
'canselectgradables' => $this->i_can_select_gradables(),
|
||||||
'tag' => "Editormodel",
|
'tag' => "Editormodel",
|
||||||
'extrafields' => $this->extrafields_model(),
|
'extrafields' => $this->extrafields_model(true),
|
||||||
'grades' => [],
|
'grades' => [],
|
||||||
'numenrolled' => $numenrolled,
|
'numenrolled' => $numenrolled,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (isset($this->studyitem)) {
|
if (isset($this->studyitem)) {
|
||||||
|
@ -373,7 +377,8 @@ class courseinfo {
|
||||||
"startdate" => new \external_value(PARAM_TEXT, 'Course start date'),
|
"startdate" => new \external_value(PARAM_TEXT, 'Course start date'),
|
||||||
"enddate" => new \external_value(PARAM_TEXT, 'Course end date'),
|
"enddate" => new \external_value(PARAM_TEXT, 'Course end date'),
|
||||||
"enrolled" => new \external_value(PARAM_BOOL, 'True if student is enrolled as student in this course'),
|
"enrolled" => new \external_value(PARAM_BOOL, 'True if student is enrolled as student in this course'),
|
||||||
"extrafields" => self::extrafields_structure();
|
"extrafields" => self::extrafields_structure(),
|
||||||
|
"showprogressbar" => new \external_value(PARAM_BOOL, "Whether to show the progress bar in the header"),
|
||||||
], 'course information', $value);
|
], 'course information', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,6 +455,7 @@ class courseinfo {
|
||||||
'grades' => [],
|
'grades' => [],
|
||||||
'enrolled' => $this->is_enrolled_student($userid),
|
'enrolled' => $this->is_enrolled_student($userid),
|
||||||
'extrafields' => $this->extrafields_model(),
|
'extrafields' => $this->extrafields_model(),
|
||||||
|
'showprogressbar' => get_config("local_treestudyplan","courseprogressbar"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
@ -485,27 +491,37 @@ class courseinfo {
|
||||||
"value" => new \external_value(PARAM_RAW, 'value'),
|
"value" => new \external_value(PARAM_RAW, 'value'),
|
||||||
"position" => new \external_value(PARAM_TEXT, 'position'),
|
"position" => new \external_value(PARAM_TEXT, 'position'),
|
||||||
"type" => new \external_value(PARAM_TEXT, 'value type'),
|
"type" => new \external_value(PARAM_TEXT, 'value type'),
|
||||||
|
"fieldname" => new \external_value(PARAM_TEXT, 'field name'),
|
||||||
|
"checked" => new \external_value(PARAM_BOOL, 'checkbox value',VALUE_OPTIONAL),
|
||||||
|
"courseid" => new \external_value(PARAM_TEXT, 'course id number'),
|
||||||
], 'referenced course information'), $value);
|
], 'referenced course information'), $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Webservice model for basic info
|
* Webservice model for basic info
|
||||||
|
* @param $includeteachervisible Include custom fiel
|
||||||
* @return array Webservice data model
|
* @return array Webservice data model
|
||||||
*/
|
*/
|
||||||
public function extrafields_model() {
|
public function extrafields_model($includeteachervisible=false) {
|
||||||
$list = [];
|
$list = [];
|
||||||
for ($i=1; $i <= 5; $i++) {
|
for ($i=1; $i <= 5; $i++) {
|
||||||
$field = get_config('local_treestudyplan','courseinfo'.$i.'_field');
|
$field = get_config('local_treestudyplan','courseinfo'.$i.'_field');
|
||||||
$title = self::extrafields_localize_title(get_config('local_treestudyplan','courseinfo'.$i.'_title'));
|
if ($field) {
|
||||||
$pos = get_config('local_treestudyplan','courseinfo'.$i.'_position');
|
$title = self::extrafields_localize_title(get_config('local_treestudyplan','courseinfo'.$i.'_title'));
|
||||||
[$value,$type] = $this->extrafields_value($field);
|
$pos = get_config('local_treestudyplan','courseinfo'.$i.'_position');
|
||||||
$list[] = [
|
[$value,$type, $raw] = $this->extrafields_value($field,$includeteachervisible);
|
||||||
"title" => $title,
|
if ($type) {
|
||||||
"value" => $value,
|
$list[] = [
|
||||||
"position" => $pos,
|
"title" => $title,
|
||||||
"type" => $type,
|
"value" => $value,
|
||||||
];
|
"position" => $pos,
|
||||||
|
"type" => $type,
|
||||||
|
"fieldname" => $field,
|
||||||
|
"courseid" => $this->course->id,
|
||||||
|
"checked" => ($type=="checkbox")?($raw?true:false):null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
@ -514,33 +530,51 @@ class courseinfo {
|
||||||
$lang = trim(current_language());
|
$lang = trim(current_language());
|
||||||
$lines = explode("\n",$field);
|
$lines = explode("\n",$field);
|
||||||
$title = "";
|
$title = "";
|
||||||
|
$fallback = ""; // Fallback to first title
|
||||||
foreach ($lines as $l) {
|
foreach ($lines as $l) {
|
||||||
$parts = explode("|",$l,2);
|
$parts = explode("|",$l,2);
|
||||||
if (count($parts) > 0) {
|
if (count($parts) > 0) {
|
||||||
|
// Set the first line as fallback.
|
||||||
|
if (empty($firsttitle) && !empty($parts[0])) {
|
||||||
|
$fallback = $parts[0];
|
||||||
|
}
|
||||||
if (count($parts) == 1 && empty($title)) {
|
if (count($parts) == 1 && empty($title)) {
|
||||||
|
// Set line without language as default if no localized line found
|
||||||
$title = trim($parts[0]);
|
$title = trim($parts[0]);
|
||||||
}
|
} else if (trim($parts[1]) == $lang) {
|
||||||
else if (trim($parts[1]) == $lang) {
|
|
||||||
return trim($parts[0]);
|
return trim($parts[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $title;
|
// Return default title or fall back to first localizef title.
|
||||||
|
return (strlen($title) > 0)?$title:$fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine value and type of an extra field for this course
|
* Determine value and type of an extra field for this course
|
||||||
* @return array [value,type] of the field for this
|
* @return array [value,type] of the field for this
|
||||||
*/
|
*/
|
||||||
protected function extrafields_value($fieldname) {
|
protected function extrafields_value($fieldname,$includeteachervisible=false) {
|
||||||
$fieldname = get_config("local_treestudyplan", "display_field");
|
|
||||||
|
|
||||||
if ($fieldname == "description") {
|
if ($fieldname == "description") {
|
||||||
return [$this->course()->description, "textarea"];
|
// Process embedded files.
|
||||||
|
$value = \file_rewrite_pluginfile_urls(
|
||||||
|
// The description content
|
||||||
|
$this->course()->summary,
|
||||||
|
// The pluginfile URL which will serve the request.
|
||||||
|
'pluginfile.php',
|
||||||
|
// The combination of contextid / component / filearea / itemid
|
||||||
|
// form the virtual bucket that file are stored in.
|
||||||
|
$this->coursecontext->id, // System instance is always used for this
|
||||||
|
'course',
|
||||||
|
'summary',
|
||||||
|
''
|
||||||
|
);
|
||||||
|
return [$value, "textarea", $this->course()->summary];
|
||||||
} else if ($fieldname == "idnumber") {
|
} else if ($fieldname == "idnumber") {
|
||||||
$idnumber = trim(preg_replace("/\s+/u", " ", $this->course->idnumber));
|
$idnumber = trim(preg_replace("/\s+/u", " ", $this->course->idnumber));
|
||||||
return [$idnumber, "text"];
|
return [$idnumber, "text", $this->course->idnumber];
|
||||||
} else if ($fieldname == "contacts") {
|
} else if ($fieldname == "contacts") {
|
||||||
$cle = new \core_course_list_element($this->course());
|
$cle = new \core_course_list_element($this->course());
|
||||||
$contacts = $cle->get_course_contacts();
|
$contacts = $cle->get_course_contacts();
|
||||||
|
@ -552,24 +586,41 @@ class courseinfo {
|
||||||
$value .= $contact["username"] . "(".$contact["role"]["name"].")";
|
$value .= $contact["username"] . "(".$contact["role"]["name"].")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$value, "text"];
|
return [$value, "text", $value];
|
||||||
} else if (strpos( $fieldname , "customfield_") === 0) {
|
} else if (strpos( $fieldname , "customfield_") === 0) {
|
||||||
$fieldname = substr($fieldname, strlen("customfield_"));
|
$fieldshortname = substr($fieldname, strlen("customfield_"));
|
||||||
|
|
||||||
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
||||||
$datas = $handler->get_instance_data($this->course->id);
|
$datas = $handler->get_instance_data($this->course->id);
|
||||||
foreach ($datas as $data) {
|
foreach ($datas as $data) {
|
||||||
$field = $data->get_field();
|
$field = $data->get_field();
|
||||||
if ($field->get('shortname') == $fieldname) {
|
$fshortname = $field->get('shortname');
|
||||||
$value = trim(preg_replace("/\s+/u", " ", $data->get_value()));
|
if ($fshortname == $fieldshortname) {
|
||||||
|
$visibility = $field->get_configdata_property("visibility");
|
||||||
|
$raw = $data->get_value();
|
||||||
$type = $field->get('type');
|
$type = $field->get('type');
|
||||||
if (strlen($value) > 0) {
|
|
||||||
return [$value,$type];
|
// Only show if visibility is "Everyone" or ("Teachers" and in teacher view )
|
||||||
|
if ($visibility > 0 && ($visibility == 2 || $includeteachervisible)) {
|
||||||
|
if ($type == "date") {
|
||||||
|
// Date should be converted to YYYY-MM-DD so the javascript can properly format it.
|
||||||
|
if ($raw == 0) {
|
||||||
|
$value = "";
|
||||||
|
} else {
|
||||||
|
// Convert to YYYY-MM-DD format.
|
||||||
|
$value = date("Y-m-d", $raw);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Everything else can just use the export value.
|
||||||
|
$value = $data->export_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$value,$type,$raw];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fallback to shortname when the specified display field fails, since shortname is never empty.
|
// Fallback to empty if finding a match fails.
|
||||||
return ["",""];
|
return [null,null,null];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,7 +407,6 @@ class studentstudyplanservice extends \external_api {
|
||||||
|
|
||||||
if ($studyplan->exist_for_user($userid)) {
|
if ($studyplan->exist_for_user($userid)) {
|
||||||
$model = $studyplan->user_model($userid);
|
$model = $studyplan->user_model($userid);
|
||||||
debug::dump($model);
|
|
||||||
return $model;
|
return $model;
|
||||||
} else {
|
} else {
|
||||||
throw new \moodle_exception("You do not have access to this studyplan");
|
throw new \moodle_exception("You do not have access to this studyplan");
|
||||||
|
|
|
@ -1336,6 +1336,25 @@
|
||||||
.features-treestudyplan table.r-item-course-competency-list td {
|
.features-treestudyplan table.r-item-course-competency-list td {
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
.path-local-treestudyplan header.modal-header.r-item-course-header,
|
||||||
|
.features-treestudyplan header.modal-header.r-item-course-header {
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan header.modal-header.r-item-course-header .s-studyplan-card-progressbar,
|
||||||
|
.features-treestudyplan header.modal-header.r-item-course-header .s-studyplan-card-progressbar {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan div.r-item-course-header-details,
|
||||||
|
.features-treestudyplan div.r-item-course-header-details {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan div.r-item-course-header-details:last-child,
|
||||||
|
.features-treestudyplan div.r-item-course-header-details:last-child {
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
.path-local-treestudyplan .card.s-studyplan-card,
|
.path-local-treestudyplan .card.s-studyplan-card,
|
||||||
.features-treestudyplan .card.s-studyplan-card {
|
.features-treestudyplan .card.s-studyplan-card {
|
||||||
|
@ -1467,6 +1486,31 @@
|
||||||
width: 128px;
|
width: 128px;
|
||||||
height: 128px;
|
height: 128px;
|
||||||
}
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields.above,
|
||||||
|
.features-treestudyplan .s-course-extrafields.above {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields.below,
|
||||||
|
.features-treestudyplan .s-course-extrafields.below {
|
||||||
|
border-top: 1px solid #dee2e6;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields .title,
|
||||||
|
.features-treestudyplan .s-course-extrafields .title {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields .value.true,
|
||||||
|
.features-treestudyplan .s-course-extrafields .value.true {
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields .value.false,
|
||||||
|
.features-treestudyplan .s-course-extrafields .value.false {
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
.path-local-treestudyplan .b-modal-justify-footer-between .modal-footer,
|
.path-local-treestudyplan .b-modal-justify-footer-between .modal-footer,
|
||||||
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
||||||
|
|
|
@ -1150,4 +1150,21 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header.modal-header.r-item-course-header {
|
||||||
|
display: block;
|
||||||
|
.s-studyplan-card-progressbar {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.r-item-course-header-details {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -129,4 +129,35 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.s-course-extrafields {
|
||||||
|
&.above {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.below {
|
||||||
|
border-top: 1px solid #dee2e6;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
&.true {
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
&.false {
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
16
settings.php
16
settings.php
|
@ -88,17 +88,21 @@ if ($hassiteconfig) {
|
||||||
get_string('settingdesc_display_heading', 'local_treestudyplan')
|
get_string('settingdesc_display_heading', 'local_treestudyplan')
|
||||||
));
|
));
|
||||||
|
|
||||||
$displayfields = ["shortname" => get_string("shortname"), "idnumber" => get_string("idnumber")];
|
$displayfields = ["shortname" => get_string("shortname"), "idnumber" => get_string("idnumber"), "fullname" => get_string("fullname"), ];
|
||||||
$infofields = ["" => get_string('none'), "description" => get_string("description"), "contacts" => get_string("teachers"), "idnumber" => get_string("idnumber")];
|
$infofields = ["" => get_string('none'), "description" => get_string("description"), "contacts" => get_string("teachers"), "idnumber" => get_string("idnumber")];
|
||||||
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
$handler = \core_customfield\handler::get_handler('core_course', 'course');
|
||||||
|
|
||||||
foreach ($handler->get_categories_with_fields() as $cat) {
|
foreach ($handler->get_categories_with_fields() as $cat) {
|
||||||
$catname = $cat->get_formatted_name();
|
$catname = $cat->get_formatted_name();
|
||||||
foreach ($cat->get_fields() as $field) {
|
foreach ($cat->get_fields() as $field) {
|
||||||
$fieldname = $field->get_formatted_name();
|
$visibility = $field->get_configdata_property("visibility");
|
||||||
$fieldid = $field->get("shortname");
|
if ($visibility > 0) {
|
||||||
$displayfields["customfield_".$fieldid] = $catname.": ".$fieldname;
|
// Only include fields that are visible to Teachers, or Everyone.
|
||||||
$infofields["customfield_".$fieldid] = $catname.": ".$fieldname;
|
$fieldname = $field->get_formatted_name();
|
||||||
|
$fieldid = $field->get("shortname");
|
||||||
|
$displayfields["customfield_".$fieldid] = $catname.": ".$fieldname;
|
||||||
|
$infofields["customfield_".$fieldid] = $catname.": ".$fieldname;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +126,6 @@ if ($hassiteconfig) {
|
||||||
|
|
||||||
$positions = [ "above" => get_string('infofield_position_above', 'local_treestudyplan'),
|
$positions = [ "above" => get_string('infofield_position_above', 'local_treestudyplan'),
|
||||||
"below" => get_string("infofield_position_below", 'local_treestudyplan'),
|
"below" => get_string("infofield_position_below", 'local_treestudyplan'),
|
||||||
"header" => get_string("infofield_position_header", 'local_treestudyplan'),
|
|
||||||
"footer" => get_string("infofield_position_footer", 'local_treestudyplan')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for ($i=1;$i<=5;$i++) {
|
for ($i=1;$i<=5;$i++) {
|
||||||
|
|
44
styles.css
44
styles.css
|
@ -1336,6 +1336,25 @@
|
||||||
.features-treestudyplan table.r-item-course-competency-list td {
|
.features-treestudyplan table.r-item-course-competency-list td {
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
.path-local-treestudyplan header.modal-header.r-item-course-header,
|
||||||
|
.features-treestudyplan header.modal-header.r-item-course-header {
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan header.modal-header.r-item-course-header .s-studyplan-card-progressbar,
|
||||||
|
.features-treestudyplan header.modal-header.r-item-course-header .s-studyplan-card-progressbar {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan div.r-item-course-header-details,
|
||||||
|
.features-treestudyplan div.r-item-course-header-details {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan div.r-item-course-header-details:last-child,
|
||||||
|
.features-treestudyplan div.r-item-course-header-details:last-child {
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
.path-local-treestudyplan .card.s-studyplan-card,
|
.path-local-treestudyplan .card.s-studyplan-card,
|
||||||
.features-treestudyplan .card.s-studyplan-card {
|
.features-treestudyplan .card.s-studyplan-card {
|
||||||
|
@ -1467,6 +1486,31 @@
|
||||||
width: 128px;
|
width: 128px;
|
||||||
height: 128px;
|
height: 128px;
|
||||||
}
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields.above,
|
||||||
|
.features-treestudyplan .s-course-extrafields.above {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields.below,
|
||||||
|
.features-treestudyplan .s-course-extrafields.below {
|
||||||
|
border-top: 1px solid #dee2e6;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields .title,
|
||||||
|
.features-treestudyplan .s-course-extrafields .title {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields .value.true,
|
||||||
|
.features-treestudyplan .s-course-extrafields .value.true {
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
.path-local-treestudyplan .s-course-extrafields .value.false,
|
||||||
|
.features-treestudyplan .s-course-extrafields .value.false {
|
||||||
|
color: var(--danger);
|
||||||
|
}
|
||||||
|
|
||||||
.path-local-treestudyplan .b-modal-justify-footer-between .modal-footer,
|
.path-local-treestudyplan .b-modal-justify-footer-between .modal-footer,
|
||||||
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user