Finished implementing frontend CRU for pages
This commit is contained in:
parent
702435566d
commit
a60c259408
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/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
|
@ -128,6 +128,15 @@ export default {
|
|||
required_goal: "required_goal",
|
||||
student_from_plan_enrolled: "student_from_plan_enrolled",
|
||||
students_from_plan_enrolled: "students_from_plan_enrolled",
|
||||
},
|
||||
pageinfo: {
|
||||
edit: 'period_edit',
|
||||
fullname: 'studyplan_name',
|
||||
shortname: 'studyplan_shortname',
|
||||
startdate: 'studyplan_startdate',
|
||||
enddate: 'studyplan_enddate',
|
||||
description: 'studyplan_description',
|
||||
duration: 'studyplan_duration'
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -303,29 +312,34 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
selectedpageindex: 0,
|
||||
text: strings.pageinfo,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
columns() {
|
||||
return 1+ (this.page.periods * 2);
|
||||
|
||||
selectedpage() {
|
||||
return this.value.pages[this.selectedpageindex];
|
||||
},
|
||||
columns_stylerule() {
|
||||
},
|
||||
methods: {
|
||||
pageduration(page){
|
||||
return format_date(page.startdate,false) + " - " + format_date(page.enddate,false);
|
||||
},
|
||||
columns(page) {
|
||||
return 1+ (page.periods * 2);
|
||||
},
|
||||
columns_stylerule(page) {
|
||||
// Uses css variables, so width for slots and filters can be configured in css
|
||||
let s = "grid-template-columns: var(--studyplan-filter-width)"; // use css variable here
|
||||
for(let i=0; i<this.page.periods;i++){
|
||||
for(let i=0; i<page.periods;i++){
|
||||
s+= " var(--studyplan-course-width) var(--studyplan-filter-width)";
|
||||
}
|
||||
return s+";";
|
||||
},
|
||||
page() {
|
||||
//FIXME: Replace this when actual page management is implemented
|
||||
return this.value.pages[0];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
countLineLayers(line){
|
||||
countLineLayers(line,page){
|
||||
let maxLayer = -1;
|
||||
for(let i = 0; i <= this.page.periods; i++){
|
||||
for(let i = 0; i <= page.periods; i++){
|
||||
const slot = line.slots[i];
|
||||
// Determine the amount of used layers in a studyline slit
|
||||
for(const ix in line.slots[i].courses){
|
||||
|
@ -343,11 +357,11 @@ export default {
|
|||
}
|
||||
return (maxLayer >= 0)?(maxLayer+1):1;
|
||||
},
|
||||
showslot(line,index, layeridx, type){
|
||||
showslot(page,line,index, layeridx, type){
|
||||
// check if the slot should be hidden because a previous slot has an item with a span
|
||||
// so big that it hides this slot
|
||||
const forGradable = (type == 'gradable')?true:false;
|
||||
const periods = this.page.periods;
|
||||
const periods = page.periods;
|
||||
let show = true;
|
||||
for(let i = 0; i < periods; i++){
|
||||
if(line.slots[index-i] && line.slots[index-i].courses){
|
||||
|
@ -370,6 +384,10 @@ export default {
|
|||
}
|
||||
|
||||
return show;
|
||||
},
|
||||
selectedpageChanged(newTabIndex,prevTabIndex) {
|
||||
const page = this.value.pages[newTabIndex];
|
||||
scrollCurrentIntoView(this.value.id);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -381,76 +399,129 @@ export default {
|
|||
|
||||
},
|
||||
template: `
|
||||
<div class='r-studyplan-content'>
|
||||
<!-- First paint the headings-->
|
||||
<div class='r-studyplan-headings'
|
||||
><s-studyline-header-heading></s-studyline-header-heading>
|
||||
<r-studyline-heading v-for="(line,lineindex) in page.studylines"
|
||||
:key="line.id"
|
||||
v-model="page.studylines[lineindex]"
|
||||
:layers='countLineLayers(line)+1'
|
||||
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
||||
+ ((lineindex==0)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
></r-studyline-heading
|
||||
></div>
|
||||
<!-- Next, paint all the cells in the scrollable -->
|
||||
<div class="r-studyplan-scrollable" >
|
||||
<div class="r-studyplan-timeline" :style="columns_stylerule">
|
||||
<!-- add period information -->
|
||||
<template v-for="(n,index) in (page.periods+1)">
|
||||
<s-studyline-header-period
|
||||
v-if="index > 0"
|
||||
v-model="page.perioddesc[index-1]"
|
||||
></s-studyline-header-period>
|
||||
<div class="s-studyline-header-filter"></div>
|
||||
<div>
|
||||
<b-card no-body>
|
||||
<b-tabs
|
||||
v-model='selectedpageindex'
|
||||
@activate-tab='selectedpageChanged'
|
||||
content-class="mt-1">
|
||||
<b-tab
|
||||
v-for="(page,pageindex) in value.pages"
|
||||
:key="page.id"
|
||||
:title-item-class="'s-studyplanpage-tab '+ page.timing"
|
||||
><template #title>
|
||||
<span v-b-tooltip.hover :title='page.fullname'>{{page.shortname}}</span>
|
||||
<a href="#" v-b-modal="'studyplanpage-info-'+page.id" variant='info'
|
||||
v-if='pageindex == selectedpageindex'
|
||||
><i class='fa fa-info-circle'></i></a>
|
||||
</template>
|
||||
|
||||
<b-modal
|
||||
:id="'studyplanpage-info-'+page.id"
|
||||
scrollable
|
||||
ok-only
|
||||
>
|
||||
<template #modal-title>
|
||||
{{page.fullname}}
|
||||
</template>
|
||||
<b-container>
|
||||
<b-row>
|
||||
<b-col cols="4"><b>{{ text.shortname}}</b></b-col>
|
||||
<b-col cols="8">
|
||||
{{ page.shortname }}
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="4"><b>{{ text.duration}}</b></b-col>
|
||||
<b-col cols="8">
|
||||
{{ pageduration(page) }}
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row v-if="page.description">
|
||||
<b-col cols="12"><b>{{ text.description}}</b></b-col>
|
||||
</b-row>
|
||||
<b-row v-if="page.description">
|
||||
<b-col cols="12">
|
||||
<span v-html="page.description"></span>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-modal>
|
||||
<div v-if="page.studylines.length > 0" class='r-studyplan-content'>
|
||||
<!-- First paint the headings-->
|
||||
<div class='r-studyplan-headings'
|
||||
><s-studyline-header-heading :identifier="Number(page.id)"></s-studyline-header-heading>
|
||||
<r-studyline-heading v-for="(line,lineindex) in page.studylines"
|
||||
:key="line.id"
|
||||
v-model="page.studylines[lineindex]"
|
||||
:layers='countLineLayers(page,line)+1'
|
||||
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
||||
+ ((lineindex==0)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
></r-studyline-heading
|
||||
></div>
|
||||
<!-- Next, paint all the cells in the scrollable -->
|
||||
<div class="r-studyplan-scrollable" >
|
||||
<div class="r-studyplan-timeline" :style="columns_stylerule(page)">
|
||||
<!-- add period information -->
|
||||
<template v-for="(n,index) in (page.periods+1)">
|
||||
<s-studyline-header-period
|
||||
v-if="index > 0"
|
||||
v-model="page.perioddesc[index-1]"
|
||||
:identifier="Number(page.id)"
|
||||
></s-studyline-header-period>
|
||||
<div class="s-studyline-header-filter"></div>
|
||||
</template>
|
||||
|
||||
<!-- Line by line add the items -->
|
||||
<!-- The grid layout handles putting it in rows and columns -->
|
||||
<template v-for="(line,lineindex) in page.studylines"
|
||||
><template v-for="(layernr,layeridx) in countLineLayers(line)"
|
||||
><template v-for="(n,index) in (page.periods+1)"
|
||||
><r-studyline-slot
|
||||
v-if="index > 0 && showslot(line, index, layeridx, 'gradable')"
|
||||
type='gradable'
|
||||
v-model="line.slots[index].courses"
|
||||
:key="'c-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:period="page.perioddesc[index-1]"
|
||||
:guestmode='guestmode'
|
||||
:teachermode='teachermode'
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
></r-studyline-slot
|
||||
><r-studyline-slot
|
||||
v-if="showslot(line, index, layeridx, 'gradable')"
|
||||
type='filter'
|
||||
v-model="line.slots[index].filters"
|
||||
:teachermode='teachermode'
|
||||
:key="'f-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':'')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((index==page.periods)?' rightmost':'')"
|
||||
>
|
||||
</r-studyline-slot
|
||||
<!-- Line by line add the items -->
|
||||
<!-- The grid layout handles putting it in rows and columns -->
|
||||
<template v-for="(line,lineindex) in page.studylines"
|
||||
><template v-for="(layernr,layeridx) in countLineLayers(page,line)"
|
||||
><template v-for="(n,index) in (page.periods+1)"
|
||||
><r-studyline-slot
|
||||
v-if="index > 0 && showslot(page,line, index, layeridx, 'gradable')"
|
||||
type='gradable'
|
||||
v-model="line.slots[index].courses"
|
||||
:key="'c-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:period="page.perioddesc[index-1]"
|
||||
:guestmode='guestmode'
|
||||
:teachermode='teachermode'
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
></r-studyline-slot
|
||||
><r-studyline-slot
|
||||
v-if="showslot(page,line, index, layeridx, 'gradable')"
|
||||
type='filter'
|
||||
v-model="line.slots[index].filters"
|
||||
:teachermode='teachermode'
|
||||
:key="'f-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':'')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((index==page.periods)?' rightmost':'')"
|
||||
>
|
||||
</r-studyline-slot
|
||||
></template
|
||||
></template
|
||||
></template
|
||||
></template
|
||||
></template
|
||||
></div
|
||||
></div
|
||||
></div>
|
||||
></div
|
||||
></div
|
||||
></div>
|
||||
</b-tab>
|
||||
</b-tabs>
|
||||
</b-card>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
|
|
|
@ -136,6 +136,8 @@ export default {
|
|||
studyplan_edit: {
|
||||
studyplan_edit: 'studyplan_edit',
|
||||
studyplan_add: 'studyplan_add',
|
||||
studyplanpage_add: 'studyplanpage_add',
|
||||
studyplanpage_edit: 'studyplanpage_edit',
|
||||
},
|
||||
period_edit: {
|
||||
edit: 'period_edit',
|
||||
|
@ -241,6 +243,7 @@ export default {
|
|||
type: Object,
|
||||
default(){ return null;},
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -628,7 +631,7 @@ export default {
|
|||
@saved="planSaved"
|
||||
:variant="variant"
|
||||
:type="type"
|
||||
:title="(mode == 'create')?text.studyplan_add:text.studyplan_edit"
|
||||
:title="(mode == 'create')?text.studyplanpage_add:text.studyplanpage_edit"
|
||||
><slot><i class='fa fa-gear'></i></slot></mform>
|
||||
</span>
|
||||
`
|
||||
|
@ -1163,6 +1166,15 @@ export default {
|
|||
cache: {
|
||||
linelayers: {},
|
||||
},
|
||||
selectedpageindex: 0,
|
||||
emptyline: {
|
||||
id: -1,
|
||||
name: '<No study lines defined>',
|
||||
shortname: '<No study lines>',
|
||||
color: '#FF0000',
|
||||
filterslots: [{}],
|
||||
courseslots: [{}]
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
@ -1180,7 +1192,9 @@ export default {
|
|||
ItemEventBus.$emit('redrawLines');
|
||||
},
|
||||
computed: {
|
||||
|
||||
selectedpage() {
|
||||
return this.value.pages[this.selectedpageindex];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
columns(page) {
|
||||
|
@ -1360,7 +1374,6 @@ export default {
|
|||
deleteStudyItem(event){
|
||||
//const self = this;
|
||||
let item = event.data;
|
||||
|
||||
call([{
|
||||
methodname: 'local_treestudyplan_delete_studyitem',
|
||||
args: { 'id': item.id, }
|
||||
|
@ -1426,6 +1439,15 @@ export default {
|
|||
},
|
||||
pagecreated(page) {
|
||||
this.value.pages.push(page);
|
||||
},
|
||||
selectedpageChanged(newTabIndex,prevTabIndex) {
|
||||
const page = this.value.pages[newTabIndex];
|
||||
|
||||
if (page.studylines.length == 0) {
|
||||
this.edit.studyline.editmode = true;
|
||||
} else {
|
||||
this.edit.studyline.editmode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
,
|
||||
|
@ -1466,214 +1488,227 @@ export default {
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<b-tabs content-class="mt-1">
|
||||
<!-- New Tab Button (Using tabs-end slot) -->
|
||||
<template #tabs-end>
|
||||
<t-studyplan-page-edit
|
||||
:studyplan="value"
|
||||
v-model="create.page"
|
||||
type="link"
|
||||
mode="create"
|
||||
@created="pagecreated"
|
||||
><i class='fa fa-plus'></i></t-studyplan-page-edit>
|
||||
</template>
|
||||
<b-tab
|
||||
v-for="(page,pageindex) in value.pages"
|
||||
:key="page.id"
|
||||
>
|
||||
<template #title>
|
||||
{{page.shortname}}
|
||||
<b-card no-body>
|
||||
<b-tabs
|
||||
v-model='selectedpageindex'
|
||||
@activate-tab='selectedpageChanged'
|
||||
content-class="mt-1">
|
||||
<!-- New Tab Button (Using tabs-end slot) -->
|
||||
<template #tabs-end>
|
||||
<t-studyplan-page-edit
|
||||
v-model="value.pages[pageindex]"
|
||||
:studyplan="value"
|
||||
v-model="create.page"
|
||||
type="link"
|
||||
></t-studyplan-page-edit>
|
||||
mode="create"
|
||||
@created="pagecreated"
|
||||
><i class='fa fa-plus'></i></t-studyplan-page-edit>
|
||||
</template>
|
||||
<div class='t-studyplan-content-edit' v-if="edit.studyline.editmode">
|
||||
<drop-list
|
||||
:items="page.studylines"
|
||||
class="t-slot-droplist"
|
||||
:accepts-type="'studyline-'+page.id"
|
||||
xreorder="$event.apply(page.studylines)"
|
||||
@reorder="reorderLines($event,page.studylines)"
|
||||
mode="copy"
|
||||
row
|
||||
<b-tab
|
||||
v-for="(page,pageindex) in value.pages"
|
||||
:key="page.id"
|
||||
>
|
||||
<template v-slot:item="{item}">
|
||||
<drag
|
||||
:key="item.id"
|
||||
class='t-studyline-drag'
|
||||
:data="item"
|
||||
:type="'studyline-'+page.id"
|
||||
>
|
||||
<template v-slot:drag-image>
|
||||
<i class="fa fa-arrows text-primary"></i>
|
||||
</template>
|
||||
<t-studyline-edit
|
||||
v-model="item"
|
||||
@edit='editLineStart(item)'
|
||||
@delete='deleteLine(page,item)'
|
||||
<template #title>
|
||||
{{page.shortname}}
|
||||
<t-studyplan-page-edit
|
||||
v-if="pageindex == selectedpageindex"
|
||||
v-model="value.pages[pageindex]"
|
||||
:studyplan="value"
|
||||
type="link"
|
||||
></t-studyplan-page-edit>
|
||||
</template>
|
||||
<div class='t-studyplan-content-edit'
|
||||
v-if="edit.studyline.editmode">
|
||||
<drop-list
|
||||
:items="page.studylines"
|
||||
class="t-slot-droplist"
|
||||
:accepts-type="'studyline-'+page.id"
|
||||
xreorder="$event.apply(page.studylines)"
|
||||
@reorder="reorderLines($event,page.studylines)"
|
||||
mode="copy"
|
||||
row
|
||||
>
|
||||
<template v-slot:item="{item}">
|
||||
<drag
|
||||
:key="item.id"
|
||||
class='t-studyline-drag'
|
||||
:data="item"
|
||||
:type="'studyline-'+page.id"
|
||||
>
|
||||
<div v-if="!slotsempty(item.slots)"> {{ text.editmode_modules_hidden}} </div>
|
||||
</t-studyline-edit>
|
||||
</drag>
|
||||
</template>
|
||||
</drop-list>
|
||||
</div>
|
||||
<div class='t-studyplan-content' v-else>
|
||||
|
||||
<!-- Now paint the headings column -->
|
||||
<div class='t-studyplan-headings'>
|
||||
<s-studyline-header-heading :identifier='Number(page.id)'></s-studyline-header-heading>
|
||||
<t-studyline-heading v-for="(line,lineindex) in page.studylines"
|
||||
:key="line.id"
|
||||
@resize="headingresized(lineindex,$event)"
|
||||
v-model="page.studylines[lineindex]"
|
||||
:layers='countLineLayers(line,page)+1'
|
||||
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
||||
+ ((lineindex==0)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
></t-studyline-heading>
|
||||
</div>
|
||||
<!-- Next, paint all the cells in the scrollable -->
|
||||
<div class="t-studyplan-scrollable" >
|
||||
<div class="t-studyplan-timeline" :style="columns_stylerule(page)">
|
||||
<!-- add period information -->
|
||||
<template v-for="(n,index) in (page.periods+1)">
|
||||
<s-studyline-header-period
|
||||
:identifier='Number(page.id)'
|
||||
v-if="index > 0"
|
||||
v-model="page.perioddesc[index-1]"
|
||||
><t-period-edit
|
||||
:ref="'periodeditor-'+index"
|
||||
@edited="periodEdited"
|
||||
v-model="page.perioddesc[index-1]"
|
||||
:minstart="(index > 1) ? add_day(page.perioddesc[index-2].startdate,2) : null"
|
||||
:maxend="(index < page.periods) ? sub_day(page.perioddesc[index].enddate,2) : null"
|
||||
></t-period-edit
|
||||
></s-studyline-header-period>
|
||||
<div class="s-studyline-header-filter"></div>
|
||||
</template>
|
||||
|
||||
<!-- Line by line add the items -->
|
||||
<!-- The grid layout handles putting it in rows and columns -->
|
||||
<template v-for="(line,lineindex) in page.studylines"
|
||||
><template v-for="(layernr,layeridx) in countLineLayers(line,page)+1"
|
||||
><template v-for="(n,index) in (page.periods+1)"
|
||||
>
|
||||
<t-studyline-slot
|
||||
v-if="index > 0 && showslot(page,line, index, layeridx, 'gradable')"
|
||||
type='gradable'
|
||||
v-model="line.slots[index].courses"
|
||||
:key="'c-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:period="page.perioddesc[index-1]"
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((layernr == countLineLayers(line,page))?' lastlyr ':' ')
|
||||
+ ((layernr == countLineLayers(line,page)+1)?' newlyr ':' ')"
|
||||
></t-studyline-slot
|
||||
><t-studyline-slot
|
||||
type='filter'
|
||||
v-if="showslot(page,line, index, layeridx, 'filter')"
|
||||
v-model="line.slots[index].filters"
|
||||
:key="'f-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':'')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((index==page.periods)?' rightmost':'')
|
||||
+ ((layernr == countLineLayers(line,page))?' lastlyr ':' ')
|
||||
+ ((layernr == countLineLayers(line,page)+1)?' newlyr ':' ')"
|
||||
<template v-slot:drag-image>
|
||||
<i class="fa fa-arrows text-primary"></i>
|
||||
</template>
|
||||
<t-studyline-edit
|
||||
v-model="item"
|
||||
@edit='editLineStart(item)'
|
||||
@delete='deleteLine(page,item)'
|
||||
>
|
||||
</t-studyline-slot
|
||||
<div v-if="!slotsempty(item.slots)"> {{ text.editmode_modules_hidden}} </div>
|
||||
</t-studyline-edit>
|
||||
</drag>
|
||||
</template>
|
||||
</drop-list>
|
||||
</div>
|
||||
<div class='t-studyplan-content' v-else>
|
||||
<!-- Now paint the headings column -->
|
||||
<div class='t-studyplan-headings'>
|
||||
<s-studyline-header-heading :identifier='Number(page.id)'></s-studyline-header-heading>
|
||||
<template v-if="page.studylines.length > 0">
|
||||
<t-studyline-heading v-for="(line,lineindex) in page.studylines"
|
||||
:key="line.id"
|
||||
@resize="headingresized(lineindex,$event)"
|
||||
v-model="page.studylines[lineindex]"
|
||||
:layers='countLineLayers(line,page)+1'
|
||||
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
||||
+ ((lineindex==0)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
></t-studyline-heading>
|
||||
</template>
|
||||
<t-studyline-heading v-else
|
||||
@resize="headingresized(0,$event)"
|
||||
|
||||
:layers="1"
|
||||
:class="'odd first last'"
|
||||
></t-studyline-heading>
|
||||
</div>
|
||||
<!-- Next, paint all the cells in the scrollable -->
|
||||
<div class="t-studyplan-scrollable" >
|
||||
<div class="t-studyplan-timeline" :style="columns_stylerule(page)">
|
||||
<!-- add period information -->
|
||||
<template v-for="(n,index) in (page.periods+1)">
|
||||
<s-studyline-header-period
|
||||
:identifier='Number(page.id)'
|
||||
v-if="index > 0"
|
||||
v-model="page.perioddesc[index-1]"
|
||||
><t-period-edit
|
||||
:ref="'periodeditor-'+index"
|
||||
@edited="periodEdited"
|
||||
v-model="page.perioddesc[index-1]"
|
||||
:minstart="(index > 1) ? add_day(page.perioddesc[index-2].startdate,2) : null"
|
||||
:maxend="(index < page.periods) ? sub_day(page.perioddesc[index].enddate,2) : null"
|
||||
></t-period-edit
|
||||
></s-studyline-header-period>
|
||||
<div class="s-studyline-header-filter"></div>
|
||||
</template>
|
||||
|
||||
<!-- Line by line add the items -->
|
||||
<!-- The grid layout handles putting it in rows and columns -->
|
||||
<template v-for="(line,lineindex) in page.studylines"
|
||||
><template v-for="(layernr,layeridx) in countLineLayers(line,page)+1"
|
||||
><template v-for="(n,index) in (page.periods+1)"
|
||||
>
|
||||
<t-studyline-slot
|
||||
v-if="index > 0 && showslot(page,line, index, layeridx, 'gradable')"
|
||||
type='gradable'
|
||||
v-model="line.slots[index].courses"
|
||||
:key="'c-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:period="page.perioddesc[index-1]"
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((layernr == countLineLayers(line,page))?' lastlyr ':' ')
|
||||
+ ((layernr == countLineLayers(line,page)+1)?' newlyr ':' ')"
|
||||
></t-studyline-slot
|
||||
><t-studyline-slot
|
||||
type='filter'
|
||||
v-if="showslot(page,line, index, layeridx, 'filter')"
|
||||
v-model="line.slots[index].filters"
|
||||
:key="'f-'+lineindex+'-'+index+'-'+layernr"
|
||||
:slotindex="index"
|
||||
:line="line"
|
||||
:plan="value"
|
||||
:page="page"
|
||||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':'')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((index==page.periods)?' rightmost':'')
|
||||
+ ((layernr == countLineLayers(line,page))?' lastlyr ':' ')
|
||||
+ ((layernr == countLineLayers(line,page)+1)?' newlyr ':' ')"
|
||||
></t-studyline-slot
|
||||
></template
|
||||
></template
|
||||
></template
|
||||
></template
|
||||
></div>
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="edit.studyline.editmode" class='t-studyline-add'>
|
||||
<a href="#" v-b-modal="'modal-add-studyline-'+page.id" @click="false;"
|
||||
><i class='fa fa-plus'></i>{{ text.studyline_add }}</a>
|
||||
</div>
|
||||
<b-modal
|
||||
:id="'modal-add-studyline-'+page.id"
|
||||
size="lg"
|
||||
:ok-title="text.add$core"
|
||||
ok-variant="primary"
|
||||
:title="text.studyline_add"
|
||||
@ok="addStudyLine(page,create.studyline)"
|
||||
:ok-disabled="Math.min(create.studyline.name.length,create.studyline.shortname.length) == 0"
|
||||
>
|
||||
<b-container>
|
||||
<b-row>
|
||||
<b-col cols="3">{{text.studyline_name}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input v-model="create.studyline.name" :placeholder="text.studyline_name_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{text.studyline_shortname}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input
|
||||
v-model="create.studyline.shortname"
|
||||
:placeholder="text.studyline_shortname_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{text.studyline_color}}</b-col>
|
||||
<b-col>
|
||||
<input type="color" v-model="create.studyline.color" />
|
||||
<!-- hsluv-picker v-model="create.studyline.color" horizontal displaysize="175" ></hsluv-picker -->
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-modal>
|
||||
<b-modal
|
||||
:id="'modal-edit-studyline-'+page.id"
|
||||
size="lg"
|
||||
ok-variant="primary"
|
||||
:title="text.studyline_edit"
|
||||
@ok="editLineFinish()"
|
||||
:ok-disabled="Math.min(edit.studyline.data.name.length,edit.studyline.data.shortname.length) == 0"
|
||||
>
|
||||
<b-container>
|
||||
<b-row>
|
||||
<b-col cols="3">{{ text.studyline_name}}</b-col>
|
||||
<b-col>
|
||||
<div v-if="edit.studyline.editmode" class='t-studyline-add ml-2 mt-1'>
|
||||
<a href="#" v-b-modal="'modal-add-studyline-'+page.id" @click="false;"
|
||||
><i class='fa fa-plus'></i>{{ text.studyline_add }}</a>
|
||||
</div>
|
||||
<b-modal
|
||||
:id="'modal-add-studyline-'+page.id"
|
||||
size="lg"
|
||||
:ok-title="text.add$core"
|
||||
ok-variant="primary"
|
||||
:title="text.studyline_add"
|
||||
@ok="addStudyLine(page,create.studyline)"
|
||||
:ok-disabled="Math.min(create.studyline.name.length,create.studyline.shortname.length) == 0"
|
||||
>
|
||||
<b-container>
|
||||
<b-row>
|
||||
<b-col cols="3">{{text.studyline_name}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input v-model="create.studyline.name" :placeholder="text.studyline_name_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{text.studyline_shortname}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input
|
||||
v-model="edit.studyline.data.name"
|
||||
:placeholder="text.studyline_name_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{ text.studyline_shortname}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input
|
||||
v-model="edit.studyline.data.shortname"
|
||||
:placeholder="text.studyline_shortname_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{ text.studyline_color}}</b-col>
|
||||
<b-col>
|
||||
<input type="color" v-model="edit.studyline.data.color" />
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-modal>
|
||||
</b-tab>
|
||||
</b-tabs>
|
||||
v-model="create.studyline.shortname"
|
||||
:placeholder="text.studyline_shortname_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{text.studyline_color}}</b-col>
|
||||
<b-col>
|
||||
<input type="color" v-model="create.studyline.color" />
|
||||
<!-- hsluv-picker v-model="create.studyline.color" horizontal displaysize="175" ></hsluv-picker -->
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-modal>
|
||||
<b-modal
|
||||
:id="'modal-edit-studyline-'+page.id"
|
||||
size="lg"
|
||||
ok-variant="primary"
|
||||
:title="text.studyline_edit"
|
||||
@ok="editLineFinish()"
|
||||
:ok-disabled="Math.min(edit.studyline.data.name.length,edit.studyline.data.shortname.length) == 0"
|
||||
>
|
||||
<b-container>
|
||||
<b-row>
|
||||
<b-col cols="3">{{ text.studyline_name}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input
|
||||
v-model="edit.studyline.data.name"
|
||||
:placeholder="text.studyline_name_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{ text.studyline_shortname}}</b-col>
|
||||
<b-col>
|
||||
<b-form-input
|
||||
v-model="edit.studyline.data.shortname"
|
||||
:placeholder="text.studyline_shortname_ph"></b-form-input>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row>
|
||||
<b-col cols="3">{{ text.studyline_color}}</b-col>
|
||||
<b-col>
|
||||
<input type="color" v-model="edit.studyline.data.color" />
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-modal>
|
||||
</b-tab>
|
||||
</b-tabs>
|
||||
</b-card>
|
||||
</div>
|
||||
`
|
||||
});
|
||||
|
@ -2118,7 +2153,6 @@ export default {
|
|||
:data-studyline="line.id" ref="main"
|
||||
:style='spanCss'
|
||||
><drag v-if="item"
|
||||
|
||||
:key="item.id"
|
||||
class="t-slot-item"
|
||||
:data="item"
|
||||
|
|
|
@ -240,7 +240,7 @@ class studyplanpage_editform extends formbase {
|
|||
]);
|
||||
}
|
||||
|
||||
/* Return the simple model of the page to make sure we can update stuff.
|
||||
/* Return the editor structure of the new / edited page
|
||||
Parse it through the clean_returnvalue function of exernal api (of which studyplanservice is a subclass)
|
||||
so we return it in a consistent way
|
||||
*/
|
||||
|
|
|
@ -142,6 +142,40 @@ class studyplanpage {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return description with all file references resolved
|
||||
* @return string
|
||||
*/
|
||||
public function description() {
|
||||
$text = file_rewrite_pluginfile_urls(
|
||||
// The content of the text stored in the database.
|
||||
$this->r->description,
|
||||
// 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.
|
||||
\context_system::instance()->id, // System instance is always used for this
|
||||
'local_treestudyplan',
|
||||
'studyplanpage',
|
||||
$this->id
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function timing() {
|
||||
$now = new \DateTime();
|
||||
if ($now > $this->startdate) {
|
||||
if ($this->enddate > 0 && $now > $this->enddate) {
|
||||
return "past";
|
||||
} else {
|
||||
return "present";
|
||||
}
|
||||
} else {
|
||||
return "future";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Webservice structure for basic info
|
||||
* @param int $value Webservice requirement constant
|
||||
|
@ -155,6 +189,7 @@ class studyplanpage {
|
|||
"description" => new \external_value(PARAM_RAW, 'description of studyplan page'),
|
||||
"startdate" => new \external_value(PARAM_TEXT, 'start date of studyplan'),
|
||||
"enddate" => new \external_value(PARAM_TEXT, 'end date of studyplan'),
|
||||
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
|
||||
"perioddesc" => period::page_structure(),
|
||||
], 'Studyplan page basic info', $value);
|
||||
}
|
||||
|
@ -169,9 +204,10 @@ class studyplanpage {
|
|||
'fullname' => $this->r->fullname,
|
||||
'shortname' => $this->r->shortname,
|
||||
'periods' => $this->r->periods,
|
||||
'description' => $this->r->description,
|
||||
'description' => $this->description(),
|
||||
'startdate' => $this->r->startdate,
|
||||
'enddate' => $this->r->enddate,
|
||||
'timing' => $this->timing(),
|
||||
"perioddesc" => period::page_model($this),
|
||||
];
|
||||
}
|
||||
|
@ -189,6 +225,7 @@ class studyplanpage {
|
|||
"periods" => new \external_value(PARAM_INT, 'number of periods in studyplan page'),
|
||||
"startdate" => new \external_value(PARAM_TEXT, 'start date of studyplan page'),
|
||||
"enddate" => new \external_value(PARAM_TEXT, 'end date of studyplan page'),
|
||||
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
|
||||
"studylines" => new \external_multiple_structure(studyline::editor_structure()),
|
||||
"perioddesc" => period::page_structure(),
|
||||
], 'Studyplan page full structure', $value);
|
||||
|
@ -205,10 +242,11 @@ class studyplanpage {
|
|||
'id' => $this->r->id,
|
||||
'fullname' => $this->r->fullname,
|
||||
'shortname' => $this->r->shortname,
|
||||
'description' => $this->r->description,
|
||||
'description' => $this->description(),
|
||||
'periods' => $this->r->periods,
|
||||
'startdate' => $this->r->startdate,
|
||||
'enddate' => $this->r->enddate,
|
||||
'timing' => $this->timing(),
|
||||
'studylines' => [],
|
||||
"perioddesc" => period::page_model($this),
|
||||
];
|
||||
|
@ -313,6 +351,7 @@ class studyplanpage {
|
|||
"periods" => new \external_value(PARAM_INT, 'number of slots in studyplan page'),
|
||||
"startdate" => new \external_value(PARAM_TEXT, 'start date of studyplan page'),
|
||||
"enddate" => new \external_value(PARAM_TEXT, 'end date of studyplan page'),
|
||||
"timing" => new \external_value(PARAM_TEXT, '(past|present|future)'),
|
||||
"studylines" => new \external_multiple_structure(studyline::user_structure()),
|
||||
"perioddesc" => period::page_structure(),
|
||||
], 'Studyplan page with user info', $value);
|
||||
|
@ -329,10 +368,11 @@ class studyplanpage {
|
|||
'id' => $this->r->id,
|
||||
'fullname' => $this->r->fullname,
|
||||
'shortname' => $this->r->shortname,
|
||||
'description' => $this->r->description,
|
||||
'description' => $this->description(),
|
||||
'periods' => $this->r->periods,
|
||||
'startdate' => $this->r->startdate,
|
||||
'enddate' => $this->r->enddate,
|
||||
'timing' => $this->timing(),
|
||||
'studylines' => [],
|
||||
"perioddesc" => period::page_model($this),
|
||||
];
|
||||
|
|
|
@ -114,7 +114,13 @@ $string["refreshteacherlist_name"] = "Refresh teacher's study plan list";
|
|||
$string["studyplan_add"] = 'Add study plan';
|
||||
$string["studyplan_edit"] = 'Edit study plan';
|
||||
$string["studyplan_remove"] = 'Remove study plan';
|
||||
$string["studyplan_confirm_remove"] = 'Are you sure you want to remove study plan {$a}?';
|
||||
$string["studyplan_confirm_remove"] = 'Are you sure you want to remove study plan page {$a}?';
|
||||
$string["studyplanpage"] = 'Study plan page';
|
||||
$string["studyplanpage_add"] = 'Add study plan page';
|
||||
$string["studyplanpage_edit"] = 'Edit study plan page';
|
||||
$string["studyplanpage_remove"] = 'Remove study plan page';
|
||||
$string["studyplanpage_confirm_remove"] = 'Are you sure you want to remove study plan page {$a}?';
|
||||
$string["studyplan_duration"] = 'Duration';
|
||||
$string["studyplan_name"] = 'Full name';
|
||||
$string["studyplan_name_ph"] = '';
|
||||
$string["studyplan_icon"] = "Image for this studyplan";
|
||||
|
|
|
@ -112,6 +112,12 @@ $string["studyplan_add"] = 'Nieuw studieplan';
|
|||
$string["studyplan_edit"] = 'Studieplan bewerken';
|
||||
$string["studyplan_remove"] = 'Studieplan verwijderen';
|
||||
$string["studyplan_confirm_remove"] = 'Weet je zeker dat je studieplan {$a} wilt verwijderen?';
|
||||
$string["studyplanpage"] = 'Studieplan-tabblad';
|
||||
$string["studyplanpage_add"] = 'Nieuw studieplan-tabblad';
|
||||
$string["studyplanpage_edit"] = 'Studieplan-tabblad bewerken';
|
||||
$string["studyplanpage_remove"] = 'Studieplan-tabblad verwijderen';
|
||||
$string["studyplanpage_confirm_remove"] = 'Weet je zeker dat je studieplan-tabblad {$a} wilt verwijderen?';
|
||||
$string["studyplan_duration"] = 'Duur';
|
||||
$string["studyplan_name"] = 'Volledige Naam';
|
||||
$string["studyplan_name_ph"] = '';
|
||||
$string["studyplan_icon"] = "Afbeelding for this studyplan";
|
||||
|
|
35
lib.php
35
lib.php
|
@ -25,6 +25,7 @@
|
|||
|
||||
use local_treestudyplan\local\helpers\webservicehelper;
|
||||
use \local_treestudyplan\studyplan;
|
||||
use local_treestudyplan\studyplanpage;
|
||||
|
||||
/**
|
||||
* Describe editor options
|
||||
|
@ -457,6 +458,40 @@ function local_treestudyplan_pluginfile(
|
|||
return false;
|
||||
}
|
||||
|
||||
} else if (in_array($filearea,["studyplanpage"])) {
|
||||
// The args is an array containing [itemid, path].
|
||||
// Fetch the itemid from the path.
|
||||
$itemid = array_shift($args);
|
||||
|
||||
$page = studyplanpage::find_by_id($itemid);
|
||||
$plan = $page->studyplan();
|
||||
$planctx = $plan->context();
|
||||
|
||||
// Check if the current user has access to this studyplan
|
||||
if ( webservicehelper::has_capabilities($studyplan_filecaps,$planctx) || $plan->has_linked_user($USER)) {
|
||||
// Extract the filename / filepath from the $args array
|
||||
$filename = array_pop($args); // The last item in the $args array.
|
||||
if (empty($args)) {
|
||||
// $args is empty => the path is '/'.
|
||||
$filepath = '/';
|
||||
} else {
|
||||
// $args contains the remaining elements of the filepath.
|
||||
$filepath = '/' . implode('/', $args) . '/';
|
||||
}
|
||||
|
||||
// Retrieve the file from the Files API.
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->get_file(\context_system::instance()->id, 'local_treestudyplan', $filearea, $itemid, $filepath, $filename);
|
||||
if (!$file) {
|
||||
// The file does not exist.
|
||||
return false;
|
||||
}
|
||||
// We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
|
||||
send_stored_file($file, 24*60*60, 0, $forcedownload, $options);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (in_array($filearea,['defaulticon'])) {
|
||||
// The args is an array containing [itemid, path].
|
||||
// Fetch the itemid from the path.
|
||||
|
|
|
@ -1117,5 +1117,4 @@
|
|||
margin-bottom: auto;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user