2023-05-17 21:19:14 +02:00
|
|
|
/*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
|
|
|
|
|
2023-09-03 16:54:09 +02:00
|
|
|
import {load_strings} from './util/string-helper';
|
|
|
|
import {format_date} from './util/date-helper';
|
2023-05-17 21:19:14 +02:00
|
|
|
|
|
|
|
export default {
|
|
|
|
studyplanTiming(a) {
|
|
|
|
const now = new Date().getTime();
|
|
|
|
let timing = 'future';
|
|
|
|
if(new Date(a.startdate).getTime() < now){
|
|
|
|
if(a.enddate && now > new Date(a.enddate).getTime()) {
|
|
|
|
timing = 'past';
|
|
|
|
} else {
|
|
|
|
timing = 'present';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return timing;
|
|
|
|
},
|
|
|
|
|
|
|
|
install(Vue/*,options*/){
|
|
|
|
let strings = load_strings({
|
|
|
|
studyplancard: {
|
|
|
|
open: "open",
|
|
|
|
noenddate: "noenddate",
|
2023-10-23 21:54:09 +02:00
|
|
|
idnumber: "studyplan_idnumber",
|
2023-10-23 23:19:14 +02:00
|
|
|
description: "studyplan_description",
|
|
|
|
completed: "completed",
|
2023-05-17 21:19:14 +02:00
|
|
|
}
|
|
|
|
});
|
2023-07-28 00:04:24 +02:00
|
|
|
// Create new eventbus for interaction between item components
|
|
|
|
const ItemEventBus = new Vue();
|
2023-05-17 21:19:14 +02:00
|
|
|
|
|
|
|
Vue.component('s-studyplan-card', {
|
|
|
|
props: {
|
|
|
|
value: {
|
|
|
|
type: Object,
|
|
|
|
},
|
|
|
|
open: {
|
|
|
|
type: Boolean
|
2023-10-23 23:19:14 +02:00
|
|
|
},
|
2023-05-17 21:19:14 +02:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
text: strings.studyplancard
|
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
timing(){
|
|
|
|
const now = new Date().getTime();
|
2023-07-27 12:28:04 +02:00
|
|
|
const startdate = new Date(this.value.pages[0].startdate).getTime();
|
|
|
|
const enddate = new Date(this.value.pages[0].enddate).getTime();
|
2023-05-17 21:19:14 +02:00
|
|
|
let timing = 'future';
|
|
|
|
if(startdate < now){
|
2023-07-27 12:28:04 +02:00
|
|
|
if(this.value.pages[0].enddate && now > enddate) {
|
2023-05-17 21:19:14 +02:00
|
|
|
timing = 'past';
|
|
|
|
} else {
|
|
|
|
timing = 'present';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return timing;
|
|
|
|
},
|
|
|
|
startdate(){
|
2023-07-28 23:43:11 +02:00
|
|
|
return format_date(this.value.pages[0].startdate);
|
2023-05-17 21:19:14 +02:00
|
|
|
},
|
|
|
|
enddate(){
|
2023-08-16 23:38:46 +02:00
|
|
|
if(this.value.pages[0].enddate){
|
2023-07-28 23:43:11 +02:00
|
|
|
return format_date(this.value.pages[0].enddate);
|
2023-09-08 12:47:29 +02:00
|
|
|
}
|
2023-05-17 21:19:14 +02:00
|
|
|
else {
|
|
|
|
return this.text.noenddate;
|
|
|
|
}
|
2023-10-23 23:19:14 +02:00
|
|
|
},
|
|
|
|
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%";
|
|
|
|
}
|
2023-05-17 21:19:14 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onOpenClick(e) {
|
|
|
|
this.$emit('open',e);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
template: `
|
2023-09-08 12:47:29 +02:00
|
|
|
<b-card
|
2023-05-17 21:19:14 +02:00
|
|
|
:class="'s-studyplan-card timing-' + timing"
|
|
|
|
>
|
|
|
|
<template #header></template>
|
2023-10-23 21:54:09 +02:00
|
|
|
|
2023-10-23 23:19:14 +02:00
|
|
|
<div class='s-studyplan-card-content'>
|
|
|
|
<div class='s-studyplan-card-icon'><img :src='value.icon'></div>
|
|
|
|
<div class='s-studyplan-card-info'>
|
|
|
|
<div class='s-studyplan-card-titlebar'>
|
|
|
|
<b-card-title>
|
|
|
|
<a v-if='open' href='#' @click.prevent='onOpenClick($event)'>{{value.name}}</a>
|
|
|
|
<template v-else>{{value.name}}</template>
|
|
|
|
</b-card-title>
|
|
|
|
<div class='s-studyplan-card-titleslot'><slot name='title'></slot></div>
|
|
|
|
</div>
|
|
|
|
<div class='s-studyplan-card-idnumber' v-if='value.idnumber'>
|
|
|
|
{{ text.idnumber }}: {{ value.idnumber }}
|
|
|
|
</div>
|
|
|
|
<div class='s-studyplan-card-progress' v-if='value.progress !== undefined && value.progress !== null'>
|
|
|
|
<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>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
2023-05-17 21:19:14 +02:00
|
|
|
<slot></slot>
|
|
|
|
<template #footer>
|
|
|
|
<span :class="'t-timing-'+timing" v-html="startdate + ' - '+ enddate"></span>
|
|
|
|
<span class="s-studyplan-card-buttons">
|
|
|
|
<slot name='footer'></slot>
|
2023-10-23 21:54:09 +02:00
|
|
|
<template v-if='value.description'>
|
|
|
|
<b-button variant="primary" v-b-modal="'modal-description-'+value.id"
|
|
|
|
><i class='fa fa-info-circle'></i> {{ text.description }}</b-button>
|
|
|
|
<b-modal
|
|
|
|
:title="value.name"
|
|
|
|
scrollable
|
|
|
|
centered
|
|
|
|
ok-only
|
|
|
|
size="xl"
|
|
|
|
:id="'modal-description-'+value.id"
|
|
|
|
><span v-html="value.description"></span>
|
|
|
|
</b-modal>
|
|
|
|
</template>
|
2023-09-08 12:47:29 +02:00
|
|
|
<b-button style="float:right;" v-if='open' variant='primary'
|
2023-05-17 21:19:14 +02:00
|
|
|
@click.prevent='onOpenClick($event)'>{{ text.open }}</b-button>
|
|
|
|
</span>
|
|
|
|
</template>
|
|
|
|
</b-card>
|
|
|
|
`,
|
|
|
|
});
|
2023-07-28 00:04:24 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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: {
|
|
|
|
|
|
|
|
},
|
|
|
|
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: {
|
2023-09-08 12:47:29 +02:00
|
|
|
|
2023-07-28 00:04:24 +02:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onHeaderHeightChange(newheight){
|
2023-08-08 22:47:36 +02:00
|
|
|
if(this.$refs.main){
|
|
|
|
this.$refs.main.style.height = `${newheight}px`;
|
|
|
|
}
|
2023-07-28 00:04:24 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
template: `
|
|
|
|
<div class="s-studyline-header-heading" ref="main"></div>
|
|
|
|
`,
|
|
|
|
});
|
|
|
|
|
|
|
|
Vue.component('s-studyline-header-period', {
|
|
|
|
props: {
|
|
|
|
value: {
|
|
|
|
type: Object, // dict with layer as index
|
|
|
|
},
|
|
|
|
},
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}).observe(self.$refs.main);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
unmounted() {
|
|
|
|
if(this.resizeListener) {
|
|
|
|
this.resizeListener.disconnect();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
2023-07-28 23:43:11 +02:00
|
|
|
startdate(){
|
|
|
|
return format_date(this.value.startdate);
|
|
|
|
},
|
|
|
|
enddate(){
|
|
|
|
return format_date(this.value.enddate);
|
2023-08-03 18:44:57 +02:00
|
|
|
},
|
|
|
|
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;
|
|
|
|
}
|
2023-07-28 23:43:11 +02:00
|
|
|
}
|
2023-08-03 18:44:57 +02:00
|
|
|
|
2023-07-28 00:04:24 +02:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
};
|
|
|
|
},
|
|
|
|
template: `
|
2023-08-03 18:44:57 +02:00
|
|
|
<div :class="'s-studyline-header-period ' + (current?'current ':' ')" ref="main"
|
2023-07-29 12:21:30 +02:00
|
|
|
><p><abbr :id="'s-period-'+value.id" :title="value.fullname">{{ value.shortname }}</abbr>
|
|
|
|
<b-tooltip
|
|
|
|
:target="'s-period-'+value.id" triggers="hover"
|
|
|
|
>{{ value.fullname }}<br>
|
|
|
|
<span class="s-studyline-header-period-datespan">
|
|
|
|
<span class="date">{{ startdate }}</span> - <span class="date">{{ enddate }}</span>
|
2023-07-30 04:08:57 +02:00
|
|
|
</span>
|
2023-07-29 12:21:30 +02:00
|
|
|
</b-tooltip>
|
|
|
|
<slot></slot
|
|
|
|
><p class="s-studyline-header-period-datespan small">
|
2023-07-28 23:43:11 +02:00
|
|
|
<span class="date">{{ startdate }}</span> - <span class="date">{{ enddate }}</span>
|
|
|
|
</p>
|
2023-07-28 00:04:24 +02:00
|
|
|
</div>
|
|
|
|
`,
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2023-05-17 21:19:14 +02:00
|
|
|
}
|
|
|
|
};
|