Reworked timeline grid (stage 1)
This commit is contained in:
		
							parent
							
								
									f8896ddfdb
								
							
						
					
					
						commit
						340b0eef6b
					
				
					 4 changed files with 147 additions and 126 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
/*eslint no-var: "error"*/
 | 
			
		||||
/*eslint no-console: "off"*/
 | 
			
		||||
/*eslint no-unused-vars: warn */
 | 
			
		||||
/*eslint max-len: ["error", { "code": 160 }] */
 | 
			
		||||
/*eslint-disable no-trailing-spaces */
 | 
			
		||||
/*eslint-env es6*/
 | 
			
		||||
// Put this file in path/to/plugin/amd/src
 | 
			
		||||
| 
						 | 
				
			
			@ -1131,6 +1133,26 @@ export default {
 | 
			
		|||
                }
 | 
			
		||||
            },
 | 
			
		||||
            methods: {
 | 
			
		||||
                countLineLayers(line){
 | 
			
		||||
                    let maxLayer = -1;
 | 
			
		||||
                    for(let i = 0; i <= this.value.slots; i++){
 | 
			
		||||
                        const slot = line.slots[i];
 | 
			
		||||
                        // Determine the amount of used layers in a studyline slit
 | 
			
		||||
                        for(const ix in line.slots[i].competencies){
 | 
			
		||||
                            const item = line.slots[i].competencies[ix];
 | 
			
		||||
                            if(item.layer > maxLayer){
 | 
			
		||||
                                maxLayer = item.layer;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        for(const ix in line.slots[i].filters){
 | 
			
		||||
                            const item = line.slots[i].filters[ix];
 | 
			
		||||
                            if(item.layer > maxLayer){
 | 
			
		||||
                                maxLayer = item.layer;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    return maxLayer+1;
 | 
			
		||||
                },
 | 
			
		||||
                slotsempty(slots) {
 | 
			
		||||
                    if(Array.isArray(slots)){
 | 
			
		||||
                        let count = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1353,32 +1375,36 @@ export default {
 | 
			
		|||
                        <!-- Line by line add the items -->
 | 
			
		||||
                        <!-- The grid layout handles putting it in rows and columns -->
 | 
			
		||||
                        <template v-for="(line,lineindex) in value.studylines"
 | 
			
		||||
                            ><template v-for="(n,index) in (value.slots+1)"
 | 
			
		||||
                                ><t-studyline-slot 
 | 
			
		||||
                                    v-if="index > 0"
 | 
			
		||||
                                    type='gradable'
 | 
			
		||||
                                    v-model="line.slots[index].competencies" 
 | 
			
		||||
                                    :key="'c-'+lineindex+'-'+index" 
 | 
			
		||||
                                    :slotindex="index" 
 | 
			
		||||
                                    :line="line"
 | 
			
		||||
                                    :plan="value"
 | 
			
		||||
                                    :class= "'t-studyline ' + (line.sequence==1?' first':'') + 
 | 
			
		||||
                                             (line.sequence==value.studylines.length?' last':'')"
 | 
			
		||||
                            ><template v-for="layeridx in countLineLayers(line)+1"
 | 
			
		||||
                                ><template v-for="(n,index) in (value.slots+1)"
 | 
			
		||||
                                    >
 | 
			
		||||
                                </t-studyline-slot
 | 
			
		||||
                                ><t-studyline-slot 
 | 
			
		||||
                                    type='filter'
 | 
			
		||||
                                    v-model="line.slots[index].filters" 
 | 
			
		||||
                                    :key="'f-'+lineindex+'-'+index" 
 | 
			
		||||
                                    :slotindex="index" 
 | 
			
		||||
                                    :line="line"
 | 
			
		||||
                                    :plan="value"
 | 
			
		||||
                                    :class="  't-studyline ' 
 | 
			
		||||
                                            + (line.sequence==1?' first':'') 
 | 
			
		||||
                                            + (line.sequence==value.studylines.length?' last':'')
 | 
			
		||||
                                            + (index==value.slots?' end':'')"
 | 
			
		||||
                                    >
 | 
			
		||||
                                </t-studyline-slot
 | 
			
		||||
                                    <t-studyline-slot 
 | 
			
		||||
                                        v-if="index > 0"
 | 
			
		||||
                                        type='gradable'
 | 
			
		||||
                                        v-model="line.slots[index].competencies" 
 | 
			
		||||
                                        :key="'c-'+lineindex+'-'+index+'-'+layeridx" 
 | 
			
		||||
                                        :slotindex="index" 
 | 
			
		||||
                                        :line="line"
 | 
			
		||||
                                        :plan="value"
 | 
			
		||||
                                        :layer="layeridx-1"
 | 
			
		||||
                                        :class= "'t-studyline ' + ((line.sequence==1 && layeridx==1)?' first':'') + 
 | 
			
		||||
                                                (line.sequence==value.studylines.length?' last':'')"
 | 
			
		||||
                                    ></t-studyline-slot
 | 
			
		||||
                                    ><t-studyline-slot 
 | 
			
		||||
                                        type='filter'
 | 
			
		||||
                                        v-model="line.slots[index].filters" 
 | 
			
		||||
                                        :key="'f-'+lineindex+'-'+index+'-'+layeridx" 
 | 
			
		||||
                                        :slotindex="index" 
 | 
			
		||||
                                        :line="line"
 | 
			
		||||
                                        :plan="value"
 | 
			
		||||
                                        :layer="layeridx-1"
 | 
			
		||||
                                        :class="  't-studyline ' 
 | 
			
		||||
                                                + ((line.sequence==1 && layeridx==1)?' first':'') 
 | 
			
		||||
                                                + (line.sequence==value.studylines.length?' last':'')
 | 
			
		||||
                                                + (index==value.slots?' end':'')"
 | 
			
		||||
                                        >
 | 
			
		||||
                                    </t-studyline-slot
 | 
			
		||||
                                ></template
 | 
			
		||||
                            ></template
 | 
			
		||||
                        ></template
 | 
			
		||||
                        ></div><div :id="'studyplan-linewrapper-'+value.id" class='l-leaderline-linewrapper'></div>
 | 
			
		||||
| 
						 | 
				
			
			@ -1594,6 +1620,11 @@ export default {
 | 
			
		|||
            `,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * During a redisign it was decided to have the studyline still get the entire array as a value,
 | 
			
		||||
         * even though it only shows one drop slot for the layer it is in. This is to make repainting easier, 
 | 
			
		||||
         * since we modify the array for the layer we handle 
 | 
			
		||||
         */
 | 
			
		||||
        Vue.component('t-studyline-slot', {
 | 
			
		||||
            props: {
 | 
			
		||||
                type : {
 | 
			
		||||
| 
						 | 
				
			
			@ -1608,8 +1639,11 @@ export default {
 | 
			
		|||
                    type: Object,
 | 
			
		||||
                    default(){ return null;},
 | 
			
		||||
                },
 | 
			
		||||
                layer : {
 | 
			
		||||
                    type: Number,
 | 
			
		||||
                },
 | 
			
		||||
                value: {
 | 
			
		||||
                    type: Array,
 | 
			
		||||
                    type: Array, // dict with layer as index
 | 
			
		||||
                    default(){ return [];},
 | 
			
		||||
                },
 | 
			
		||||
                plan: {
 | 
			
		||||
| 
						 | 
				
			
			@ -1640,20 +1674,35 @@ export default {
 | 
			
		|||
                }
 | 
			
		||||
            },
 | 
			
		||||
            computed: {
 | 
			
		||||
                item(){
 | 
			
		||||
                    for(const itm of this.value){
 | 
			
		||||
                        if(itm.layer == this.layer){
 | 
			
		||||
                            return itm;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    return null;
 | 
			
		||||
                },
 | 
			
		||||
                listtype() {
 | 
			
		||||
                    return this.type;
 | 
			
		||||
                },
 | 
			
		||||
                dragacceptlist(){
 | 
			
		||||
                    if(this.type == "gradable"){
 | 
			
		||||
                        return ["course","competency","gradable-item"];
 | 
			
		||||
                        return ["course", "gradable-item"];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return ["filter", "filter-item"];
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                courseHoverDummy(){
 | 
			
		||||
                    return {course: this.hover.component};
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            data() {
 | 
			
		||||
                return {
 | 
			
		||||
                    resizeListener: null,
 | 
			
		||||
                    hover: { 
 | 
			
		||||
                        component:null,
 | 
			
		||||
                        type: null,
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            methods: {
 | 
			
		||||
| 
						 | 
				
			
			@ -1666,51 +1715,34 @@ export default {
 | 
			
		|||
                },
 | 
			
		||||
                dragacceptcomponent(){
 | 
			
		||||
                    if(this.type == "gradable"){
 | 
			
		||||
                        return ["course","competency",];
 | 
			
		||||
                        return ["course",];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return ["filter",];
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                onInsert(event) {
 | 
			
		||||
                onDrop(event) {
 | 
			
		||||
                    this.hover.component = null;
 | 
			
		||||
                    this.hover.type = null;
 | 
			
		||||
 | 
			
		||||
                    const self = this;
 | 
			
		||||
                    if(self.dragacceptitem().includes(event.type)) {
 | 
			
		||||
                        let item = event.data;
 | 
			
		||||
                        self.value.splice(  event.index,0, item);
 | 
			
		||||
                        self.afterReorder(self.value).done(function(){
 | 
			
		||||
                        // Perform layer update - set this slot and layer here
 | 
			
		||||
                        self.relocateStudyItem(item).done(()=>{
 | 
			
		||||
                            item.layer = this.layer;
 | 
			
		||||
                            item.slot = this.slotindex;
 | 
			
		||||
                            self.value.push(item);
 | 
			
		||||
                            self.$emit("input",self.value);                    
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    else if(self.dragacceptcomponent().includes(event.type) ){
 | 
			
		||||
                        if(event.type == "competency"){
 | 
			
		||||
                            call([{
 | 
			
		||||
                                methodname: 'local_treestudyplan_add_studyitem',
 | 
			
		||||
                                args: { 
 | 
			
		||||
                                    "line_id": self.line.id,
 | 
			
		||||
                                    "slot" : self.slotindex,
 | 
			
		||||
                                    "type": 'competency',
 | 
			
		||||
                                    "details": {
 | 
			
		||||
                                        "competency_id": event.data.id,
 | 
			
		||||
                                        'conditions':'',
 | 
			
		||||
                                        'course_id':null,
 | 
			
		||||
                                        'badge_id':null,
 | 
			
		||||
                                        'continuation_id':null,
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }])[0].done((response) => {
 | 
			
		||||
                                console.info('Add item response:', response);
 | 
			
		||||
                                let item = response;
 | 
			
		||||
                                self.value.splice(event.index, 0, item);
 | 
			
		||||
                                self.afterReorder(self.value).done(function () {
 | 
			
		||||
                                    self.$emit("input", self.value);
 | 
			
		||||
                                });
 | 
			
		||||
                            }).fail(notification.exception);
 | 
			
		||||
                        } 
 | 
			
		||||
                        else if(event.type == "course"){
 | 
			
		||||
                        if(event.type == "course"){
 | 
			
		||||
                            call([{
 | 
			
		||||
                                methodname: 'local_treestudyplan_add_studyitem',
 | 
			
		||||
                                args: { 
 | 
			
		||||
                                    "line_id": self.line.id,
 | 
			
		||||
                                    "slot" : self.slotindex,
 | 
			
		||||
                                    "layer" : self.layer,
 | 
			
		||||
                                    "type": 'course',
 | 
			
		||||
                                    "details": {
 | 
			
		||||
                                        "competency_id": null,
 | 
			
		||||
| 
						 | 
				
			
			@ -1723,9 +1755,9 @@ export default {
 | 
			
		|||
                            }])[0].done((response) => {
 | 
			
		||||
                                console.info('Add item response:', response);
 | 
			
		||||
                                let item = response;
 | 
			
		||||
                                self.value.splice(event.index, 0, item);
 | 
			
		||||
                                self.afterReorder(self.value).done(function () {
 | 
			
		||||
                                    self.$emit("input", self.value);
 | 
			
		||||
                                self.relocateStudyItem(item).done(()=>{
 | 
			
		||||
                                    self.value.push(item);
 | 
			
		||||
                                    self.$emit("input",self.value);                    
 | 
			
		||||
                                });
 | 
			
		||||
                            }).fail(notification.exception);
 | 
			
		||||
                        }                 
 | 
			
		||||
| 
						 | 
				
			
			@ -1743,9 +1775,9 @@ export default {
 | 
			
		|||
                            }])[0].done((response) => {
 | 
			
		||||
                                console.info('Add item response:', response);
 | 
			
		||||
                                let item = response;
 | 
			
		||||
                                self.value.splice(event.index, 0, item);
 | 
			
		||||
                                self.afterReorder(self.value).done(function () {
 | 
			
		||||
                                    self.$emit("input", self.value);
 | 
			
		||||
                                self.relocateStudyItem(item).done(()=>{
 | 
			
		||||
                                    self.value.push(item);
 | 
			
		||||
                                    self.$emit("input",self.value);                    
 | 
			
		||||
                                });
 | 
			
		||||
                            }).fail(notification.exception);
 | 
			
		||||
                        } 
 | 
			
		||||
| 
						 | 
				
			
			@ -1754,88 +1786,76 @@ export default {
 | 
			
		|||
                onCut(event) {
 | 
			
		||||
                    const self=this;
 | 
			
		||||
                    let id = event.data.id;
 | 
			
		||||
 | 
			
		||||
                    for(let i = 0; i < self.value.length; i++){ 
 | 
			
		||||
                        if(self.value[i].id == id){ 
 | 
			
		||||
                            self.value.splice(i, 1); i--; 
 | 
			
		||||
                            break; // just remove one
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    this.afterReorder(self.value);
 | 
			
		||||
                    // Do something to signal that this item has been removed
 | 
			
		||||
                    this.$emit("input",this.value);
 | 
			
		||||
                },
 | 
			
		||||
                onReorder(event) {
 | 
			
		||||
                    const self=this;            
 | 
			
		||||
                    // apply list first
 | 
			
		||||
                    event.apply(self.value);
 | 
			
		||||
                    this.afterReorder(self.value);
 | 
			
		||||
                },
 | 
			
		||||
                afterReorder() {
 | 
			
		||||
                    const self=this;            
 | 
			
		||||
                    // send the new order to the server
 | 
			
		||||
                    let items = [];
 | 
			
		||||
                    for(let idx in self.value)
 | 
			
		||||
                    {
 | 
			
		||||
                        self.value[idx].layer = idx;
 | 
			
		||||
                        items.push({'id': self.value[idx].id,'layer': idx, 'slot': this.slotindex, 'line_id': this.line.id});
 | 
			
		||||
                    }
 | 
			
		||||
                relocateStudyItem(item){
 | 
			
		||||
                    const iteminfo = {'id': item.id, 'layer': this.layer, 'slot': this.slotindex, 'line_id': this.line.id};
 | 
			
		||||
                    return call([{
 | 
			
		||||
                        methodname: 'local_treestudyplan_reorder_studyitems',
 | 
			
		||||
                        args: { 'items': items }
 | 
			
		||||
                    }])[0].fail(notification.exception);          
 | 
			
		||||
                        args: { 'items': [iteminfo] } // function was designed to relocate multiple items at once, hence the array
 | 
			
		||||
                    }])[0].fail(notification.exception);  
 | 
			
		||||
                },
 | 
			
		||||
                feedbackDummy(type,data){
 | 
			
		||||
                    let item = {};
 | 
			
		||||
                    item[type] = data;
 | 
			
		||||
                    return item;
 | 
			
		||||
                }
 | 
			
		||||
                onDragEnter(event){
 | 
			
		||||
                    this.hover.component = event.data;
 | 
			
		||||
                    this.hover.type = event.type;
 | 
			
		||||
                },
 | 
			
		||||
                onDragLeave(){
 | 
			
		||||
                    this.hover.component = null;
 | 
			
		||||
                    this.hover.type = null;
 | 
			
		||||
                },
 | 
			
		||||
 | 
			
		||||
            },
 | 
			
		||||
            template: `
 | 
			
		||||
            <div :class="'t-studyline-slot '+type + ' t-studyline-slot-'+slotindex + ((slotindex==0)?'t-studyline-firstcolumn':'')
 | 
			
		||||
                         + ((line.sequence%2)?' odd':' even') "
 | 
			
		||||
                         :data-studyline="line.id" ref="sizeElement"
 | 
			
		||||
                >
 | 
			
		||||
                <drop-list
 | 
			
		||||
                    :items="value"
 | 
			
		||||
                ><drag v-if="item"
 | 
			
		||||
                    
 | 
			
		||||
                    :key="item.id" 
 | 
			
		||||
                    class="t-slot-item" 
 | 
			
		||||
                    :data="item" 
 | 
			
		||||
                    :type="type+'-item'" 
 | 
			
		||||
                    @cut="onCut"
 | 
			
		||||
                        ><t-item v-model="item" :plan="plan"></t-item
 | 
			
		||||
                        ></drag
 | 
			
		||||
                ><drop v-else
 | 
			
		||||
                    :class="'t-slot-droplist '+type"
 | 
			
		||||
                    :accepts-type="dragacceptlist"
 | 
			
		||||
                    @insert="onInsert"
 | 
			
		||||
                    @reorder="onReorder"
 | 
			
		||||
                    @drop="onDrop"
 | 
			
		||||
                    mode="cut"
 | 
			
		||||
                    row
 | 
			
		||||
                >
 | 
			
		||||
                    <template v-slot:item="{item}">
 | 
			
		||||
                        <drag 
 | 
			
		||||
                            :key="item.id" 
 | 
			
		||||
                            class="t-slot-item" 
 | 
			
		||||
                            :data="item" 
 | 
			
		||||
                            :type="type+'-item'" 
 | 
			
		||||
                            @cut="onCut"><t-item v-model="item" :plan="plan"></t-item></drag>
 | 
			
		||||
                    </template>
 | 
			
		||||
                    <template v-slot:feedback="{data,type}">
 | 
			
		||||
                        <div v-if="type == listtype+'-item'" 
 | 
			
		||||
                    @dragenter="onDragEnter"
 | 
			
		||||
                    @dragleave="onDragLeave"
 | 
			
		||||
                ><template v-if="hover.component">
 | 
			
		||||
                        <div v-if="hover.type == listtype+'-item'" 
 | 
			
		||||
                            class="t-slot-item feedback" 
 | 
			
		||||
                            :key="data.id"><t-item v-model="data" dummy></t-item></div>
 | 
			
		||||
                        <div v-else-if="type == 'competency'" 
 | 
			
		||||
                            :key="hover.component.id"
 | 
			
		||||
                            ><t-item v-model="hover.component" dummy></t-item
 | 
			
		||||
                            ></div
 | 
			
		||||
                        ><div v-else-if="hover.type == 'course'" 
 | 
			
		||||
                            class="t-slot-item feedback" 
 | 
			
		||||
                            :key="'competency-'+data.idnumber"><t-item-competency v-model="data"></t-item-competency></div>
 | 
			
		||||
                        <div v-else-if="type == 'course'" 
 | 
			
		||||
                            :key="'course-'+hover.component.id"
 | 
			
		||||
                            ><t-item-course v-model="courseHoverDummy"></t-item-course></div
 | 
			
		||||
                        ><div v-else-if="hover.type == 'filter'" 
 | 
			
		||||
                            class="t-slot-item feedback" 
 | 
			
		||||
                            :key="'course-;'+data.id"><t-item-course v-model="feedbackDummy('course',data)"></t-item-course></div>
 | 
			
		||||
                        <div v-else-if="type == 'filter'" 
 | 
			
		||||
                            class="t-slot-item feedback" 
 | 
			
		||||
                            key="tooldrop">
 | 
			
		||||
                            <t-item-junction    v-if="data.type == 'junction'" ></t-item-junction>
 | 
			
		||||
                            <t-item-start       v-else-if="data.type == 'start'"    ></t-item-start>
 | 
			
		||||
                            <t-item-finish      v-else-if="data.type == 'finish'"   ></t-item-finish>
 | 
			
		||||
                            <t-item-badge       v-else-if="data.type == 'badge'"    ></t-item-badge>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div v-else 
 | 
			
		||||
                            key="tooldrop"
 | 
			
		||||
                            ><t-item-junction    v-if="hover.component.type == 'junction'" ></t-item-junction
 | 
			
		||||
                            ><t-item-start       v-else-if="hover.component.type == 'start'"    ></t-item-start
 | 
			
		||||
                            ><t-item-finish      v-else-if="hover.component.type == 'finish'"   ></t-item-finish
 | 
			
		||||
                            ><t-item-badge       v-else-if="hover.component.type == 'badge'"    ></t-item-badge
 | 
			
		||||
                        ></div
 | 
			
		||||
                        ><div v-else 
 | 
			
		||||
                            class="t-slot-item feedback"
 | 
			
		||||
                            :key="type">--{{ type }}--</div>
 | 
			
		||||
                    </template>
 | 
			
		||||
                </drop-list>
 | 
			
		||||
            </div>
 | 
			
		||||
                            :key="hover.type">--{{ hover.type }}--</div
 | 
			
		||||
                    ></template
 | 
			
		||||
                ></drop
 | 
			
		||||
            ></div>
 | 
			
		||||
            `,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,9 +189,8 @@ class studyitem {
 | 
			
		|||
    public static function add($fields,$import=false)
 | 
			
		||||
    {
 | 
			
		||||
        global $DB;
 | 
			
		||||
        $addable = ['line_id','type','conditions','slot','competency_id','course_id','badge_id','continuation_id'];
 | 
			
		||||
        if($import){ $addable[] = "layer";}
 | 
			
		||||
        $info = [ 'layer' => -1, ];
 | 
			
		||||
        $addable = ['line_id','type','layer','conditions','slot','competency_id','course_id','badge_id','continuation_id'];
 | 
			
		||||
        $info = [ 'layer' => 0, ];
 | 
			
		||||
        foreach($addable as $f){
 | 
			
		||||
            if(array_key_exists($f,$fields)){
 | 
			
		||||
                $info[$f] = $fields[$f];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -417,6 +417,7 @@ class studyplanservice extends \external_api
 | 
			
		|||
                "continuation_id" => new \external_value(PARAM_INT, 'id of continued item',VALUE_OPTIONAL),
 | 
			
		||||
            ]),
 | 
			
		||||
            "slot" => new \external_value(PARAM_INT, 'slot in the study plan',VALUE_DEFAULT),
 | 
			
		||||
            "layer" => new \external_value(PARAM_INT, 'layer in the slot',VALUE_OPTIONAL),
 | 
			
		||||
        ] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -425,7 +426,7 @@ class studyplanservice extends \external_api
 | 
			
		|||
        return studyitem::editor_structure();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function add_studyitem($line_id,$type,$details,$slot=-1)
 | 
			
		||||
    public static function add_studyitem($line_id,$type,$details,$slot=-1,$layer=0)
 | 
			
		||||
    {
 | 
			
		||||
        webservicehelper::require_capabilities(self::CAP_EDIT,studyline::findById($line_id)->context());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -434,6 +435,7 @@ class studyplanservice extends \external_api
 | 
			
		|||
            'type' => $type,
 | 
			
		||||
            //'conditions' => $conditions,
 | 
			
		||||
            'slot' => $slot,
 | 
			
		||||
            'layer' => $layer,
 | 
			
		||||
            'competency_id' => isset($details['competency_id'])?$details['competency_id']:null,
 | 
			
		||||
            'course_id' => isset($details['course_id'])?$details['course_id']:null,
 | 
			
		||||
            'badge_id' => isset($details['badge_id'])?$details['badge_id']:null,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
$plugin->component = 'local_treestudyplan';  // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
 | 
			
		||||
$plugin->version = 2023070400;  // YYYYMMDDHH (year, month, day, iteration)
 | 
			
		||||
$plugin->version = 2023071400;  // YYYYMMDDHH (year, month, day, iteration)
 | 
			
		||||
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11)
 | 
			
		||||
 | 
			
		||||
$plugin->dependencies = [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue