Replaced studentpicker sidebar by dropdown with arrows
This commit is contained in:
parent
fd1ab079a1
commit
2967f4a5bb
2
amd/build/page-view-plan.min.js
vendored
2
amd/build/page-view-plan.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/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
File diff suppressed because one or more lines are too long
2
amd/build/treestudyplan-components.min.js
vendored
2
amd/build/treestudyplan-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
|
@ -181,20 +181,21 @@ export function init(contextid,categoryid) {
|
|||
showStudentView(student){
|
||||
app.selectedstudent = student;
|
||||
app.studentstudyplan = null;
|
||||
app.loadingstudyplan = true;
|
||||
call([{
|
||||
methodname: 'local_treestudyplan_get_user_studyplan',
|
||||
args: { userid: student.id, studyplanid: app.activestudyplan.id}
|
||||
}])[0].then(function(response){
|
||||
app.studentstudyplan = ProcessStudyplan(response,false);
|
||||
app.displayedstudyplan = app.studentstudyplan;
|
||||
app.loadingstudyplan = false;
|
||||
window.location.hash = app.activestudyplan.id + "-" + student.id;
|
||||
}).catch(function(error){
|
||||
notification.exception(error);
|
||||
app.loadingstudyplan = false;
|
||||
});
|
||||
|
||||
if (student) {
|
||||
app.loadingstudyplan = true;
|
||||
call([{
|
||||
methodname: 'local_treestudyplan_get_user_studyplan',
|
||||
args: { userid: student.id, studyplanid: app.activestudyplan.id}
|
||||
}])[0].then(function(response){
|
||||
app.studentstudyplan = ProcessStudyplan(response,false);
|
||||
app.displayedstudyplan = app.studentstudyplan;
|
||||
app.loadingstudyplan = false;
|
||||
window.location.hash = app.activestudyplan.id + "-" + student.id;
|
||||
}).catch(function(error){
|
||||
notification.exception(error);
|
||||
app.loadingstudyplan = false;
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
showOverview(){
|
||||
|
|
|
@ -480,9 +480,7 @@ export default {
|
|||
let firststart = null;
|
||||
for(const ix in this.value.pages) {
|
||||
const page = this.value.pages[ix];
|
||||
debug.info(`Checking page ${ix} - timing ${studyplanPageTiming(page)}`,page);
|
||||
if(studyplanPageTiming(page) == "present") {
|
||||
debug.info(`Found page nr ${ix} to be present`);
|
||||
const s = new Date(page.startdate);
|
||||
if( (!firststart) || firststart > s) {
|
||||
startpageindex = ix;
|
||||
|
@ -512,7 +510,7 @@ export default {
|
|||
let maxLayer = -1;
|
||||
for(let i = 0; i <= page.periods; i++){
|
||||
const slot = line.slots[i];
|
||||
// Determine the amount of used layers in a studyline slit
|
||||
// Determine the amount of used layers in a studyline slot
|
||||
for(const ix in line.slots[i].courses){
|
||||
const item = line.slots[i].courses[ix];
|
||||
if(item.layer > maxLayer){
|
||||
|
@ -526,6 +524,7 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
debug.info(`Counted ${maxLayer+1} layers for ${page.shortname}/${line.name}`);
|
||||
return (maxLayer >= 0)?(maxLayer+1):1;
|
||||
},
|
||||
showslot(page,line,index, layeridx, type){
|
||||
|
@ -630,7 +629,7 @@ export default {
|
|||
<r-studyline-heading v-for="(line,lineindex) in page.studylines"
|
||||
:key="line.id"
|
||||
v-model="page.studylines[lineindex]"
|
||||
:layers='countLineLayers(page,line)+1'
|
||||
:layers='countLineLayers(line,page)+1'
|
||||
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
||||
+ ((lineindex==0)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
|
@ -652,7 +651,7 @@ export default {
|
|||
<!-- 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="(layernr,layeridx) in countLineLayers(line,page)"
|
||||
><template v-for="(n,index) in (page.periods+1)"
|
||||
><r-studyline-slot
|
||||
v-if="index > 0 && showslot(page,line, index, layeridx, 'gradable')"
|
||||
|
@ -669,7 +668,8 @@ export default {
|
|||
:layer="layeridx"
|
||||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':' ')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((layernr == countLineLayers(line,page))?' lastlyr ':' ')"
|
||||
></r-studyline-slot
|
||||
><r-studyline-slot
|
||||
v-if="showslot(page,line, index, layeridx, 'filter')"
|
||||
|
@ -685,7 +685,8 @@ export default {
|
|||
:class="'t-studyline ' + ((lineindex%2==0)?' odd ':' even ')
|
||||
+ ((lineindex==0 && layernr==1)?' first ':'')
|
||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')
|
||||
+ ((index==page.periods)?' rightmost':'')"
|
||||
+ ((index==page.periods)?' rightmost':'')
|
||||
+ ((layernr == countLineLayers(line,page))?' lastlyr ':' ')"
|
||||
>
|
||||
</r-studyline-slot
|
||||
></template
|
||||
|
|
|
@ -1332,7 +1332,7 @@ export default {
|
|||
for(let i = 0; i <= page.periods; i++){
|
||||
if(line.slots[i]){
|
||||
const slot = line.slots[i];
|
||||
// Determine the amount of used layers in a studyline slit
|
||||
// Determine the amount of used layers in a studyline slot
|
||||
for(const ix in line.slots[i].courses){
|
||||
const item = line.slots[i].courses[ix];
|
||||
if(item.layer > maxLayer){
|
||||
|
|
|
@ -24,6 +24,12 @@ export default {
|
|||
},
|
||||
extrafields: {
|
||||
show: "show@core"
|
||||
},
|
||||
prevnext: {
|
||||
prev: "prev@core",
|
||||
previous: "previous@core",
|
||||
next: "next@core",
|
||||
select: "selectanoptions@core",
|
||||
}
|
||||
});
|
||||
// Create new eventbus for interaction between item components
|
||||
|
@ -400,5 +406,155 @@ export default {
|
|||
`,
|
||||
});
|
||||
|
||||
Vue.component('s-prevnext-selector', {
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default() { return null;}
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
},
|
||||
grouped: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
titlefield: {
|
||||
type: String,
|
||||
default: "title",
|
||||
},
|
||||
labelfield: {
|
||||
type: String,
|
||||
default: "label",
|
||||
},
|
||||
optionsfield: {
|
||||
type: String,
|
||||
default: "options",
|
||||
},
|
||||
defaultselectable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
arrows: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
text: strings.prevnext,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
const f = [];
|
||||
if(this.defaultselectable) {
|
||||
f.push(null);
|
||||
}
|
||||
if (this.grouped) {
|
||||
for ( const gix in this.options) {
|
||||
const group = this.options[gix];
|
||||
for ( const ix in group) {
|
||||
const v = this.options[ix];
|
||||
f.push(v);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( const ix in this.options) {
|
||||
const v = this.options[ix];
|
||||
f.push(v);
|
||||
}
|
||||
}
|
||||
return f;
|
||||
},
|
||||
bubblevalue: {
|
||||
get() { return (this.value)?this.value:null;},
|
||||
set(v) { this.$emit('input',(v)?v:null);},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
atFirst() {
|
||||
if (this.fields.length > 0) {
|
||||
return this.fields[0] == this.value;
|
||||
}
|
||||
return true; // Since it disables the button, do so if pressing it would make no sense.
|
||||
},
|
||||
atLast() {
|
||||
if (this.fields.length > 0) {
|
||||
const l = this.fields.length -1;
|
||||
return this.fields[l] == this.value;
|
||||
}
|
||||
return true; // Since it disables the button, do so if pressing it would make no sense.
|
||||
},
|
||||
prev() {
|
||||
if (this.fields.length > 0) {
|
||||
const index = this.fields.indexOf(this.value);
|
||||
if (index > 0) {
|
||||
this.$emit("input",this.fields[index -1]);
|
||||
this.$emit("change",this.fields[index -1]);
|
||||
}
|
||||
}
|
||||
},
|
||||
next() {
|
||||
if (this.fields.length > 0) {
|
||||
const index = this.fields.indexOf(this.value);
|
||||
const l = this.fields.length -1;
|
||||
if (index >= 0 && index < l) {
|
||||
this.$emit("input",this.fields[index + 1]);
|
||||
this.$emit("change",this.fields[index + 1]);
|
||||
}
|
||||
}
|
||||
},
|
||||
selectedchanged(value) {
|
||||
this.$emit("change",value);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div :class="'s-prevnext-selector '">
|
||||
<b-button :variant='variant' @click="prev" :disabled="atFirst()"
|
||||
><i v-if='arrows' class='fa fa-caret-left s-prevnext-arrow'></i
|
||||
><template v-else>{{text.prev}}</template></b-button>
|
||||
<b-form-select v-model="bubblevalue"
|
||||
@change='selectedchanged'
|
||||
>
|
||||
<b-form-select-option
|
||||
:disabled="!defaultselectable"
|
||||
:value="null"
|
||||
:class="(defaultselectable)?'font-italic text-primary ':'font-italic'"
|
||||
><slot name="defaultlabel">{{text.select}}</slot></b-form-select-option>
|
||||
</b-form-select-option-group>
|
||||
<template v-if="grouped">
|
||||
<b-form-select-option-group
|
||||
v-for="(g,gi) in this.options"
|
||||
:key="gi"
|
||||
:label="g[grouptitlefield]"
|
||||
>
|
||||
<b-form-select-option
|
||||
v-for="(o,i) in g[grouplistfield]"
|
||||
:key="i"
|
||||
:value="o"
|
||||
><slot :value="o">{{o[titlefield]}}</slot></b-form-select-option>
|
||||
</b-form-select-option-group>
|
||||
</template>
|
||||
<template v-else>
|
||||
<b-form-select-option
|
||||
v-for="(o,i) in this.options"
|
||||
:key="i"
|
||||
:value="o"
|
||||
><slot :value="o">{{o[titlefield]}}</slot></b-form-select-option>
|
||||
</template>
|
||||
</b-form-select>
|
||||
<b-button :variant='variant' @click="next" :disabled="atLast()"
|
||||
><i v-if='arrows' class='fa fa-caret-right s-prevnext-arrow'></i
|
||||
><template v-else>{{text.next}}</template></b-button>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
};
|
|
@ -787,12 +787,12 @@
|
|||
.path-local-treestudyplan .t-studyline-heading.last,
|
||||
.path-local-treestudyplan .t-studyline-slot.last.newlyr,
|
||||
.path-local-treestudyplan .r-studyline-heading.last,
|
||||
.path-local-treestudyplan .r-studyline-slot.last,
|
||||
.path-local-treestudyplan .r-studyline-slot.last.lastlyr,
|
||||
.features-treestudyplan .t-studyline-drag:last-child,
|
||||
.features-treestudyplan .t-studyline-heading.last,
|
||||
.features-treestudyplan .t-studyline-slot.last.newlyr,
|
||||
.features-treestudyplan .r-studyline-heading.last,
|
||||
.features-treestudyplan .r-studyline-slot.last {
|
||||
.features-treestudyplan .r-studyline-slot.last.lastlyr {
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
.path-local-treestudyplan .s-studyline-header-period,
|
||||
|
@ -1367,6 +1367,15 @@
|
|||
.features-treestudyplan div.r-item-course-header-details:last-child {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
.path-local-treestudyplan .s-prevnext-selector,
|
||||
.features-treestudyplan .s-prevnext-selector {
|
||||
display: inline-block;
|
||||
}
|
||||
.path-local-treestudyplan .s-prevnext-selector i.s-prevnext-arrow,
|
||||
.features-treestudyplan .s-prevnext-selector i.s-prevnext-arrow {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.path-local-treestudyplan .card.s-studyplan-card,
|
||||
.features-treestudyplan .card.s-studyplan-card {
|
||||
|
|
|
@ -671,7 +671,7 @@
|
|||
.t-studyline-heading.last,
|
||||
.t-studyline-slot.last.newlyr,
|
||||
.r-studyline-heading.last,
|
||||
.r-studyline-slot.last {
|
||||
.r-studyline-slot.last.lastlyr {
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
|
@ -1180,4 +1180,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.s-prevnext-selector {
|
||||
display: inline-block;
|
||||
|
||||
i.s-prevnext-arrow {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
13
styles.css
13
styles.css
|
@ -787,12 +787,12 @@
|
|||
.path-local-treestudyplan .t-studyline-heading.last,
|
||||
.path-local-treestudyplan .t-studyline-slot.last.newlyr,
|
||||
.path-local-treestudyplan .r-studyline-heading.last,
|
||||
.path-local-treestudyplan .r-studyline-slot.last,
|
||||
.path-local-treestudyplan .r-studyline-slot.last.lastlyr,
|
||||
.features-treestudyplan .t-studyline-drag:last-child,
|
||||
.features-treestudyplan .t-studyline-heading.last,
|
||||
.features-treestudyplan .t-studyline-slot.last.newlyr,
|
||||
.features-treestudyplan .r-studyline-heading.last,
|
||||
.features-treestudyplan .r-studyline-slot.last {
|
||||
.features-treestudyplan .r-studyline-slot.last.lastlyr {
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
.path-local-treestudyplan .s-studyline-header-period,
|
||||
|
@ -1367,6 +1367,15 @@
|
|||
.features-treestudyplan div.r-item-course-header-details:last-child {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
.path-local-treestudyplan .s-prevnext-selector,
|
||||
.features-treestudyplan .s-prevnext-selector {
|
||||
display: inline-block;
|
||||
}
|
||||
.path-local-treestudyplan .s-prevnext-selector i.s-prevnext-arrow,
|
||||
.features-treestudyplan .s-prevnext-selector i.s-prevnext-arrow {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
}
|
||||
|
||||
.path-local-treestudyplan .card.s-studyplan-card,
|
||||
.features-treestudyplan .card.s-studyplan-card {
|
||||
|
|
|
@ -134,8 +134,24 @@ print $OUTPUT->header();
|
|||
v-model="displayedstudyplan"
|
||||
v-if="displayedstudyplan && displayedstudyplan.description"
|
||||
></s-studyplan-details>
|
||||
<b-button class="ml-1" v-if="activestudyplan" variant='primary' v-b-toggle.toolbox-sidebar
|
||||
><?php t('selectstudent_btn') ?></b-button>
|
||||
<div class="flex-grow-1"><!-- Spacer to align student selector right --></div>
|
||||
<div v-if="displayedstudyplan && displayedstudyplan.description">
|
||||
<span><?php t('selectstudent_btn') ?></span>
|
||||
<s-prevnext-selector
|
||||
|
||||
:options="associatedstudents"
|
||||
title="firstname"
|
||||
v-model="selectedstudent"
|
||||
defaultselectable
|
||||
arrows
|
||||
@change="showStudentView"
|
||||
class="ml-2"
|
||||
variant="primary"
|
||||
>
|
||||
<template v-slot="{value}">{{value.firstname}} {{value.lastname}}</template>
|
||||
<template #defaultlabel><span class='text-primary'><?php t("showoverview"); ?></span></template>
|
||||
</s-prevnext-selector>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class='t-studyplan-container'>
|
||||
|
@ -161,30 +177,6 @@ print $OUTPUT->header();
|
|||
</b-card-group>
|
||||
</div>
|
||||
</div>
|
||||
<b-sidebar
|
||||
id="toolbox-sidebar"
|
||||
right
|
||||
shadow
|
||||
title='<?php t("selectstudent")?>'
|
||||
>
|
||||
<div class='m-2'><?php t("selectstudent_details")?></div>
|
||||
<b-list-group v-if="associatedstudents">
|
||||
<b-list-group-item :active="! selectedstudent"
|
||||
button
|
||||
variant="primary"
|
||||
@click='showOverview()'
|
||||
>
|
||||
<?php t("showoverview"); ?>
|
||||
</b-list-group-item>
|
||||
<b-list-group-item v-for="student in associatedstudents" :key="student.id"
|
||||
:active="selectedstudent && student.id == selectedstudent.id"
|
||||
button
|
||||
@click='showStudentView(student)'
|
||||
>
|
||||
{{student.firstname}} {{student.lastname}}
|
||||
</b-list-group-item>
|
||||
</b-list-group>
|
||||
</b-sidebar>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
|
Loading…
Reference in New Issue
Block a user