Reordering

This commit is contained in:
PMKuipers 2023-07-07 21:45:09 +02:00
parent 5a37073a65
commit 48e4203761

View file

@ -192,406 +192,6 @@ export default {
}); });
/*
* T-STUDYPLAN
*/
Vue.component('t-studyplan', {
props: ['value', 'index'],
data() {
return {
config: {
userfields: [
{ key: "selected",},
{ key: "firstname", "sortable": true,},
{ key: "lastname", "sortable": true,},
],
cohortfields:[
{ key: "selected",},
{ key: "name", "sortable": true,},
{ key: "context", "sortable": true,},
]
},
create: {
studyline: {
'name': '',
'shortname': '',
'color': '#DDDDDD',
},
},
edit: {
studyline: {
editmode: false,
data: {
name: '',
shortname: '',
color: '#DDDDDD',
},
original: {},
},
studyplan: {
data: {
name: '',
shortname: '',
description: '',
slots : 4,
startdate: '2020-08-01',
enddate: '',
aggregation: '',
aggregation_config: '',
aggregation_info: {
useRequiredGrades: true,
useItemCondition: false,
},
},
original: {},
}
},
text: strings.studyplan_text,
};
},
created() {
},
mounted() {
if(this.value.studylines.length == 0){
// start in editmode if studylines are empty
this.edit.studyline.editmode = true;
}
this.$root.$emit('redrawLines');
},
updated() {
console.info("UPDATED Studyplan");
this.$root.$emit('redrawLines');
ItemEventBus.$emit('redrawLines');
},
computed: {
},
methods: {
slotsempty(slots) {
if(Array.isArray(slots)){
let count = 0;
for(let i = 0; i < slots.length; i++) {
if(Array.isArray(slots[i].competencies)){
count += slots[i].competencies.length;
}
if(Array.isArray(slots[i].filters)){
count += slots[i].filters.length;
}
}
return (count == 0);
} else {
return false;
}
},
movedStudyplan(plan,from,to) {
this.$emit('moved',plan,from,to); // Throw the event up....
},
addStudyLine(studyplan,newlineinfo) {
call([{
methodname: 'local_treestudyplan_add_studyline',
args: {
'studyplan_id': studyplan.id,
'name': newlineinfo.name,
'shortname': newlineinfo.shortname,
'color': newlineinfo.color,
'sequence': studyplan.studylines.length,
}
}])[0].done(function(response){
debug.info("New studyline:",response);
studyplan.studylines.push(response);
newlineinfo.name = '';
newlineinfo.shortname = '';
newlineinfo.color = "#dddddd";
}).fail(notification.exception);
},
editLineStart(line) {
Object.assign(this.edit.studyline.data,line);
this.edit.studyline.original = line;
this.$bvModal.show('modal-edit-studyline-'+this.value.id);
},
editLineFinish() {
let editedline = this.edit.studyline.data;
let originalline = this.edit.studyline.original;
debug.info('Edit Line',this.edit.studyline);
call([{
methodname: 'local_treestudyplan_edit_studyline',
args: { 'id': editedline.id,
'name': editedline.name,
'shortname': editedline.shortname,
'color': editedline.color,}
}])[0].done(function(response){
debug.info('Edit response:', response);
originalline['name'] = response['name'];
originalline['shortname'] = response['shortname'];
originalline['color'] = response['color'];
}).fail(notification.exception);
},
deleteLine(studyplan,line) {
debug.info('Delete Line',line);
const self=this;
get_strings([
{key: 'studyline_confirm_remove', param: line.name, component: 'local_treestudyplan' },
{key: 'delete', component: 'core' },
]).then(function(s){
self.$bvModal.msgBoxConfirm(s[0], {
okTitle: s[1],
okVariant: 'danger',
}).then(function(modalresponse){
if(modalresponse){
call([{
methodname: 'local_treestudyplan_delete_studyline',
args: { 'id': line.id, }
}])[0].done(function(response){
debug.info('Delete response:', response);
if(response.success == true){
let index = studyplan.studylines.indexOf(line);
studyplan.studylines.splice(index, 1);
}
}).fail(notification.exception);
}
});
});
},
reorderLines(event,lines){
debug.info("Reorder lines",event,lines);
// apply reordering
event.apply(lines);
// send the new sequence to the server
let sequence = [];
for(let idx in lines)
{
sequence.push({'id': lines[idx].id,'sequence': idx});
}
call([{
methodname: 'local_treestudyplan_reorder_studylines',
args: { 'sequence': sequence }
}])[0].done(function(response){
debug.info('Reorder response:', response);
}).fail(notification.exception);
},
deletePlan(studyplan){
const self=this;
debug.info('Delete studyplan:', studyplan);
get_strings([
{key: 'studyplan_confirm_remove', param: studyplan.name, component: 'local_treestudyplan' },
{key: 'delete', component: 'core' },
]).then(function(s){
self.$bvModal.msgBoxConfirm(s[0], {
okTitle: s[1],
okVariant: 'danger',
}).then(function(modalresponse){
if(modalresponse){
call([{
methodname: 'local_treestudyplan_delete_studyplan',
args: { 'id': studyplan.id, }
}])[0].done(function(response){
debug.info('Delete response:', response);
if(response.success == true){
self.$root.$emit("studyplanRemoved",studyplan);
}
}).fail(notification.exception);
}
});
});
},
deleteStudyItem(event){
debug.info('Delete studyitem:', event);
//const self = this;
let item = event.data;
call([{
methodname: 'local_treestudyplan_delete_studyitem',
args: { 'id': item.id, }
}])[0].done(function(response){
debug.info('Delete response:', response);
if(response.success == true){
event.source.$emit('cut',event);
}
}).fail(notification.exception);
},
}
,
template:
`
<div>
<div class='controlbox t-studyplan-controlbox'>
<b-form-checkbox v-model="edit.studyline.editmode" class="sw-studyline-editmode" switch
>{{ text.studyline_editmode }}</b-form-checkbox>
<drop
mode='copy'
class='t-item-deletebox text-danger border-danger'
@drop='deleteStudyItem'
:accepts-type="['gradable-item','filter-item']"
><i class='fa fa-trash'></i>
</drop>
<span class='control deletable'>
<a v-if='value.studylines.length == 0' href='#' @click='deletePlan(value)'
><i class='text-danger fa fa-trash'></i></a>
</span>
<span class='control editable'>
<t-studyplan-edit v-model="value" @moved="movedStudyplan"
><i class='fa fa-pencil'></i> {{text.edit$core}}</t-studyplan-edit>
</span>
<span class='control editable'>
<t-studyplan-associate
v-model="value"><i class='fa fa-users'></i> {{text.associations}}</t-studyplan-associate>
</span>
<span class='control editable'>
<t-studyplan-advanced v-model="value"></t-studyplan-advanced>
</span>
</div>
<div class='t-studyplan-content'>
<drop-list v-if="edit.studyline.editmode"
:items="value.studylines"
class="t-slot-droplist"
:accepts-type="'studyline-'+value.id"
xreorder="$event.apply(value.studylines)"
@reorder="reorderLines($event,value.studylines)"
mode="copy"
row
>
<template v-slot:item="{item}">
<drag
:key="item.id"
class='t-studyplan-drag'
:data="item"
:type="'studyline-'+value.id"
>
<template v-slot:drag-image>
<i class="fa fa-arrows text-primary"></i>
</template>
<t-studyline
:color='item.color'
:name='item.name'
:code='item.shortname'
:editable='true'
:deletable='slotsempty(item.slots)'
:sequence='item.sequence'
:numlines='value.studylines.length'
@edit='editLineStart(item)'
@delete='deleteLine(value,item)'
>
<template v-slot:movebox><i class='fa fa-arrows text-primary'></i></template>
<div v-if="!slotsempty(item.slots)"> {{ text.editmode_modules_hidden}} </div>
</t-studyline>
</drag>
</template>
</drop-list>
<template v-else>
<t-studyline v-for="(item,lineindex) in value.studylines"
:key="item.id"
:color='item.color'
:name='item.name'
:code='item.shortname'
:sequence='lineindex'
:numlines='value.studylines.length'
@edit='editLineStart(item)'
>
<template v-for="(n,index) in (value.slots+1)">
<t-studyline-slot
v-if="index > 0"
type='gradable'
v-model="item.slots[index].competencies"
:key="'c-'+index"
:slotindex="index"
:lineid="item.id"
:plan="value">
</t-studyline-slot>
<t-studyline-slot
type='filter'
v-model="item.slots[index].filters"
:key="'f-'+index"
:slotindex="index"
:lineid="item.id"
:plan="value"
>
</t-studyline-slot>
</template>
</t-studyline>
</template>
<div :id="'studyplan-linewrapper-'+value.id" class='l-leaderline-linewrapper'></div>
</div>
<div v-if="edit.studyline.editmode" class='t-studyline-add'>
<a href="#" v-b-modal="'modal-add-studyline-'+value.id" @click="false;"
><i class='fa fa-plus'></i>{{ text.studyline_add }}</a>
</div>
<b-modal
:id="'modal-add-studyline-'+value.id"
size="lg"
:ok-title="text.add$core"
ok-variant="primary"
:title="text.studyline_add"
@ok="addStudyLine(value,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-'+value.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" />
<!--hsluv-picker
v-model="edit.studyline.data.color"
horizontal displaysize="175" ></hsluv-picker -->
</b-col>
</b-row>
</b-container>
</b-modal>
</div>
`
});
/* /*
* T-STUDYPLAN-ADVANCED * T-STUDYPLAN-ADVANCED
*/ */
@ -841,6 +441,7 @@ export default {
` `
}); });
/* /*
* T-STUDYPLAN-EDIT * T-STUDYPLAN-EDIT
*/ */
@ -1444,7 +1045,433 @@ export default {
}); });
/* /*
* T-STUDYLINE * T-STUDYPLAN
*/
Vue.component('t-studyplan', {
props: ['value', 'index'],
data() {
return {
config: {
userfields: [
{ key: "selected",},
{ key: "firstname", "sortable": true,},
{ key: "lastname", "sortable": true,},
],
cohortfields:[
{ key: "selected",},
{ key: "name", "sortable": true,},
{ key: "context", "sortable": true,},
]
},
create: {
studyline: {
'name': '',
'shortname': '',
'color': '#DDDDDD',
},
},
edit: {
studyline: {
editmode: false,
data: {
name: '',
shortname: '',
color: '#DDDDDD',
},
original: {},
},
studyplan: {
data: {
name: '',
shortname: '',
description: '',
slots : 4,
startdate: '2020-08-01',
enddate: '',
aggregation: '',
aggregation_config: '',
aggregation_info: {
useRequiredGrades: true,
useItemCondition: false,
},
},
original: {},
}
},
text: strings.studyplan_text,
};
},
created() {
},
mounted() {
if(this.value.studylines.length == 0){
// start in editmode if studylines are empty
this.edit.studyline.editmode = true;
}
this.$root.$emit('redrawLines');
},
updated() {
console.info("UPDATED Studyplan");
this.$root.$emit('redrawLines');
ItemEventBus.$emit('redrawLines');
},
computed: {
},
methods: {
slotsempty(slots) {
if(Array.isArray(slots)){
let count = 0;
for(let i = 0; i < slots.length; i++) {
if(Array.isArray(slots[i].competencies)){
count += slots[i].competencies.length;
}
if(Array.isArray(slots[i].filters)){
count += slots[i].filters.length;
}
}
return (count == 0);
} else {
return false;
}
},
movedStudyplan(plan,from,to) {
this.$emit('moved',plan,from,to); // Throw the event up....
},
addStudyLine(studyplan,newlineinfo) {
call([{
methodname: 'local_treestudyplan_add_studyline',
args: {
'studyplan_id': studyplan.id,
'name': newlineinfo.name,
'shortname': newlineinfo.shortname,
'color': newlineinfo.color,
'sequence': studyplan.studylines.length,
}
}])[0].done(function(response){
debug.info("New studyline:",response);
studyplan.studylines.push(response);
newlineinfo.name = '';
newlineinfo.shortname = '';
newlineinfo.color = "#dddddd";
}).fail(notification.exception);
},
editLineStart(line) {
Object.assign(this.edit.studyline.data,line);
this.edit.studyline.original = line;
this.$bvModal.show('modal-edit-studyline-'+this.value.id);
},
editLineFinish() {
let editedline = this.edit.studyline.data;
let originalline = this.edit.studyline.original;
debug.info('Edit Line',this.edit.studyline);
call([{
methodname: 'local_treestudyplan_edit_studyline',
args: { 'id': editedline.id,
'name': editedline.name,
'shortname': editedline.shortname,
'color': editedline.color,}
}])[0].done(function(response){
debug.info('Edit response:', response);
originalline['name'] = response['name'];
originalline['shortname'] = response['shortname'];
originalline['color'] = response['color'];
}).fail(notification.exception);
},
deleteLine(studyplan,line) {
debug.info('Delete Line',line);
const self=this;
get_strings([
{key: 'studyline_confirm_remove', param: line.name, component: 'local_treestudyplan' },
{key: 'delete', component: 'core' },
]).then(function(s){
self.$bvModal.msgBoxConfirm(s[0], {
okTitle: s[1],
okVariant: 'danger',
}).then(function(modalresponse){
if(modalresponse){
call([{
methodname: 'local_treestudyplan_delete_studyline',
args: { 'id': line.id, }
}])[0].done(function(response){
debug.info('Delete response:', response);
if(response.success == true){
let index = studyplan.studylines.indexOf(line);
studyplan.studylines.splice(index, 1);
}
}).fail(notification.exception);
}
});
});
},
reorderLines(event,lines){
debug.info("Reorder lines",event,lines);
// apply reordering
event.apply(lines);
// send the new sequence to the server
let sequence = [];
for(let idx in lines)
{
sequence.push({'id': lines[idx].id,'sequence': idx});
}
call([{
methodname: 'local_treestudyplan_reorder_studylines',
args: { 'sequence': sequence }
}])[0].done(function(response){
debug.info('Reorder response:', response);
}).fail(notification.exception);
},
deletePlan(studyplan){
const self=this;
debug.info('Delete studyplan:', studyplan);
get_strings([
{key: 'studyplan_confirm_remove', param: studyplan.name, component: 'local_treestudyplan' },
{key: 'delete', component: 'core' },
]).then(function(s){
self.$bvModal.msgBoxConfirm(s[0], {
okTitle: s[1],
okVariant: 'danger',
}).then(function(modalresponse){
if(modalresponse){
call([{
methodname: 'local_treestudyplan_delete_studyplan',
args: { 'id': studyplan.id, }
}])[0].done(function(response){
debug.info('Delete response:', response);
if(response.success == true){
self.$root.$emit("studyplanRemoved",studyplan);
}
}).fail(notification.exception);
}
});
});
},
deleteStudyItem(event){
debug.info('Delete studyitem:', event);
//const self = this;
let item = event.data;
call([{
methodname: 'local_treestudyplan_delete_studyitem',
args: { 'id': item.id, }
}])[0].done(function(response){
debug.info('Delete response:', response);
if(response.success == true){
event.source.$emit('cut',event);
}
}).fail(notification.exception);
},
}
,
template:
`
<div>
<div class='controlbox t-studyplan-controlbox'>
<b-form-checkbox v-model="edit.studyline.editmode" class="sw-studyline-editmode" switch
>{{ text.studyline_editmode }}</b-form-checkbox>
<drop
mode='copy'
class='t-item-deletebox text-danger border-danger'
@drop='deleteStudyItem'
:accepts-type="['gradable-item','filter-item']"
><i class='fa fa-trash'></i>
</drop>
<span class='control deletable'>
<a v-if='value.studylines.length == 0' href='#' @click='deletePlan(value)'
><i class='text-danger fa fa-trash'></i></a>
</span>
<span class='control editable'>
<t-studyplan-edit v-model="value" @moved="movedStudyplan"
><i class='fa fa-pencil'></i> {{text.edit$core}}</t-studyplan-edit>
</span>
<span class='control editable'>
<t-studyplan-associate
v-model="value"><i class='fa fa-users'></i> {{text.associations}}</t-studyplan-associate>
</span>
<span class='control editable'>
<t-studyplan-advanced v-model="value"></t-studyplan-advanced>
</span>
</div>
<div class='t-studyplan-content'>
<drop-list v-if="edit.studyline.editmode"
:items="value.studylines"
class="t-slot-droplist"
:accepts-type="'studyline-'+value.id"
xreorder="$event.apply(value.studylines)"
@reorder="reorderLines($event,value.studylines)"
mode="copy"
row
>
<template v-slot:item="{item}">
<drag
:key="item.id"
class='t-studyplan-drag'
:data="item"
:type="'studyline-'+value.id"
>
<template v-slot:drag-image>
<i class="fa fa-arrows text-primary"></i>
</template>
<t-studyline
:color='item.color'
:name='item.name'
:code='item.shortname'
:editable='true'
:deletable='slotsempty(item.slots)'
:sequence='item.sequence'
:numlines='value.studylines.length'
@edit='editLineStart(item)'
@delete='deleteLine(value,item)'
>
<template v-slot:movebox><i class='fa fa-arrows text-primary'></i></template>
<div v-if="!slotsempty(item.slots)"> {{ text.editmode_modules_hidden}} </div>
</t-studyline>
</drag>
</template>
</drop-list>
<template v-else>
<t-studyline v-for="(item,lineindex) in value.studylines"
:key="item.id"
:color='item.color'
:name='item.name'
:code='item.shortname'
:sequence='lineindex'
:numlines='value.studylines.length'
@edit='editLineStart(item)'
>
<template v-for="(n,index) in (value.slots+1)">
<t-studyline-slot
v-if="index > 0"
type='gradable'
v-model="item.slots[index].competencies"
:key="'c-'+index"
:slotindex="index"
:lineid="item.id"
:plan="value">
</t-studyline-slot>
<t-studyline-slot
type='filter'
v-model="item.slots[index].filters"
:key="'f-'+index"
:slotindex="index"
:lineid="item.id"
:plan="value"
>
</t-studyline-slot>
</template>
</t-studyline>
</template>
<div :id="'studyplan-linewrapper-'+value.id" class='l-leaderline-linewrapper'></div>
</div>
<div v-if="edit.studyline.editmode" class='t-studyline-add'>
<a href="#" v-b-modal="'modal-add-studyline-'+value.id" @click="false;"
><i class='fa fa-plus'></i>{{ text.studyline_add }}</a>
</div>
<b-modal
:id="'modal-add-studyline-'+value.id"
size="lg"
:ok-title="text.add$core"
ok-variant="primary"
:title="text.studyline_add"
@ok="addStudyLine(value,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-'+value.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" />
<!--hsluv-picker
v-model="edit.studyline.data.color"
horizontal displaysize="175" ></hsluv-picker -->
</b-col>
</b-row>
</b-container>
</b-modal>
</div>
`
});
/*
* T-STUDYLINE-HEADER
*/
Vue.component('t-studyline-header', {
props: ['color','name','code', 'slots','sequence','numlines',],
data() {
return {
};
},
computed: {
},
methods: {
},
template: `
<div :class="'t-studyline ' + (sequence%2)?'odd':'even' +
(sequence==0?' first':'') + (sequence==numlines-1?' last':'')" >
<div class="t-studyline-handle" :style="'background-color: ' + color"></div>
<div class="t-studyline-title">
<abbr v-b-tooltip.hover :title="name">{{ code }}</abbr>
</div>
</div>
`,
});
/*
* T-STUDYLINE (Used only for study line edit mode)
*/ */
Vue.component('t-studyline', { Vue.component('t-studyline', {
props: ['color','name','code', 'slots','deletable','editable','sequence','numlines'], props: ['color','name','code', 'slots','deletable','editable','sequence','numlines'],
@ -1466,16 +1493,13 @@ export default {
}, },
template: ` template: `
<div :class="'t-studyline ' + (!editable?((sequence%2)?'odd':'even'):'') + <div :class="'t-studyline ' + (!editable?((sequence%2)?'odd':'even'):'') +
(sequence==0?' first':'') + (sequence==numlines-1?' last':'')"> (sequence==0?' first':'') + (sequence==numlines-1?' last':'')" >
<div class="t-studyline-handle" :style="'background-color: ' + color"></div> <div class="t-studyline-handle" :style="'background-color: ' + color"></div>
<div class="t-studyline-title"> <div class="t-studyline-title">
<div> <div>
<slot name='movebox'> <slot name='movebox'>
</slot> </slot>
<abbr v-b-tooltip.hover :title="name">{{ code }}</abbr> <abbr v-b-tooltip.hover :title="name">{{ code }}</abbr>
<span class='control editable' v-if='!editable'>
<a href='#' @click='onEdit'><i class='fa fa-pencil'></i></a>
</span>
</div> </div>
</div> </div>
<div v-if="editable" class='t-studyline-editmode-content'> <div v-if="editable" class='t-studyline-editmode-content'>
@ -1714,7 +1738,6 @@ export default {
}); });
Vue.component('t-item', { Vue.component('t-item', {
props: { props: {
'value' :{ 'value' :{