/*eslint no-var: "error"*/ /*eslint no-console: "off"*/ /*eslint-disable no-trailing-spaces */ /*eslint-env es6*/ // Put this file in path/to/plugin/amd/src import {load_strings} from './util/string-helper'; import {format_date, studyplanDates, studyplanTiming} from './util/date-helper'; export default { install(Vue/*,options*/){ let strings = load_strings({ studyplancard: { open: "open", noenddate: "noenddate", idnumber: "studyplan_idnumber", description: "studyplan_description", completed: "completed", details: "studyplan_details", }, details: { details: "studyplan_details", }, extrafields: { show: "show@core" } }); // Create new eventbus for interaction between item components const ItemEventBus = new Vue(); Vue.component('s-studyplan-card', { props: { value: { type: Object, }, open: { type: Boolean }, }, data() { return { text: strings.studyplancard }; }, computed: { timing(){ return studyplanTiming(this.value); }, dates(){ const dates = studyplanDates(this.value); return { start: format_date(dates.start), end: (dates.end)?format_date(dates.end):this.text.noenddate, }; }, }, methods: { onOpenClick(e) { this.$emit('open',e); } }, template: `
{{ text.idnumber }}: {{ value.idnumber }}
`, }); 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: `
{{ percentage_complete}} {{ text.completed.toLowerCase() }}
`, }); /* * S-STUDYLINE-HEADER-HEADING * The only reasing this is not a simple empty div, is the fact that the header height * needs to match that of the period headers */ Vue.component('s-studyline-header-heading', { props: { identifier: { type: Number, // Page reference. default() { return 0;} } }, data() { return { layerHeights: {} }; }, created() { // Listener for the signal that a new connection was made and needs to be drawn // Sent by the incoming item - By convention, outgoing items are responsible for drawing the lines ItemEventBus.$on('headerHeightChange', this.onHeaderHeightChange); }, computed: { }, methods: { onHeaderHeightChange(newheight,identifier){ if (this.identifier == identifier) { if(this.$refs.main){ this.$refs.main.style.height = `${newheight}px`; } } } }, template: `
`, }); Vue.component('s-studyline-header-period', { props: { value: { type: Object, // dict with layer as index }, identifier: { type: Number, // Page reference. default() { return 0;} } }, mounted() { const self=this; if(self.value.period == 1){ self.resizeListener = new ResizeObserver(() => { if(self.$refs.main){ const size = self.$refs.main.getBoundingClientRect(); ItemEventBus.$emit('headerHeightChange', size.height, self.identifier); } }).observe(self.$refs.main); } }, unmounted() { if(this.resizeListener) { this.resizeListener.disconnect(); } }, computed: { startdate(){ return format_date(this.value.startdate); }, enddate(){ return format_date(this.value.enddate); }, current(){ if( this.value && this.value.startdate && this.value.enddate){ const now = new Date(); const pstart = new Date(this.value.startdate); const pend = new Date(this.value.enddate); return (now >= pstart && now < pend); } else { return false; } } }, data() { return { }; }, template: `

{{ value.shortname }} {{ value.fullname }}
{{ startdate }} - {{ enddate }}

{{ startdate }} - {{ enddate }}

`, }); Vue.component('s-studyplan-details', { props: { value: { type: Object, }, variant: { type: String, default() { return "info"; } }, pill: { type: Boolean, default() { return false; } }, size: { type: String, default() { return "";} } }, data() { return { text: strings.details, }; }, template: ` {{ text.details}} `, }); 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: `
{{ field.title}} {{ displaydate(field) }} {{ field.value }} {{text.show}}...
`, }); } };