From f8b18d4d6ee12a4cad4c380437a54c51daf0ffdf Mon Sep 17 00:00:00 2001 From: PMKuipers Date: Tue, 20 Feb 2024 20:40:18 +0100 Subject: [PATCH] Update --- amd/build/studyplan-report-components.min.js | 2 +- .../studyplan-report-components.min.js.map | 2 +- amd/src/studyplan-report-components.js | 260 +++++++++++------- css/devstyles.css | 116 +++----- lang/en/local_treestudyplan.php | 5 +- lang/nl/local_treestudyplan.php | 4 +- scss/studyplan-report.scss | 76 +++-- styles.css | 116 +++----- 8 files changed, 273 insertions(+), 308 deletions(-) diff --git a/amd/build/studyplan-report-components.min.js b/amd/build/studyplan-report-components.min.js index 6f68b3a..897580c 100644 --- a/amd/build/studyplan-report-components.min.js +++ b/amd/build/studyplan-report-components.min.js @@ -1,3 +1,3 @@ -define("local_treestudyplan/studyplan-report-components",["exports","./util/string-helper","core/ajax","core/notification","./util/debugger","core/config","./treestudyplan-components"],(function(_exports,_stringHelper,_ajax,_notification,_debugger,_config,_treestudyplanComponents){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_notification=_interopRequireDefault(_notification),_debugger=_interopRequireDefault(_debugger),_config=_interopRequireDefault(_config),_treestudyplanComponents=_interopRequireDefault(_treestudyplanComponents);Math.PI;var _default={install(Vue){Vue.use(_treestudyplanComponents.default);let debug=new _debugger.default("treestudyplan-viewer"),strings=(0,_stringHelper.load_strings)({report:{loading:"loadinghelp@core",studyplan_past:"studyplan_past",studyplan_present:"studyplan_present",studyplan_future:"studyplan_future",back:"back"},invalid:{error:"error"},header:{overall:"overall",students:"students@core"},studentresults:{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",student_not_tracked:"student_not_tracked"}});Vue.component("q-studyplanreport",{props:{structure:{type:Object}},data:()=>({students:[],studentresults:{},expansioninfo:{periods:{},lines:{},items:{}},groupinfo:{},sorting:{name:"asc"}}),created(){this.loadStudents()},computed:{sortedstudents(){return this.students}},watch:{structure:{immediate:!0,handler(structure){for(const period of structure.periods){const pid=period.period.id;this.expansioninfo.periods[pid]||(this.$set(this.expansioninfo.periods,pid,{expanded:!1}),this.$set(this.expansioninfo.lines,period.period.id,{}));for(const line of period.lines){const lid=line.line.id;this.expansioninfo.lines[lid]||this.$set(this.expansioninfo.lines[pid],lid,{expanded:!0});for(const item of line.items)this.expansioninfo.items[item.id]||this.$set(this.expansioninfo.items,item.id,{expanded:!1})}}}}},methods:{loadStudents(){const self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_all_associated_grouped",args:{studyplan_id:this.structure.studyplan.id}}])[0].then((function(response){self.students=response;for(const group of self.students){self.$set(self.groupinfo,group.label,{expand:!0});for(const student of group.users)self.$set(self.studentresults,student.id,{loading:!0,results:[]}),(0,_ajax.call)([{methodname:"local_treestudyplan_get_report_data",args:{pageid:self.structure.page.id,userid:student.id,firstperiod:self.structure.firstperiod,lastperiod:self.structure.lastperiod}}])[0].then((function(response){self.studentresults[student.id].loading=!1,self.studentresults[student.id].results=response})).catch(_notification.default.exception)}})).catch(_notification.default.exception)},expansionChanged(parm,id,val){parm="p"==parm[0]?"periods":"l"==parm[0]?"lines":"items",debug.info("Expansion Changed",parm,id,val),"lines"==parm?this.expansioninfo[parm][id[0]][id[1]].expanded=val:this.expansioninfo[parm][id].expanded=val}},template:"\n
\n \n
\n \n
\n
\n "}),Vue.component("q-header",{props:{structure:{type:Object},sorting:{type:Object},expansion:{type:Object}},data:()=>({text:strings.header}),computed:{},methods:{conditions(item){const course=item.course,list=[];if(debug.info("Determining conditions",course),course.completion){debug.info("Has Competencies");for(const cmp of course.competencies)list.push({name:cmp.title})}else if(course.completion){debug.info("Has Core completion");for(const cnd of course.completion.conditions)for(const itm of cnd.items)list.push({name:itm.title})}else if(course.grades){debug.info("Has selected grades");for(const g of course.grades)list.push({name:g.name})}return list},colspanPeriod(period){if(this.expansion.periods[period.id].expanded){let sum=0;for(const l of period.lines)sum+=this.colspanLine(period,l);return sum}return 1},colspanLine(period,line){if(this.expansion.lines[period.id][line.id].expanded){let sum=0;for(const i of line.items)sum+=this.colspanItem(i);return sum}return 1},colspanItem(item){if(this.expansion.items[item.id].expanded){return 1+this.conditions(item).length}return 1}},mounted(){},updated(){},template:"\n \n \x3c!-- period heading --\x3e\n {{text.students}}\n {{ p.period.fullname}}<\n /th>\n \n \x3c!-- line heading --\x3e\n \n \n \x3c!-- item heading --\x3e\n \n \n \n \x3c!-- condition heading --\x3e\n \n \n \n \n \n "}),Vue.component("q-groupheading",{props:{structure:{type:Object}},data:()=>({}),computed:{},methods:{},template:"\n
\n\n
\n "}),Vue.component("q-studentresults",{props:{student:{type:Object},structure:{type:Object},results:{type:Array},loading:{type:Boolean,default:!1},expansion:{type:Object}},data:()=>({text:strings.studentresults}),computed:{},methods:{useritems(line){const list=[];for(const item of line.items){let newitm=item;for(const itm of this.results)if(item.id==itm.id){newitm=itm;break}list.push(newitm)}return list}},template:'\n \n {{student.firstname}} {{student.lastname}}\n \n \n '}),Vue.component("q-courseresult",{props:{student:{type:Object},item:{type:Object},loading:{type:Boolean,default:!1}},data:()=>({text:strings.studentresults}),computed:{hasprogressinfo(){const course=this.item.course;return!!course.enrolled&&(course.completion||course.competency||course.grades)},completion_icon(){switch(this.item.completion){default:return"circle-o";case"pending":return"question-circle";case"failed":return"times-circle";case"progress":return"exclamation-circle";case"completed":case"good":case"excellent":return"check-circle"}}},methods:{},template:'\n
\n \n \n \n
\n '}),Vue.component("q-conditionresult",{props:{student:{type:Object},item:{type:Object},loading:{type:Boolean,default:!1},conditionidx:{type:Number}},data:()=>({text:strings.studentresults}),computed:{conditions(){const course=this.item.course;if(debug.info("Determining conditions",course),course.completion)return debug.info("Has Competencies"),course.competencies;if(course.completion){debug.info("Has Core completion");const list=[];for(const cnd of course.completion.conditions)for(const itm of cnd.items)list.push(itm);return list}return course.grades?course.grades:void 0},condition(){return this.conditionidx>=0&&this.conditionidx\n \n \n \n \n \n '})}};return _exports.default=_default,_exports.default})); +define("local_treestudyplan/studyplan-report-components",["exports","./util/string-helper","core/ajax","core/notification","./util/debugger","core/config","./treestudyplan-components"],(function(_exports,_stringHelper,_ajax,_notification,_debugger,_config,_treestudyplanComponents){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_notification=_interopRequireDefault(_notification),_debugger=_interopRequireDefault(_debugger),_config=_interopRequireDefault(_config),_treestudyplanComponents=_interopRequireDefault(_treestudyplanComponents);const debug=new _debugger.default("treestudyplan-viewer");Math.PI;function conditions(item){const course=item.course,list=[];if(course.completion)for(const cmp of course.competencies)list.push(cmp);else if(course.completion)for(const cnd of course.completion.conditions)for(const itm of cnd.items)list.push(itm);else if(course.grades)for(const g of course.grades)g.selected&&list.push(g);return list}var _default={install(Vue){Vue.use(_treestudyplanComponents.default);let strings=(0,_stringHelper.load_strings)({report:{loading:"loadinghelp@core",studyplan_past:"studyplan_past",studyplan_present:"studyplan_present",studyplan_future:"studyplan_future",back:"back"},invalid:{error:"error"},header:{overall:"overall",students:"students@core"},studentresults:{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",student_not_tracked:"student_not_tracked"}});Vue.component("q-studyplanreport",{props:{structure:{type:Object}},data:()=>({students:[],studentresults:{},expansioninfo:{periods:{},lines:{},items:{}},groupinfo:{},sorting:{name:"asc"}}),created(){this.loadStudents()},watch:{structure:{immediate:!0,handler(structure){for(const period of structure.periods){const pid=period.period.id;this.expansioninfo.periods[pid]||(this.$set(this.expansioninfo.periods,pid,{expanded:!1}),this.$set(this.expansioninfo.lines,period.period.id,{}));for(const line of period.lines){const lid=line.line.id;this.expansioninfo.lines[lid]||this.$set(this.expansioninfo.lines[pid],lid,{expanded:!0});for(const item of line.items)this.expansioninfo.items[item.id]||this.$set(this.expansioninfo.items,item.id,{expanded:!1})}}}}},computed:{sortedstudents(){return this.students},resultColCount(){let count=0;for(const period of this.structure.periods){const pid=period.period.id;if(this.expansioninfo.periods[pid].expanded)for(const line of period.lines){const lid=line.line.id;if(this.expansioninfo.lines[pid][lid])for(const item of line.items)this.expansioninfo.items[item.id]?count+=1+conditions(item).length:count+=1;else count+=1}else count+=1}return count}},methods:{loadStudents(){const self=this;(0,_ajax.call)([{methodname:"local_treestudyplan_all_associated_grouped",args:{studyplan_id:this.structure.studyplan.id}}])[0].then((function(response){self.students=response;for(const group of self.students){self.$set(self.groupinfo,group.label,{expand:!0});for(const student of group.users)self.$set(self.studentresults,student.id,{loading:!0,results:[]}),(0,_ajax.call)([{methodname:"local_treestudyplan_get_report_data",args:{pageid:self.structure.page.id,userid:student.id,firstperiod:self.structure.firstperiod,lastperiod:self.structure.lastperiod}}])[0].then((function(response){self.studentresults[student.id].loading=!1,self.studentresults[student.id].results=response})).catch(_notification.default.exception)}})).catch(_notification.default.exception)},expansionChanged(parm,id,val){parm="p"==parm[0]?"periods":"l"==parm[0]?"lines":"items",debug.info("Expansion Changed",parm,id,val),"lines"==parm?this.expansioninfo[parm][id[0]][id[1]].expanded=val:this.expansioninfo[parm][id].expanded=val}},template:"\n \n \n \n
\n "}),Vue.component("q-header",{props:{structure:{type:Object},sorting:{type:Object},expansion:{type:Object}},data:()=>({text:strings.header}),computed:{},methods:{conditions:item=>function(item){const course=item.course,list=[];if(course.completion)for(const cmp of course.competencies)list.push({name:cmp.title});else if(course.completion)for(const cnd of course.completion.conditions)for(const itm of cnd.items)list.push({name:itm.title});else if(course.grades)for(const g of course.grades)g.selected&&(debug.info("...included"),list.push({name:g.name}));return debug.info("Returning list",list),list}(item),colspanPeriod(period){const pid=period.period.id;if(debug.info("Checking period expansion",period,this.expansion.periods),this.expansion.periods[pid].expanded){let sum=0;for(const l of period.lines)sum+=this.colspanLine(period,l);return sum}return 1},colspanLine(period,line){const pid=period.period.id,lid=line.line.id;if(this.expansion.lines[pid][lid].expanded){let sum=0;for(const i of line.items)sum+=this.colspanItem(i);return sum}return 1},colspanItem(item){if(this.expansion.items[item.id].expanded){return 1+this.conditions(item).length}return 1}},mounted(){},updated(){},template:"\n \n \x3c!-- period heading --\x3e\n {{text.students}}\n  {{ p.period.fullname}}\n \n \n \x3c!-- line heading --\x3e\n \n \n \x3c!-- item heading --\x3e\n \n \n \x3c!-- condition heading --\x3e\n \n \n \n "}),Vue.component("q-groupheading",{props:{structure:{type:Object}},data:()=>({}),computed:{},methods:{},template:"\n \n\n \n "}),Vue.component("q-studentresults",{props:{student:{type:Object},structure:{type:Object},results:{type:Array},loading:{type:Boolean,default:!1},expansion:{type:Object}},data:()=>({text:strings.studentresults}),computed:{},methods:{useritems(line){const list=[];for(const item of line.items){let newitm=item;for(const itm of this.results)if(item.id==itm.id){newitm=itm;break}list.push(newitm)}return list},conditions:item=>conditions(item)},template:'\n \n {{student.firstname}} {{student.lastname}}\n \n \n '}),Vue.component("q-courseresult",{props:{student:{type:Object},item:{type:Object},loading:{type:Boolean,default:!1}},data:()=>({text:strings.studentresults}),computed:{hasprogressinfo(){const course=this.item.course;return!!course.enrolled&&(course.completion||course.competency||course.grades)},completion_icon(){switch(this.item.completion){default:return"circle-o";case"pending":return"question-circle";case"failed":return"times-circle";case"progress":return"exclamation-circle";case"completed":case"good":case"excellent":return"check-circle"}}},methods:{},template:'\n \n \n \n \n \n '}),Vue.component("q-conditionresult",{props:{student:{type:Object},item:{type:Object},loading:{type:Boolean,default:!1},conditionidx:{type:Number}},data:()=>({text:strings.studentresults}),computed:{conditions(){return conditions(this.item)},condition(){return this.conditionidx>=0&&this.conditionidx\n \n \n \n \n '})}};return _exports.default=_default,_exports.default})); //# sourceMappingURL=studyplan-report-components.min.js.map \ No newline at end of file diff --git a/amd/build/studyplan-report-components.min.js.map b/amd/build/studyplan-report-components.min.js.map index 512c7b1..73a52f3 100644 --- a/amd/build/studyplan-report-components.min.js.map +++ b/amd/build/studyplan-report-components.min.js.map @@ -1 +1 @@ -{"version":3,"file":"studyplan-report-components.min.js","sources":["../src/studyplan-report-components.js"],"sourcesContent":["/*eslint no-var: \"error\"*/\n/*eslint no-console: \"off\"*/\n/*eslint no-unused-vars: warn */\n/*eslint max-len: [\"error\", { \"code\": 160 }] */\n/*eslint-disable no-trailing-spaces */\n/*eslint-env es6*/\n// Put this file in path/to/plugin/amd/src\n\nimport {load_strings} from './util/string-helper';\nimport {call} from 'core/ajax';\nimport notification from 'core/notification';\nimport Debugger from './util/debugger';\nimport Config from 'core/config';\nimport TSComponents from './treestudyplan-components';\n\n// Make π available as a constant\nconst π = Math.PI;\n// Gravity value for arrow lines - determines how much a line is pulled in the direction of the start/end before changing direction\nconst LINE_GRAVITY = 1.3;\n\n\nexport default {\n install(Vue/*,options*/){\n Vue.use(TSComponents);\n let debug = new Debugger(\"treestudyplan-viewer\");\n\n let strings = load_strings({\n report: {\n loading: \"loadinghelp@core\",\n studyplan_past: \"studyplan_past\",\n studyplan_present: \"studyplan_present\",\n studyplan_future: \"studyplan_future\",\n back: \"back\",\n },\n \n invalid: {\n error: 'error',\n },\n header: {\n overall: 'overall',\n students: 'students@core'\n },\n studentresults: {\n completion_incomplete: \"completion_incomplete\",\n completion_failed: \"completion_failed\",\n completion_pending: \"completion_pending\",\n completion_progress: \"completion_progress\",\n completion_completed: \"completion_completed\",\n completion_good: \"completion_good\",\n completion_excellent: \"completion_excellent\",\n student_not_tracked: \"student_not_tracked\",\n }\n });\n\n /************************************\n * *\n * Treestudyplan Viewer components *\n * *\n ************************************/\n\n Vue.component('q-studyplanreport', {\n props: {\n structure: {\n type: Object,\n },\n },\n data() {\n return {\n students: [],\n studentresults: {},\n expansioninfo: {\n periods: {},\n lines: {},\n items: {},\n },\n groupinfo: {},\n\n sorting: {\n name: \"asc\",\n }\n };\n },\n created() {\n this.loadStudents();\n },\n computed: {\n sortedstudents(){\n return this.students;\n }\n },\n watch:{\n structure: {\n immediate: true,\n handler (structure) {\n // (Re)build expansion info structure\n for (const period of structure.periods) {\n const pid = period.period.id;\n if (!this.expansioninfo.periods[pid]) {\n // Use this.$set to make sure the properties are reactive.\n this.$set(\n this.expansioninfo.periods, \n pid, \n {\n expanded: false,\n }\n );\n this.$set(\n this.expansioninfo.lines, \n period.period.id, \n {}\n );\n }\n for (const line of period.lines) {\n const lid = line.line.id;\n if (!this.expansioninfo.lines[lid]) {\n // Use this.$set to make sure the properties are reactive.\n this.$set(\n this.expansioninfo.lines[pid],\n lid, \n {\n expanded: true,\n }\n );\n }\n for (const item of line.items) {\n if (!this.expansioninfo.items[item.id]) {\n // Use this.$set to make sure the properties are reactive.\n this.$set(\n this.expansioninfo.items,\n item.id,\n {\n expanded: false,\n }\n );\n }\n }\n }\n }\n }\n }\n },\n methods: {\n loadStudents() {\n const self = this;\n call([{\n methodname: 'local_treestudyplan_all_associated_grouped',\n args: { studyplan_id: this.structure.studyplan.id}\n }])[0].then(function(response){\n self.students = response;\n for(const group of self.students) {\n self.$set(\n self.groupinfo,\n group.label,\n {\n expand: true,\n }\n );\n\n for(const student of group.users){\n self.$set(\n self.studentresults,\n student.id, \n {\n loading: true,\n results: [],\n }\n );\n call([{\n methodname: 'local_treestudyplan_get_report_data',\n args: { pageid: self.structure.page.id, \n userid: student.id,\n firstperiod: self.structure.firstperiod,\n lastperiod: self.structure.lastperiod,\n }\n }])[0].then(function(response){\n self.studentresults[student.id].loading = false;\n self.studentresults[student.id].results = response;\n }).catch(notification.exception);\n }\n }\n }).catch(notification.exception);\n },\n expansionChanged(parm, id, val) {\n if(parm[0] == 'p') {\n parm = 'periods';\n } else if(parm[0] == 'l') {\n parm = 'lines';\n } else {\n parm = 'items';\n }\n debug.info('Expansion Changed',parm,id,val);\n\n if (parm == 'lines') {\n this.expansioninfo[parm][id[0]][id[1]].expanded = val;\n } else {\n this.expansioninfo[parm][id].expanded = val;\n }\n\n }\n },\n template: `\n
\n \n
\n \n
\n
\n `,\n });\n\n Vue.component('q-header', {\n props: {\n structure: {\n type: Object,\n },\n sorting: {\n type: Object,\n },\n expansion: {\n type: Object\n },\n },\n data() {\n return {\n text: strings.header,\n };\n },\n computed: {\n },\n methods: {\n conditions(item) {\n const course = item.course;\n const list = [];\n debug.info(\"Determining conditions\", course);\n if (course.completion) {\n debug.info(\"Has Competencies\");\n for (const cmp of course.competencies) {\n list.push({\n name: cmp.title,\n });\n }\n } else if(course.completion) {\n debug.info(\"Has Core completion\");\n for (const cnd of course.completion.conditions) {\n for (const itm of cnd.items) {\n list.push({\n name: itm.title,\n });\n }\n }\n } else if(course.grades) {\n debug.info(\"Has selected grades\");\n for (const g of course.grades) {\n list.push({\n name: g.name,\n });\n }\n }\n\n return list;\n },\n colspanPeriod(period) {\n if (this.expansion.periods[period.id].expanded) {\n let sum = 0;\n for (const l of period.lines) {\n sum += this.colspanLine(period,l);\n }\n return sum;\n } else {\n return 1;\n }\n },\n colspanLine(period,line) {\n if (this.expansion.lines[period.id][line.id].expanded) {\n let sum = 0;\n for (const i of line.items) {\n sum += this.colspanItem(i);\n }\n return sum;\n } else {\n return 1;\n }\n },\n colspanItem(item) {\n if (this.expansion.items[item.id].expanded) {\n const cs = this.conditions(item);\n return 1+cs.length;\n } else {\n return 1;\n }\n }\n\n },\n mounted() {\n \n },\n updated() {\n },\n /* https://css-tricks.com/position-sticky-and-table-headers/ */\n /* TODO: Rework below to make use of tables. Use as main element. Then create multiple as needed for the headers.\n This should create a much better view than using divs overal.\n */\n template: `\n \n \n {{text.students}}\n
{{ p.period.fullname}}<\n /th>\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n `,\n });\n\n Vue.component('q-groupheading', {\n props: {\n structure: {\n type: Object,\n },\n },\n data() {\n return {\n\n };\n },\n computed: {\n },\n methods: {\n },\n template: `\n
\n\n
\n `,\n });\n\n Vue.component('q-studentresults', {\n props: {\n student: {\n type: Object,\n },\n structure: {\n type: Object,\n },\n results: {\n type: Array,\n },\n loading: {\n type: Boolean,\n default: false\n },\n expansion: {\n type: Object,\n },\n },\n data() {\n return {\n text: strings.studentresults,\n };\n },\n computed: {\n },\n methods: {\n useritems(line) {\n const list = [];\n for (const item of line.items) {\n let newitm = item;\n for (const itm of this.results) {\n if (item.id == itm.id) {\n newitm = itm;\n break;\n }\n }\n list.push(newitm);\n }\n return list;\n }\n },\n /* https://css-tricks.com/position-sticky-and-table-headers/ */\n /* TODO: Rework below to make use of tables. Use as main element. Then create multiple as needed for the headers.\n This should create a much better view than using divs overal.\n */\n template: `\n \n {{student.firstname}} {{student.lastname}}\n \n \n  \n \n \n `,\n });\n\n Vue.component('q-courseresult', {\n props: {\n student: {\n type: Object,\n },\n item: {\n type: Object,\n },\n loading: {\n type: Boolean,\n default: false\n },\n },\n data() {\n return {\n text: strings.studentresults,\n };\n },\n computed: {\n hasprogressinfo() {\n const course = this.item.course;\n if (!course.enrolled) {\n return false;\n } else {\n return (course.completion || course.competency || course.grades);\n }\n },\n completion_icon() {\n const completion = this.item.completion;\n switch(completion){\n default: // case \"incomplete\"\n return \"circle-o\";\n case \"pending\":\n return \"question-circle\";\n case \"failed\":\n return \"times-circle\";\n case \"progress\":\n return \"exclamation-circle\";\n case \"completed\":\n return \"check-circle\";\n case \"good\":\n return \"check-circle\";\n case \"excellent\":\n return \"check-circle\";\n }\n },\n },\n methods: {\n },\n template: `\n
\n \n \n \n
\n `,\n });\n\n Vue.component('q-conditionresult', {\n props: {\n student: {\n type: Object,\n },\n item: {\n type: Object,\n },\n loading: {\n type: Boolean,\n default: false\n },\n conditionidx: {\n type: Number,\n }\n },\n data() {\n return {\n text: strings.studentresults,\n };\n },\n computed: {\n conditions() {\n const course = this.item.course;\n const list = [];\n debug.info(\"Determining conditions\", course);\n if (course.completion) {\n debug.info(\"Has Competencies\");\n return course.competencies;\n } else if(course.completion) {\n debug.info(\"Has Core completion\");\n const list = [];\n for (const cnd of course.completion.conditions) {\n for (const itm of cnd.items) {\n list.push(itm);\n }\n }\n return list;\n } else if(course.grades) {\n return course.grades;\n }\n },\n condition() {\n if (this.conditionidx >= 0 && this.conditionidx < this.conditions.length) {\n return this.conditions[this.conditionidx];\n } else {\n return null;\n }\n },\n hasprogressinfo() {\n const course = this.item.course;\n if (!course.enrolled) {\n return false;\n } else {\n return (course.completion || course.competency || course.grades);\n }\n },\n },\n methods: {\n completion_icon(completion) {\n switch(completion){\n default: // case \"incomplete\"\n return \"circle-o\";\n case \"pending\":\n return \"question-circle\";\n case \"failed\":\n return \"times-circle\";\n case \"progress\":\n return \"exclamation-circle\";\n case \"completed\":\n return \"check-circle\";\n case \"good\":\n return \"check-circle\";\n case \"excellent\":\n return \"check-circle\";\n }\n },\n },\n // TODO: Show actual grades when relevant at all (don;t forget the grade point completion requirement)\n template: `\n
\n \n \n \n \n
\n `,\n });\n\n\n\n },\n};"],"names":["Math","PI","install","Vue","use","TSComponents","debug","Debugger","strings","report","loading","studyplan_past","studyplan_present","studyplan_future","back","invalid","error","header","overall","students","studentresults","completion_incomplete","completion_failed","completion_pending","completion_progress","completion_completed","completion_good","completion_excellent","student_not_tracked","component","props","structure","type","Object","data","expansioninfo","periods","lines","items","groupinfo","sorting","name","created","loadStudents","computed","sortedstudents","this","watch","immediate","handler","period","pid","id","$set","expanded","line","lid","item","methods","self","methodname","args","studyplan_id","studyplan","then","response","group","label","expand","student","users","results","pageid","page","userid","firstperiod","lastperiod","catch","notification","exception","expansionChanged","parm","val","info","template","expansion","text","conditions","course","list","completion","cmp","competencies","push","title","cnd","itm","grades","g","colspanPeriod","sum","l","colspanLine","i","colspanItem","length","mounted","updated","Array","Boolean","default","useritems","newitm","hasprogressinfo","enrolled","competency","completion_icon","conditionidx","Number","condition"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"studyplan-report-components.min.js","sources":["../src/studyplan-report-components.js"],"sourcesContent":["/*eslint no-var: \"error\"*/\n/*eslint no-console: \"off\"*/\n/*eslint no-unused-vars: warn */\n/*eslint max-len: [\"error\", { \"code\": 160 }] */\n/*eslint-disable no-trailing-spaces */\n/*eslint-env es6*/\n// Put this file in path/to/plugin/amd/src\n\nimport {load_strings} from './util/string-helper';\nimport {call} from 'core/ajax';\nimport notification from 'core/notification';\nimport Debugger from './util/debugger';\nimport Config from 'core/config';\nimport TSComponents from './treestudyplan-components';\n\n\nconst debug = new Debugger(\"treestudyplan-viewer\");\n\n\n// Make π available as a constant\nconst π = Math.PI;\n// Gravity value for arrow lines - determines how much a line is pulled in the direction of the start/end before changing direction\nconst LINE_GRAVITY = 1.3;\n\n/**\n * Retrieve condition headers\n * @param {Object} item\n */\nfunction conditionHeaders(item) {\n const course = item.course;\n const list = [];\n if (course.completion) {\n for (const cmp of course.competencies) {\n list.push({\n name: cmp.title,\n });\n }\n } else if(course.completion) {\n for (const cnd of course.completion.conditions) {\n for (const itm of cnd.items) {\n list.push({\n name: itm.title,\n });\n }\n }\n } else if(course.grades) {\n for(const g of course.grades) {\n if (g.selected) {\n debug.info(\"...included\");\n list.push({\n name: g.name,\n });\n }\n }\n }\n debug.info(\"Returning list\",list);\n return list;\n}\n\n/**\n * Retrieve conditions\n * @param {Object} item\n */\nfunction conditions(item) {\n const course = item.course;\n const list = [];\n if (course.completion) {\n for (const cmp of course.competencies) {\n list.push(cmp);\n }\n } else if(course.completion) {\n for (const cnd of course.completion.conditions) {\n for (const itm of cnd.items) {\n list.push(itm);\n }\n }\n } else if(course.grades) {\n for(const g of course.grades) {\n if (g.selected) {\n list.push(g);\n }\n }\n }\n return list;\n}\n\n\nexport default {\n install(Vue/*,options*/){\n Vue.use(TSComponents);\n\n let strings = load_strings({\n report: {\n loading: \"loadinghelp@core\",\n studyplan_past: \"studyplan_past\",\n studyplan_present: \"studyplan_present\",\n studyplan_future: \"studyplan_future\",\n back: \"back\",\n },\n \n invalid: {\n error: 'error',\n },\n header: {\n overall: 'overall',\n students: 'students@core'\n },\n studentresults: {\n completion_incomplete: \"completion_incomplete\",\n completion_failed: \"completion_failed\",\n completion_pending: \"completion_pending\",\n completion_progress: \"completion_progress\",\n completion_completed: \"completion_completed\",\n completion_good: \"completion_good\",\n completion_excellent: \"completion_excellent\",\n student_not_tracked: \"student_not_tracked\",\n }\n });\n\n /************************************\n * *\n * Treestudyplan Viewer components *\n * *\n ************************************/\n\n Vue.component('q-studyplanreport', {\n props: {\n structure: {\n type: Object,\n },\n },\n data() {\n return {\n students: [],\n studentresults: {},\n expansioninfo: {\n periods: {},\n lines: {},\n items: {},\n },\n groupinfo: {},\n\n sorting: {\n name: \"asc\",\n }\n };\n },\n created() {\n this.loadStudents();\n },\n watch:{\n structure: {\n immediate: true,\n handler (structure) {\n // (Re)build expansion info structure\n for (const period of structure.periods) {\n const pid = period.period.id;\n if (!this.expansioninfo.periods[pid]) {\n // Use this.$set to make sure the properties are reactive.\n this.$set(\n this.expansioninfo.periods, \n pid, \n {\n expanded: false,\n }\n );\n this.$set(\n this.expansioninfo.lines, \n period.period.id, \n {}\n );\n }\n for (const line of period.lines) {\n const lid = line.line.id;\n if (!this.expansioninfo.lines[lid]) {\n // Use this.$set to make sure the properties are reactive.\n this.$set(\n this.expansioninfo.lines[pid],\n lid, \n {\n expanded: true,\n }\n );\n }\n for (const item of line.items) {\n if (!this.expansioninfo.items[item.id]) {\n // Use this.$set to make sure the properties are reactive.\n this.$set(\n this.expansioninfo.items,\n item.id,\n {\n expanded: false,\n }\n );\n }\n }\n }\n }\n }\n }\n },\n computed: {\n sortedstudents(){\n return this.students;\n },\n resultColCount(){\n let count = 0;\n for (const period of this.structure.periods) {\n const pid = period.period.id;\n if (!this.expansioninfo.periods[pid].expanded) {\n // This period is not expanded. Just one \n count += 1;\n } else {\n for (const line of period.lines) {\n const lid = line.line.id;\n if (!this.expansioninfo.lines[pid][lid]) {\n count +=1;\n } else { \n for (const item of line.items) {\n if (!this.expansioninfo.items[item.id]) {\n count += 1;\n } else {\n count += 1 + conditions(item).length;\n }\n }\n }\n }\n }\n }\n return count; \n }\n },\n methods: {\n loadStudents() {\n const self = this;\n call([{\n methodname: 'local_treestudyplan_all_associated_grouped',\n args: { studyplan_id: this.structure.studyplan.id}\n }])[0].then(function(response){\n self.students = response;\n for(const group of self.students) {\n self.$set(\n self.groupinfo,\n group.label,\n {\n expand: true,\n }\n );\n\n for(const student of group.users){\n self.$set(\n self.studentresults,\n student.id, \n {\n loading: true,\n results: [],\n }\n );\n call([{\n methodname: 'local_treestudyplan_get_report_data',\n args: { pageid: self.structure.page.id, \n userid: student.id,\n firstperiod: self.structure.firstperiod,\n lastperiod: self.structure.lastperiod,\n }\n }])[0].then(function(response){\n self.studentresults[student.id].loading = false;\n self.studentresults[student.id].results = response;\n }).catch(notification.exception);\n }\n }\n }).catch(notification.exception);\n },\n expansionChanged(parm, id, val) {\n if(parm[0] == 'p') {\n parm = 'periods';\n } else if(parm[0] == 'l') {\n parm = 'lines';\n } else {\n parm = 'items';\n }\n debug.info('Expansion Changed',parm,id,val);\n\n if (parm == 'lines') {\n this.expansioninfo[parm][id[0]][id[1]].expanded = val;\n } else {\n this.expansioninfo[parm][id].expanded = val;\n }\n },\n\n },\n template: `\n \n \n \n
\n `,\n });\n\n Vue.component('q-header', {\n props: {\n structure: {\n type: Object,\n },\n sorting: {\n type: Object,\n },\n expansion: {\n type: Object\n },\n },\n data() {\n return {\n text: strings.header,\n };\n },\n computed: {\n },\n methods: {\n conditions(item) {\n return conditionHeaders(item);\n },\n colspanPeriod(period) {\n const pid = period.period.id;\n debug.info(\"Checking period expansion\",period,this.expansion.periods);\n if (this.expansion.periods[pid].expanded) {\n let sum = 0;\n for (const l of period.lines) {\n sum += this.colspanLine(period,l);\n }\n return sum;\n } else {\n return 1;\n }\n },\n colspanLine(period,line) {\n const pid = period.period.id;\n const lid = line.line.id;\n\n if (this.expansion.lines[pid][lid].expanded) {\n let sum = 0;\n for (const i of line.items) {\n sum += this.colspanItem(i);\n }\n return sum;\n } else {\n return 1;\n }\n },\n colspanItem(item) {\n if (this.expansion.items[item.id].expanded) {\n const cs = this.conditions(item);\n return 1+cs.length;\n } else {\n return 1;\n }\n }\n\n },\n mounted() {\n \n },\n updated() {\n },\n /* https://css-tricks.com/position-sticky-and-table-headers/ */\n /* TODO: Rework below to make use of tables. Use as main element. Then create multiple as needed for the headers.\n This should create a much better view than using divs overal.\n */\n template: `\n \n \n {{text.students}}\n  {{ p.period.fullname}}\n \n \n \n \n \n \n \n \n \n \n \n \n `,\n });\n\n Vue.component('q-groupheading', {\n props: {\n structure: {\n type: Object,\n },\n },\n data() {\n return {\n\n };\n },\n computed: {\n },\n methods: {\n },\n template: `\n \n\n \n `,\n });\n\n Vue.component('q-studentresults', {\n props: {\n student: {\n type: Object,\n },\n structure: {\n type: Object,\n },\n results: {\n type: Array,\n },\n loading: {\n type: Boolean,\n default: false\n },\n expansion: {\n type: Object,\n },\n },\n data() {\n return {\n text: strings.studentresults,\n };\n },\n computed: {\n },\n methods: {\n useritems(line) {\n const list = [];\n for (const item of line.items) {\n let newitm = item;\n for (const itm of this.results) {\n if (item.id == itm.id) {\n newitm = itm;\n break;\n }\n }\n list.push(newitm);\n }\n return list;\n },\n conditions(item) {\n return conditions(item);\n },\n },\n /* https://css-tricks.com/position-sticky-and-table-headers/ */\n /* TODO: Rework below to make use of tables. Use as main element. Then create multiple as needed for the headers.\n This should create a much better view than using divs overal.\n */\n template: `\n \n {{student.firstname}} {{student.lastname}}\n \n \n `,\n });\n\n Vue.component('q-courseresult', {\n props: {\n student: {\n type: Object,\n },\n item: {\n type: Object,\n },\n loading: {\n type: Boolean,\n default: false\n },\n },\n data() {\n return {\n text: strings.studentresults,\n };\n },\n computed: {\n hasprogressinfo() {\n const course = this.item.course;\n if (!course.enrolled) {\n return false;\n } else {\n return (course.completion || course.competency || course.grades);\n }\n },\n completion_icon() {\n const completion = this.item.completion;\n switch(completion){\n default: // case \"incomplete\"\n return \"circle-o\";\n case \"pending\":\n return \"question-circle\";\n case \"failed\":\n return \"times-circle\";\n case \"progress\":\n return \"exclamation-circle\";\n case \"completed\":\n return \"check-circle\";\n case \"good\":\n return \"check-circle\";\n case \"excellent\":\n return \"check-circle\";\n }\n },\n },\n methods: {\n },\n template: `\n \n \n \n \n \n `,\n });\n\n Vue.component('q-conditionresult', {\n props: {\n student: {\n type: Object,\n },\n item: {\n type: Object,\n },\n loading: {\n type: Boolean,\n default: false\n },\n conditionidx: {\n type: Number,\n }\n },\n data() {\n return {\n text: strings.studentresults,\n };\n },\n computed: {\n conditions() {\n return conditions(this.item);\n },\n condition() {\n if (this.conditionidx >= 0 && this.conditionidx < this.conditions.length) {\n return this.conditions[this.conditionidx];\n } else {\n return null;\n }\n },\n hasprogressinfo() {\n const course = this.item.course;\n if (!course.enrolled) {\n return false;\n } else {\n return (course.completion || course.competency || course.grades);\n }\n },\n },\n methods: {\n completion_icon(completion) {\n switch(completion){\n default: // case \"incomplete\"\n return \"circle-o\";\n case \"pending\":\n return \"question-circle\";\n case \"failed\":\n return \"times-circle\";\n case \"progress\":\n return \"exclamation-circle\";\n case \"completed\":\n return \"check-circle\";\n case \"good\":\n return \"check-circle\";\n case \"excellent\":\n return \"check-circle\";\n }\n },\n },\n // TODO: Show actual grades when relevant at all (don;t forget the grade point completion requirement)\n template: `\n \n \n \n \n \n `,\n });\n\n\n\n },\n};"],"names":["debug","Debugger","Math","PI","conditions","item","course","list","completion","cmp","competencies","push","cnd","itm","items","grades","g","selected","install","Vue","use","TSComponents","strings","report","loading","studyplan_past","studyplan_present","studyplan_future","back","invalid","error","header","overall","students","studentresults","completion_incomplete","completion_failed","completion_pending","completion_progress","completion_completed","completion_good","completion_excellent","student_not_tracked","component","props","structure","type","Object","data","expansioninfo","periods","lines","groupinfo","sorting","name","created","loadStudents","watch","immediate","handler","period","pid","id","this","$set","expanded","line","lid","computed","sortedstudents","resultColCount","count","length","methods","self","methodname","args","studyplan_id","studyplan","then","response","group","label","expand","student","users","results","pageid","page","userid","firstperiod","lastperiod","catch","notification","exception","expansionChanged","parm","val","info","template","expansion","text","title","conditionHeaders","colspanPeriod","sum","l","colspanLine","i","colspanItem","mounted","updated","Array","Boolean","default","useritems","newitm","hasprogressinfo","enrolled","competency","completion_icon","conditionidx","Number","condition"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/studyplan-report-components.js b/amd/src/studyplan-report-components.js index d7f4ab5..a9dac8a 100644 --- a/amd/src/studyplan-report-components.js +++ b/amd/src/studyplan-report-components.js @@ -13,16 +13,81 @@ import Debugger from './util/debugger'; import Config from 'core/config'; import TSComponents from './treestudyplan-components'; + +const debug = new Debugger("treestudyplan-viewer"); + + // Make π available as a constant const π = Math.PI; // Gravity value for arrow lines - determines how much a line is pulled in the direction of the start/end before changing direction const LINE_GRAVITY = 1.3; +/** + * Retrieve condition headers + * @param {Object} item + */ +function conditionHeaders(item) { + const course = item.course; + const list = []; + if (course.completion) { + for (const cmp of course.competencies) { + list.push({ + name: cmp.title, + }); + } + } else if(course.completion) { + for (const cnd of course.completion.conditions) { + for (const itm of cnd.items) { + list.push({ + name: itm.title, + }); + } + } + } else if(course.grades) { + for(const g of course.grades) { + if (g.selected) { + debug.info("...included"); + list.push({ + name: g.name, + }); + } + } + } + debug.info("Returning list",list); + return list; +} + +/** + * Retrieve conditions + * @param {Object} item + */ +function conditions(item) { + const course = item.course; + const list = []; + if (course.completion) { + for (const cmp of course.competencies) { + list.push(cmp); + } + } else if(course.completion) { + for (const cnd of course.completion.conditions) { + for (const itm of cnd.items) { + list.push(itm); + } + } + } else if(course.grades) { + for(const g of course.grades) { + if (g.selected) { + list.push(g); + } + } + } + return list; +} + export default { install(Vue/*,options*/){ Vue.use(TSComponents); - let debug = new Debugger("treestudyplan-viewer"); let strings = load_strings({ report: { @@ -83,11 +148,6 @@ export default { created() { this.loadStudents(); }, - computed: { - sortedstudents(){ - return this.students; - } - }, watch:{ structure: { immediate: true, @@ -139,6 +199,37 @@ export default { } } }, + computed: { + sortedstudents(){ + return this.students; + }, + resultColCount(){ + let count = 0; + for (const period of this.structure.periods) { + const pid = period.period.id; + if (!this.expansioninfo.periods[pid].expanded) { + // This period is not expanded. Just one + count += 1; + } else { + for (const line of period.lines) { + const lid = line.line.id; + if (!this.expansioninfo.lines[pid][lid]) { + count +=1; + } else { + for (const item of line.items) { + if (!this.expansioninfo.items[item.id]) { + count += 1; + } else { + count += 1 + conditions(item).length; + } + } + } + } + } + } + return count; + } + }, methods: { loadStudents() { const self = this; @@ -195,32 +286,30 @@ export default { } else { this.expansioninfo[parm][id].expanded = val; } + }, - } }, template: ` -
+ -
-