Reworked resizing a course to shift collisions down a layer instead of blocking

This commit is contained in:
PMKuipers 2024-01-26 23:43:02 +01:00
parent d9bcb71a46
commit 546bff0659
3 changed files with 112 additions and 46 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2186,44 +2186,7 @@ export default {
},
maxSpan(){
// Determine the maximum span for components in this slot
// Used for setting the max in the timing adjustment screen(s)
// And for checking the filter types
// Assume this slot is first one available
let freeIndex = this.slotindex;
// Determine last free slot following this one in the layer
for(let i = this.slotindex + 1; i <= this.page.periods; i++){
if(this.line.slots && this.line.slots[i] && this.line.slots[i].courses){
const clist = this.line.slots[i].courses;
const flist = this.line.slots[i-1].filters; // next filter is in the same slot
let busy = false;
for(const ix in clist) {
if( clist[ix].layer == this.layer) {
busy = true; // slot is busy in this layer.
break;
}
}
for(const ix in flist) {
if( flist[ix].layer == this.layer) {
busy = true; // slot is busy in this layer.
break;
}
}
if(! busy) {
// slot is free in this layer
freeIndex = i;
} else {
break; // stop checking next slots
}
} else {
break; // stop processing
}
}
// calculate span from that
return freeIndex - this.slotindex + 1;
return this.page.periods - this.slotindex + 1;
},
makeType(item){
return {
@ -2303,6 +2266,7 @@ export default {
ref="timingChecker"
:maxspan="maxSpan()"
:page="page"
:line="line"
:period="period"
v-model="value[itemidx]"
></t-item-timing-checker>
@ -2317,7 +2281,10 @@ export default {
type: Object, // t-item model
},
page: {
type: Object, // Studyplan data
type: Object, // Studyplanpage
},
line: {
type: Object, // Studyline
},
period: {
type: Object, // Studyplan data
@ -2348,7 +2315,7 @@ export default {
return false;
}
} else {
debug.warn("Timing thing not proper configured",self.value,self.period,self.maxspan);
debug.warn("Timing thing not properly configured",self.value,self.period,self.maxspan);
return false;
}
},
@ -2366,8 +2333,7 @@ export default {
};
},
methods: {
validate_course_period(force) {
validate_course_period() {
const self = this;
debug.info("Validating course and period");
@ -2394,6 +2360,9 @@ export default {
debug.info("Course timing matches period",self.datechanger);
}
},
has_filter() {
const slots = this.page.slots;
},
change_course_period() {
const self=this;
// Save the state
@ -2413,8 +2382,99 @@ export default {
self.$emit("input",self.value);
});
},
checkFilterSlotBusy(slotindex) {
debug.info("checking filter",this.line.slots, slotindex,this.value.layer);
if (this.line.slots[slotindex]) {
const list = this.line.slots[slotindex].filters;
for(const ix in list) {
if( list[ix].layer == this.value.layer) {
debug.info("Busy:",list[ix]);
return list[ix];
}
}
}
return null;
},
nextFreeFilterLayer(slotindex) {
const layer = this.value.layer;
const list = this.line.slots[slotindex].filters;
const usedLayers = [];
for(const ix in list) {
usedLayers.push(list[ix].layer);
}
let nextlyr = layer+1;
while (usedLayers.includes(nextlyr)) {
nextlyr++;
}
return nextlyr;
},
checkCourseSlotBusy(slotindex) {
debug.info("checking ",this.line.slots, slotindex,this.value.layer);
if (this.line.slots[slotindex]) {
const list = this.line.slots[slotindex].courses;
for(const ix in list) {
if( list[ix].layer == this.value.layer) {
debug.info("Busy:",list[ix]);
return list[ix];
}
}
}
return null;
},
nextFreeCourseLayer(slotindex) {
const layer = this.value.layer;
const list = this.line.slots[slotindex].courses;
const usedLayers = [];
for(const ix in list) {
usedLayers.push(list[ix].layer);
}
let nextlyr = layer+1;
while (usedLayers.includes(nextlyr)) {
nextlyr++;
}
return nextlyr;
},
shift_collisions(span) {
// Check all periods for collision
const shiftfilters = [];
const shiftcourses = [];
const items = [];
for(let i = this.value.slot; i < this.value.slot + span; i++) {
const busyFilter = this.checkFilterSlotBusy(i);
if (busyFilter) {
const nextlyr = this.nextFreeFilterLayer(i);
items.push({
id: busyFilter.id,
layer: nextlyr,
line_id: this.line.id,
slot: busyFilter.slot,
});
busyFilter.layer = nextlyr;
}
const busyCourse = this.checkCourseSlotBusy(i);
if (busyCourse && busyCourse.id != this.value.id) {
const nextlyr = this.nextFreeCourseLayer(i);
items.push({
id: busyCourse.id,
layer: nextlyr,
line_id: this.line.id,
slot: busyCourse.slot,
});
busyCourse.layer = nextlyr;
}
}
if (items.length > 0){
call([{
methodname: 'local_treestudyplan_reorder_studyitems',
args: { items: items }
}])[0].catch(notification.exception).done((response) => {
});
}
},
change_span(span) {
const self=this;
this.shift_collisions(span);
return call([{
methodname: 'local_treestudyplan_set_studyitem_span',
args: { id: self.value.id,
@ -2463,13 +2523,13 @@ export default {
</span>
<span class="ml-1" v-b-tooltip.hover.bottomleft :title="text.periodspan_desc"
>{{ text.periodspan
}}&nbsp;<b-form-select
}}&nbsp;<b-form-select v-if="maxspan > 1"
class=""
size="sm" @change="change_span" v-model="value.span">
<b-form-select-option v-for="(n,i) in maxspan" :value='n' :key='i'
>{{ n }}</b-form-select-option>
</b-form-select
>&nbsp;{{
><span v-else>{{value.span}}</span>&nbsp;{{
(value.span == 1)?text.period.toLowerCase():text.periods.toLowerCase()
}}<i
class="fa fa-question-circle text-black-50"
@ -2895,6 +2955,7 @@ export default {
@deleterq="deleteItem"
v-model="value"
:plan='plan'
:line='line'
:page='page'
:period='period'
:maxspan='maxspan'
@ -3033,6 +3094,10 @@ export default {
type: Object,
default(){ return null;},
},
line:{
type: Object,
default(){ return null;},
},
page: {
type: Object, // PAge data
default() { return null;}
@ -3199,6 +3264,7 @@ export default {
class="mt-1"
:maxspan="maxspan"
:page="page"
:line="line"
:period="period"
v-model="value"
></t-item-timing-checker>