moodle_local_treestudyplan/amd/build/studyplan-report-components.min.js.map
2024-02-20 20:40:18 +01:00

1 line
35 KiB
Plaintext

{"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 <table class='q-studyplanreport'>\n <q-header \n :sorting='sorting' \n :structure='structure'\n :expansion='expansioninfo'\n @expansion='expansionChanged'\n ></q-header>\n <template v-for=\"group in sortedstudents\">\n <q-groupheading v-if=\"group.users\" :label=\"group.label\" :groupinfo=\"groupinfo[group.label]\"></q-groupheading>\n <template v-if='group.users && groupinfo[group.label].expand'>\n <q-studentresults v-for=\"student in group.users\"\n :student='student'\n :structure='structure'\n :results='studentresults[student.id].results'\n :loading='studentresults[student.id].loading'\n :expansion='expansioninfo'\n ></q-studentresults>\n </template>\n </template>\n </table>\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 <Thead> as main element. Then create multiple <tr> as needed for the headers.\n This should create a much better view than using divs overal.\n */\n template: `\n <thead class='q-header'>\n <tr> <!-- period heading -->\n <th rowspan='4' class='q-studentname'><span>{{text.students}}</span></th>\n <th v-for=\"p in structure.periods\" \n class='q-period-heading'\n :colspan='colspanPeriod(p)'\n :rowspan='(expansion.periods[p.period.id].expanded)?1:4'\n ><a v-if=\"expansion.periods[p.period.id].expanded\"\n href='#' @click.prevent=\"$emit('expansion','periods',p.period.id,false);\"\n ><i class='fa fa-minus-square'></i></a\n ><a v-else\n href='#' @click.prevent=\"$emit('expansion','periods',p.period.id,true);\"\n ><i class='fa fa-plus-square'></i></a\n >&nbsp;{{ p.period.fullname}}\n </th>\n </tr>\n <tr> <!-- line heading -->\n <template v-for=\"p in structure.periods\">\n <template v-if=\"expansion.periods[p.period.id].expanded\"> \n <th v-for=\"l in p.lines\"\n class='q-line-heading'\n :colspan=\"colspanLine(p,l)\"\n ><span v-html=\"l.line.shortname\"></span\n ></th>\n </template>\n </template>\n </tr>\n <tr> <!-- item heading -->\n <template v-for=\"p in structure.periods\"> \n <template v-if=\"expansion.periods[p.period.id].expanded\"> \n <template v-for=\"l in p.lines\">\n <template v-if=\"expansion.lines[p.period.id][l.line.id].expanded\">\n <th v-for=\"item in l.items\"\n :class=\"'q-item-heading ' + ((expansion.items[item.id].expanded)?'expanded':'collapsed')\"\n :colspan=\"colspanItem(item)\"\n :rowspan='(expansion.items[item.id].expanded)?1:2'\n ><a v-if=\"expansion.items[item.id].expanded\"\n href='#' @click.prevent=\"$emit('expansion','items',item.id,false);\"\n ><i class='fa fa-minus-square'></i></a\n ><a v-else\n href='#' @click.prevent=\"$emit('expansion','items',item.id,true);\"\n ><i class='fa fa-plus-square'></i></a\n >&nbsp;<span v-html=\"item.course.displayname\"></span\n ></th>\n </template>\n </template>\n </template>\n </template>\n </tr>\n <tr> <!-- condition heading -->\n <template v-for=\"p in structure.periods\">\n <template v-if=\"expansion.periods[p.period.id].expanded\"> \n <template v-for=\"l in p.lines\">\n <template v-if=\"expansion.lines[p.period.id][l.line.id].expanded\">\n <template v-for=\"item in l.items\">\n <template v-if=\"expansion.items[item.id].expanded\">\n <th class='q-condition-heading overall'\n ><span>{{ text.overall }}</span></th>\n <th v-for=\"c in conditions(item)\"\n class='q-condition-heading'\n ><span v-html=\"c.name\"></span\n ></th>\n </template>\n </template>\n </template>\n </template>\n </template>\n </template>\n </tr>\n </thead>\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 <tr class='q-groupheading'>\n\n </tr>\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 <Thead> as main element. Then create multiple <tr> as needed for the headers.\n This should create a much better view than using divs overal.\n */\n template: `\n <tr class='q-student-results'>\n <td class='q-studentname'><span>{{student.firstname}} {{student.lastname}}</span></td>\n <template v-for=\"p in structure.periods\">\n <template v-if=\"expansion.periods[p.period.id].expanded\"> \n <template v-for=\"l in p.lines\">\n <template v-if=\"expansion.lines[p.period.id][l.line.id].expanded\">\n <template v-for=\"item in useritems(l)\">\n <td class='q-result overall'\n ><q-courseresult\n :item=\"item\"\n :student=\"student\"\n :loading=\"loading\"\n ></q-courseresult\n ></td>\n <template v-if=\"expansion.items[item.id].expanded\">\n <td v-for=\"(c,idx) in conditions(item)\"\n class='q-result'\n ><q-conditionresult\n :item=\"item\"\n :conditionidx=\"idx\"\n :student=\"student\"\n :loading=\"loading\"\n ></q-conditionresult\n ></td>\n </template>\n </template>\n </template>\n <td v-else class='q-result collapsed'>&nbsp;</td>\n </template>\n </template>\n <td v-else class='q-result collapsed'>&nbsp;</td>\n </template>\n </tr>\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 <span class='q-courseresult'>\n <template v-if=\"loading\">\n <div class=\"spinner-border spinner-border-sm text-info\" role=\"status\"></div>\n </template>\n <template v-else-if='!item.course.enrolled'>\n <i v-b-popover.top\n class=\"fa fa-exclamation-triangle t-not-enrolled-alert\"\n :title=\"text.student_not_tracked\"></i>\n </template>\n <template v-else>\n <i v-b-popover.top\n :class=\"'fa fa-'+completion_icon+\n ' r-completion-'+item.completion\"\n :title=\"text['completion_'+item.completion]\"></i>\n </template>\n </span>\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 <span class='q-conditionresult'>\n <template v-if=\"loading\">\n <div class=\"spinner-border spinner-border-sm text-info\" role=\"status\"></div>\n </template>\n <template v-else-if='!item.course.enrolled'>\n <i v-b-popover.top\n class=\"fa fa-exclamation-triangle t-not-enrolled-alert\"\n :title=\"text.student_not_tracked\"></i>\n </template>\n <template v-else>\n <i v-b-popover.top\n :class=\"'fa fa-'+completion_icon(item.completion)+\n ' r-completion-'+item.completion\"\n :title=\"text['completion_'+item.completion]\"></i>\n </template>\n </span>\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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"}