Commit of mytreestudyplan
This commit is contained in:
parent
c2cb225fa6
commit
e8e2603679
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/.vs
|
/.vs
|
||||||
|
/node_modules
|
||||||
|
/amd/build
|
||||||
|
|
11
LICENSE
11
LICENSE
|
@ -1,7 +1,4 @@
|
||||||
Copyright 2018 P.M. Kuipers
|
Copyright (C) 2022 Peter-Martijn Kuipers
|
||||||
|
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 , USA. Also add information on how to contact you by electronic and paper mail.
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
1
amd/build/debugger.min.js
vendored
1
amd/build/debugger.min.js
vendored
|
@ -1 +0,0 @@
|
||||||
define([],function(){return function(n){let o=!1;return{write:function(){if(o){let o=Array.prototype.slice.call(arguments);o.unshift(n+": "),console.info.apply(console,o)}},info:function(){if(o){let o=Array.prototype.slice.call(arguments);o.unshift(n+": "),console.info.apply(console,o)}},warn:function(){if(o){let o=Array.prototype.slice.call(arguments);o.unshift(n+": "),console.warn.apply(console,o)}},error:function(){if(o){let o=Array.prototype.slice.call(arguments);o.unshift(n+": "),console.error.apply(console,o)}},enable:function(){o=!0},disable:function(){o=!1}}}});
|
|
1
amd/build/handlers.min.js
vendored
1
amd/build/handlers.min.js
vendored
|
@ -1 +0,0 @@
|
||||||
define([],function(){return{fail_report_exception:function(e){void 0!=e.error?console.error("Error from webservice: ",e.error,"\n",e.debuginfo,"\n---Stack trace---\n",e.stacktrace,"\n",e):console.error("Exception from webservice: ",e.message,"\n",e.debuginfo,"\n---Stack trace---\n",e.backtrace,"\n",e)}}});
|
|
1
amd/build/jquery.animate-shadow.min.js
vendored
1
amd/build/jquery.animate-shadow.min.js
vendored
|
@ -1 +0,0 @@
|
||||||
define(["jquery"],function(r){return r(function(r){r.extend(!0,r,{support:{rgba:function(){var e=r("script:first"),t=e.css("color"),s=!1;if(/^rgba/.test(t))s=!0;else try{s=t!==e.css("color","rgba(0, 0, 0, 0.5)").css("color"),e.css("color",t)}catch(r){}return e.removeAttr("style"),s}()}});var e,t=r("html").prop("style");function s(e){var t=[],s=0,n=e.length;function o(){var r=/^(-?[0-9\.]+)(?:px)?\s+(-?[0-9\.]+)(?:px)?(?:\s+(-?[0-9\.]+)(?:px)?)?(?:\s+(-?[0-9\.]+)(?:px)?)?/.exec(e.substring(s));return null!==r&&r.length>0&&(i.left=parseInt(r[1],10),i.top=parseInt(r[2],10),i.blur=r[3]?parseInt(r[3],10):0,i.spread=r[4]?parseInt(r[4],10):0,s+=r[0].length,!0)}function l(){var r=/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})/.exec(e.substring(s));return null!==r&&r.length>0?(i.color=[parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16),1],s+=r[0].length,!0):null!==(r=/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/.exec(e.substring(s)))&&r.length>0?(i.color=[17*parseInt(r[1],16),17*parseInt(r[2],16),17*parseInt(r[3],16),1],s+=r[0].length,!0):null!==(r=/^rgb\(\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*\)/.exec(e.substring(s)))&&r.length>0?(i.color=[parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10),1],s+=r[0].length,!0):null!==(r=/^rgba\(\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*\)/.exec(e.substring(s)))&&r.length>0&&(i.color=[parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10),parseFloat(r[4])],s+=r[0].length,!0)}function a(){var r=/^\s+/.exec(e.substring(s));return null!==r&&r.length>0&&(s+=r[0].length,!0)}function p(){var r=/^\s*,\s*/.exec(e.substring(s));return null!==r&&r.length>0&&(s+=r[0].length,!0)}function u(e){if(r.isPlainObject(e)){var t,s,n=0,o=[];for(r.isArray(e.color)&&(n=(s=e.color).length),t=0;t<4;t++)t<n?o.push(s[t]):3===t?o.push(1):o.push(0)}return r.extend({left:0,top:0,blur:0,spread:0},e)}for(var c,i=u();s<n;)if(void 0,null!==(c=/^inset\b/.exec(e.substring(s)))&&c.length>0&&(i.inset=!0,s+=c[0].length,1))a();else if(o())a();else if(l())a();else{if(!p())break;t.push(u(i)),i={}}return t.push(u(i)),t}r.each(["boxShadow","MozBoxShadow","WebkitBoxShadow"],function(r,s){if(void 0!==t[s])return e=s,!1}),e&&(r.Tween.propHooks.boxShadow={get:function(t){return r(t.elem).css(e)},set:function(t){var n,o=t.elem.style,l=s(r(t.elem)[0].style[e]||r(t.elem).css(e)),a=s(t.end),p=Math.max(l.length,a.length);for(n=0;n<p;n++)a[n]=r.extend({},l[n],a[n]),l[n]?"color"in l[n]&&!1!==r.isArray(l[n].color)||(l[n].color=a[n].color||[0,0,0,0]):l[n]=s("0 0 0 0 rgba(0,0,0,0)")[0];t.run=function(t){var s,n,p,u,c=(s=l,n=a,p=t,u=[],r.each(s,function(e){var t=[],o=s[e],l=n[e];if(o.inset&&t.push("inset"),void 0!==l.left&&t.push(parseFloat(o.left+p*(l.left-o.left))+"px "+parseFloat(o.top+p*(l.top-o.top))+"px"),void 0!==l.blur&&t.push(parseFloat(o.blur+p*(l.blur-o.blur))+"px"),void 0!==l.spread&&t.push(parseFloat(o.spread+p*(l.spread-o.spread))+"px"),void 0!==l.color){var a="rgb"+(r.support.rgba?"a":"")+"("+parseInt(o.color[0]+p*(l.color[0]-o.color[0]),10)+","+parseInt(o.color[1]+p*(l.color[1]-o.color[1]),10)+","+parseInt(o.color[2]+p*(l.color[2]-o.color[2]),10);r.support.rgba&&(a+=","+parseFloat(o.color[3]+p*(l.color[3]-o.color[3]))),a+=")",t.push(a)}u.push(t.join(" "))}),u.join(", "));o[e]=c}}})})});
|
|
1
amd/build/jscolor.min.js
vendored
1
amd/build/jscolor.min.js
vendored
File diff suppressed because one or more lines are too long
1
amd/build/leveleditor.min.js
vendored
1
amd/build/leveleditor.min.js
vendored
|
@ -1 +0,0 @@
|
||||||
define(["jquery","block_gradelevel/jquery.animate-shadow","core/str","core/ajax","block_gradelevel/jscolor","block_gradelevel/handlers","block_gradelevel/debugger"],function(e,t,l,a,n,i,o){let d=new o("leveleditor");d.enable();let r=null,s=null,c={init:function(){s=e("table#level_config"),(r=Number(s.attr("data-skill")))||0===r||"0"===r?(e(document).on("input","input[type=number].uint",function(t){let l=e(this);l.val()<0&&l.val(0)}),e("a[data-action=addlevel]").on("click",function(e){c.add_levelrow(-255,"","7F7F7F")}),e("button[data-action=savechanges]").on("click",c.submit),e("button[data-action=resetlevels]").on("click",c.resetlevels)):d.error("Cannot find configured skill id")},add_levelrow:function(t,l,a){let i=e("<tr data-rowid='"+t+"'><td><input data-name='points' type='number' class='uint' value='"+l+"'></td><td><input type='text' data-name='color' class='jscolor' value='"+a+"'></td></tr>");i.find("input.jscolor").each(function(){new n(this)}),s.find("tbody").append(i)},refresh:function(){d.info("Attempting to refresh"),a.call([{methodname:"block_gradelevel_list_levels",args:{skill_id:r}}])[0].done(c.success_refill_table).fail(c.fail_report_exception)},submit:function(t){let l=[];e("table#level_config").find("tbody tr[data-rowid]").each(function(){let t=e(this),a={id:Number(t.attr("data-rowid")),points:t.find("input[data-name=points]").val(),badgecolor:t.find("input[data-name=color]").val()};""===a.points&&(a.points=-255),a.points=Number(a.points),l.push(a)}),a.call([{methodname:"block_gradelevel_submit_levels",args:{skill_id:r,levels:l}}])[0].done(c.success_refill_table).fail(i.fail_report_exception)},resetlevels:function(t){let l=[];e("table#level_config").find("tbody tr[data-rowid]").each(function(){let t=e(this),a={id:Number(t.attr("data-rowid")),points:-255,badgecolor:""};l.push(a)}),a.call([{methodname:"block_gradelevel_submit_levels",args:{skill_id:r,levels:l}}])[0].done(c.success_refill_table).fail(i.fail_report_exception)},success_refill_table:function(e){let t=s.find("tbody");t.empty();for(let t in e){let l=e[t];c.add_levelrow(l.id,l.points,l.badgecolor)}t.find("input[data-name='points']").animate({boxShadow:"0px 0px 5px 3px #3FDFCF"},400).delay(200).animate({boxShadow:"none"},800)}};return c});
|
|
1
amd/build/renderbadge.min.js
vendored
1
amd/build/renderbadge.min.js
vendored
|
@ -1 +0,0 @@
|
||||||
define(["jquery","core/str","core/ajax","block_gradelevel/debugger"],function(e,t,i,r){let l=r("renderbadge");function n(e){if(/^#([A-Fa-f0-9]{3})$/.test(e)){let t=e.substring(1).split(""),i="0x"+[t[0],t[0],t[1],t[1],t[2],t[2]].join("");return"rgb("+[i>>16&255,i>>8&255,255&i].join(",")+")"}if(/^#([A-Fa-f0-9]{6})$/.test(e)){let t="0x"+e.substring(1).split("").join("");return"rgb("+[t>>16&255,t>>8&255,255&t].join(",")+")"}if(/^#([A-Fa-f0-9]{8})$/.test(e)){let t=e.substring(1).split(""),i="0x"+[t[0],t[1],t[2],t[3],t[4],t[5]].join(""),r="0x"+[t[6],t[7]].join("");return"rgba("+[i>>16&255,i>>8&255,255&i].join(",")+","+r/255+")"}throw Error("Invalid hex code: "+e)}l.enable();let a={init:function(){l.info("Setting up badge renderers"),e("figure.levelbadge").each(function(){a.setup_badge(this,!0)})},setup_badge:function(t,i){let r=e(t),n=e(t).data("badge-props");if(l.info("Setting up skill badge on ",t,n),n&&i)l.info(" skill badge was already configured. Skipping process...");else{n=a.fetchProperties(t);let i=e("<canvas height= '"+n.height+"' width = '"+n.width+"'/>");e("canvas",t).remove(),r.append(i),a.render(i[0],n),r.data("badge-props",n)}},render:function(e,t){let i=e.getContext("2d"),r={base:t.color,light:a.shadeBlendConvert(.6,t.color),dark:a.shadeBlendConvert(.3,t.color),lightPoint:a.shadeBlendConvert(.8,t.color),reflection:{lightest:"#ffffff51",darkest:"#ffffff20"},radialGradient:{x0:.75,y0:.25,r0:.05,x1:.6,y1:.4,r1:.4},levelText:"white"},s={size:Math.min(t.height,t.width),borderWidth:.05,reflection:{angle:-20,offset:.125},levelText:{x:.5,y:.9,size:.2,font:"Open Sans, Arial, helvetica, sans-serif"},icon:{x:.5,y:.47,scale:.7}};l.info(" Config",s),l.info(" Colors",r),l.info(" Props",t);let o=i.createRadialGradient(s.size*r.radialGradient.x0,s.size*r.radialGradient.y0,s.size*r.radialGradient.r0,s.size*r.radialGradient.x1,s.size*r.radialGradient.y1,s.size*r.radialGradient.r1);o.addColorStop(0,n(r.lightPoint)),o.addColorStop(1,n(r.base)),i.beginPath(),i.fillStyle=o,i.arc(.5*s.size,.5*s.size,s.size/2,0,2*Math.PI),i.fill();let d=Math.asin(s.reflection.offset),h=s.reflection.angle/360*2*Math.PI;l.info("rflAngleRad:",h);let f=i.createLinearGradient((.5-s.reflection.offset*Math.sin(h))/2*s.size,(.5+s.reflection.offset*Math.cos(h))/2*s.size,Math.sin(h)/2*s.size,Math.cos(h)/2*s.size);l.info("rflGradient",f),f.addColorStop(0,n(r.reflection.lightest)),f.addColorStop(1,n(r.reflection.darkest)),i.beginPath(),i.fillStyle=f,i.arc(.5*s.size,.5*s.size,s.size/2,0+d+h,Math.PI-d+h),i.fill(),l.info("Starting with border");let g=s.size*s.borderWidth;if(i.beginPath(),i.strokeStyle=r.light,i.lineWidth=g,i.arc(.5*s.size,.5*s.size,s.size/2-g/2,0,2*Math.PI),i.stroke(),i.beginPath(),i.strokeStyle=r.dark,i.lineWidth=g,i.arc(.5*s.size,.5*s.size,s.size/2-g/2,0-Math.PI/2,2*t.progress*Math.PI-Math.PI/2),i.stroke(),t.level&&(i.font=s.size*s.levelText.size+"px "+s.levelText.font,i.fillStyle=r.levelText,i.textAlign="center",i.fillText(""+t.level,s.size*s.levelText.x,s.size*s.levelText.y)),t.image){let e=new Image;e.onload=function(){let e={x:0,y:0,w:s.size*s.icon.scale,h:s.size*s.icon.scale};this.width>this.height?e.h*=this.height/this.width:e.w*=this.width/this.height,e.x=s.size*s.icon.x-e.w/2,e.y=s.size*s.icon.y-e.h/2,i.drawImage(this,e.x,e.y,e.w,e.h)},e.src=t.image}},fetchProperties:function(t){let i=e(t),r=i.find("img"),l=null;return r.length>0&&(l=r.attr("src")),{progress:i.attr("data-progress"),width:i.attr("data-width"),height:i.attr("data-height"),color:"#"+i.attr("data-color"),level:i.attr("data-level"),image:l}},shadeBlendConvert:function(e,t,i){if("number"!=typeof e||e<-1||e>1||"string"!=typeof t||"r"!=t[0]&&"#"!=t[0]||i&&"string"!=typeof i)return null;this.sbcRip||(this.sbcRip=(e=>{let t=e.length,i={};if(t>9){if((e=e.split(",")).length<3||e.length>4)return null;i[0]=r(e[0].split("(")[1]),i[1]=r(e[1]),i[2]=r(e[2]),i[3]=e[3]?parseFloat(e[3]):-1}else{if(8==t||6==t||t<4)return null;t<6&&(e="#"+e[1]+e[1]+e[2]+e[2]+e[3]+e[3]+(t>4?e[4]+""+e[4]:"")),e=r(e.slice(1),16),i[0]=e>>16&255,i[1]=e>>8&255,i[2]=255&e,i[3]=-1,9!=t&&5!=t||(i[3]=l(i[2]/255*1e4)/1e4,i[2]=i[1],i[1]=i[0],i[0]=e>>24&255)}return i}));var r=parseInt,l=Math.round,n=t.length>9,a=(n="string"==typeof i?i.length>9||"c"==i&&!n:n,e<0),s=(e=a?-1*e:e,i=i&&"c"!=i?i:a?"#000000":"#FFFFFF",this.sbcRip(t)),o=this.sbcRip(i);return s&&o?n?"rgb"+(s[3]>-1||o[3]>-1?"a(":"(")+l((o[0]-s[0])*e+s[0])+","+l((o[1]-s[1])*e+s[1])+","+l((o[2]-s[2])*e+s[2])+(s[3]<0&&o[3]<0?")":","+(s[3]>-1&&o[3]>-1?l(1e4*((o[3]-s[3])*e+s[3]))/1e4:o[3]<0?s[3]:o[3])+")"):"#"+(4294967296+16777216*l((o[0]-s[0])*e+s[0])+65536*l((o[1]-s[1])*e+s[1])+256*l((o[2]-s[2])*e+s[2])+(s[3]>-1&&o[3]>-1?l(255*((o[3]-s[3])*e+s[3])):o[3]>-1?l(255*o[3]):s[3]>-1?l(255*s[3]):255)).toString(16).slice(1,s[3]>-1||o[3]>-1?void 0:-2):null}};return a});
|
|
1
amd/build/skilleditor.min.js
vendored
1
amd/build/skilleditor.min.js
vendored
|
@ -1 +0,0 @@
|
||||||
define(["jquery","core/str","core/ajax","core/config","block_gradelevel/renderbadge","block_gradelevel/handlers","block_gradelevel/debugger","core/modal_factory","core/modal_events"],function(e,t,i,l,n,a,o,d,c){let r=o("skilleditor");r.enable();let f=null;let s={init:function(){f=e("div#skill_set"),r.info("Initializing editors"),f.find("li.skill_info").each(function(){s.initialize_item(this)}),r.info("Attaching function to addskill link"),f.find("a[data-action='addskill']").on("click",function(t){i.call([{methodname:"block_gradelevel_add_skill",args:{name:null,icon:null}}])[0].fail(a.fail_report_exception).done(function(t){let i=e(t.html);f.find("ul").append(i),i.each(function(){s.initialize_item(this)}),i.find("figure.levelbadge").each(function(){n.setup_badge(this)})})})},initialize_item:function(o){let f=e(o),s=f.data("id");f.find("a[data-action='editname']").on("click",function(t){let l=f.find("figcaption span[data-type='label']");if(l.length>0){let t=l.text(),n=e("<input type='text'/>").val(t);l.replaceWith(n),n.on("keyup",function(l){let o=l.keyCode?l.keyCode:l.which;if("13"==o){r.info("Saving name");let t=n.val();i.call([{methodname:"block_gradelevel_update_skill",args:{id:s,name:t,icon:null}}])[0].fail(a.fail_report_exception).done(function(t){n.replaceWith(e("<span data-type='label'>"+t.name+"</span>"))})}"27"==o&&(r.info("Cancelled editing"),n.replaceWith(e("<span data-type='label'>"+t+"</span>")))}).on("focusout",function(i){r.info("Cancelled editing"),n.replaceWith(e("<span data-type='label'>"+t+"</span>"))}),n.focus()}else f.find("figurecaption input[type=text]")}),f.find("a[data-action='editicon']").on("click",function(t){let l=e("<input type='file' style='display: none;' accept='.png,.svg'/>");l.on("change",function(t){t.stopPropagation(),t.preventDefault();let o=t.originalEvent.target.files[0],d=new FileReader;e(d).on("load",function(t){let o=t.target.result;i.call([{methodname:"block_gradelevel_update_skill",args:{id:s,name:null,icon:o}}])[0].fail(a.fail_report_exception).done(function(t){let i=f.find("figure.levelbadge");i.empty(),i.append(e("<img style='display:none;' src='"+t.icon+"'/>")),i.each(function(){n.setup_badge(this)})}),l.remove()}),d.readAsDataURL(o)}),f.append(l),l.trigger("click")}),f.find("a[data-action='editlevels']").attr("href",l.wwwroot+"/blocks/gradelevel/cfg_skilllevels.php?skill_id="+s),f.find("a[data-action='deleteskill']").each(function(){let l=e(this);d.create({type:d.types.SAVE_CANCEL,title:t.get_string("title_confirmdelete","block_gradelevel"),body:t.get_string("dialog_confirmdeleteskill","block_gradelevel")},l).done(function(e){r.info("Modal done",e),e.setSaveButtonText(t.get_string("delete","core")),e.getRoot().on(c.save,function(e){r.info("Delete Confirmed"),i.call([{methodname:"block_gradelevel_delete_skill",args:{id:s}}])[0].fail(a.fail_report_exception).done(function(e){e.deleted&&f.remove()})})})})}};return s});
|
|
111
amd/src/block_mytreestudyplan.js
Normal file
111
amd/src/block_mytreestudyplan.js
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*eslint no-var: "error" */
|
||||||
|
/*eslint no-unused-vars: "off" */
|
||||||
|
/*eslint linebreak-style: "off" */
|
||||||
|
/*eslint no-trailing-spaces: "off" */
|
||||||
|
/*eslint-env es6*/
|
||||||
|
// Put this file in path/to/plugin/amd/src
|
||||||
|
// You can call it anything you like
|
||||||
|
|
||||||
|
|
||||||
|
import {call} from 'core/ajax';
|
||||||
|
import notification from 'core/notification';
|
||||||
|
import Vue from 'local_treestudyplan/vue';
|
||||||
|
import RVComponents from 'local_treestudyplan/report-viewer-components';
|
||||||
|
import TSComponents from 'local_treestudyplan/treestudyplan-components';
|
||||||
|
import Debugger from 'local_treestudyplan/debugger';
|
||||||
|
|
||||||
|
import {load_strings} from 'local_treestudyplan/string-helper';
|
||||||
|
import {ProcessStudyplans, fixLineWrappers} from 'local_treestudyplan/studyplan-processor';
|
||||||
|
|
||||||
|
import PortalVue from 'local_treestudyplan/portal-vue';
|
||||||
|
import BootstrapVue from 'local_treestudyplan/bootstrap-vue';
|
||||||
|
Vue.use(TSComponents);
|
||||||
|
Vue.use(RVComponents);
|
||||||
|
Vue.use(PortalVue);
|
||||||
|
Vue.use(BootstrapVue);
|
||||||
|
|
||||||
|
|
||||||
|
let debug = new Debugger("mytreestudyplan");
|
||||||
|
debug.enable();
|
||||||
|
|
||||||
|
let strings = load_strings({
|
||||||
|
studyplan: {
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the Page
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Initialize the Page
|
||||||
|
* @param {string} type Type of page to show
|
||||||
|
* @param {Object} arg Arguments passed
|
||||||
|
*/
|
||||||
|
export function init(type="myreport",arg) {
|
||||||
|
// Make sure on window resize, the line wrappers are repositioned, to fix scrolling issues
|
||||||
|
window.addEventListener('resize',fixLineWrappers);
|
||||||
|
let app = new Vue({
|
||||||
|
el: '#block_mytreestudyplan',
|
||||||
|
data: {
|
||||||
|
"studyplans": [],
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let call_method;
|
||||||
|
let call_args;
|
||||||
|
if(type == "teacher"){
|
||||||
|
call_method = 'local_treestudyplan_get_teacher_studyplan';
|
||||||
|
call_args = {};
|
||||||
|
}
|
||||||
|
else if(type == "teaching"){
|
||||||
|
call_method = 'local_treestudyplan_get_teaching_studyplans';
|
||||||
|
call_args = {};
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
call_method = 'local_treestudyplan_get_own_studyplan';
|
||||||
|
call_args = {};
|
||||||
|
}
|
||||||
|
call([{
|
||||||
|
methodname: call_method,
|
||||||
|
args: call_args
|
||||||
|
}])[0].done(function(response){
|
||||||
|
debug.info("Studyplans:",response);
|
||||||
|
const timingval = { future: 0, present: 1, past: 2, };
|
||||||
|
response.sort((a,b) => {
|
||||||
|
const timinga = TSComponents.studyplanTiming(a);
|
||||||
|
const timingb = TSComponents.studyplanTiming(b);
|
||||||
|
|
||||||
|
let t = timingval[timinga] - timingval[timingb];
|
||||||
|
if(t == 0){
|
||||||
|
// sort by start date if timing is equal
|
||||||
|
t = new Date(b.startdate).getTime() - new Date(a.startdate).getTime();
|
||||||
|
|
||||||
|
if (t == 0) {
|
||||||
|
// sort by name if timing is equal
|
||||||
|
t = a.name.localeCompare(b.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
});
|
||||||
|
app.studyplans = ProcessStudyplans(response);
|
||||||
|
}).fail(notification.exception);
|
||||||
|
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$root.$on('redrawLines',()=>{
|
||||||
|
// Ugly hack, but currently the only way to properly fix scrollablility in the lines
|
||||||
|
fixLineWrappers();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
// Ugly hack, but currently the only way to properly fix scrollablility in the lines
|
||||||
|
setTimeout(fixLineWrappers, 50);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*eslint no-var: "error"*/
|
|
||||||
/*eslint no-console: "off"*/
|
|
||||||
/*eslint-env es6*/
|
|
||||||
// Put this file in path/to/plugin/amd/src
|
|
||||||
// You can call it anything you like
|
|
||||||
|
|
||||||
define([], function () {
|
|
||||||
|
|
||||||
return (function (handle) {
|
|
||||||
let output_enabled = false;
|
|
||||||
|
|
||||||
return {
|
|
||||||
write: function debugger_write() {
|
|
||||||
if (output_enabled) {
|
|
||||||
let args = Array.prototype.slice.call(arguments);
|
|
||||||
args.unshift(handle + ": ");
|
|
||||||
console.info.apply(console, args);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
info: function debugger_info() {
|
|
||||||
if (output_enabled) {
|
|
||||||
let args = Array.prototype.slice.call(arguments);
|
|
||||||
args.unshift(handle + ": ");
|
|
||||||
console.info.apply(console, args);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
warn: function debugger_warn() {
|
|
||||||
if (output_enabled) {
|
|
||||||
let args = Array.prototype.slice.call(arguments);
|
|
||||||
args.unshift(handle + ": ");
|
|
||||||
console.warn.apply(console, args);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function debugger_error() {
|
|
||||||
if (output_enabled) {
|
|
||||||
let args = Array.prototype.slice.call(arguments);
|
|
||||||
args.unshift(handle + ": ");
|
|
||||||
console.error.apply(console, args);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
enable: function debugger_enable() {
|
|
||||||
output_enabled = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
disable: function debugger_disable() {
|
|
||||||
output_enabled = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,22 +0,0 @@
|
||||||
/*eslint no-var: "error"*/
|
|
||||||
/*eslint no-console: "off"*/
|
|
||||||
/*eslint-env es6*/
|
|
||||||
// Put this file in path/to/plugin/amd/src
|
|
||||||
// You can call it anything you like
|
|
||||||
|
|
||||||
define([], function () {
|
|
||||||
let self = {
|
|
||||||
fail_report_exception: function fail_report_exception(ex) {
|
|
||||||
if (ex.error != undefined) {
|
|
||||||
console.error("Error from webservice: ", ex.error, "\n",
|
|
||||||
ex.debuginfo, "\n---Stack trace---\n", ex.stacktrace, "\n", ex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error("Exception from webservice: ", ex.message, "\n",
|
|
||||||
ex.debuginfo, "\n---Stack trace---\n", ex.backtrace, "\n", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return self;
|
|
||||||
});
|
|
|
@ -1,238 +0,0 @@
|
||||||
/*eslint max-len: ["error", { "code": 150 }]*/
|
|
||||||
/**!
|
|
||||||
* @preserve Shadow animation 1.11
|
|
||||||
* http://www.bitstorm.org/jquery/shadow-animation/
|
|
||||||
* Copyright 2011, 2013 Edwin Martin
|
|
||||||
* Contributors: Mark Carver, Xavier Lepretre and Jason Redding
|
|
||||||
* Released under the MIT and GPL licenses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
define(['jquery'], function (jQuery) {
|
|
||||||
|
|
||||||
return jQuery(function($) {
|
|
||||||
/**
|
|
||||||
* Check whether the browser supports RGBA color mode.
|
|
||||||
*
|
|
||||||
* Author Mehdi Kabab <http://pioupioum.fr>
|
|
||||||
* @return {boolean} True if the browser support RGBA. False otherwise.
|
|
||||||
*/
|
|
||||||
function isRGBACapable() {
|
|
||||||
var $script = $('script:first'),
|
|
||||||
color = $script.css('color'),
|
|
||||||
result = false;
|
|
||||||
if (/^rgba/.test(color)) {
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
result = (color !== $script.css('color', 'rgba(0, 0, 0, 0.5)').css('color'));
|
|
||||||
$script.css('color', color);
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$script.removeAttr('style');
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.extend(true, $, {
|
|
||||||
support: {
|
|
||||||
'rgba': isRGBACapable()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*************************************/
|
|
||||||
|
|
||||||
// First define which property to use
|
|
||||||
var styles = $('html').prop('style');
|
|
||||||
var boxShadowProperty;
|
|
||||||
$.each(['boxShadow', 'MozBoxShadow', 'WebkitBoxShadow'], function(i, property) {
|
|
||||||
var val = styles[property];
|
|
||||||
if (typeof val !== 'undefined') {
|
|
||||||
boxShadowProperty = property;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Extend the animate-function
|
|
||||||
if (boxShadowProperty) {
|
|
||||||
$['Tween']['propHooks']['boxShadow'] = {
|
|
||||||
get: function(tween) {
|
|
||||||
return $(tween.elem).css(boxShadowProperty);
|
|
||||||
},
|
|
||||||
set: function(tween) {
|
|
||||||
var style = tween.elem.style;
|
|
||||||
var p_begin = parseShadows($(tween.elem)[0].style[boxShadowProperty] || $(tween.elem).css(boxShadowProperty));
|
|
||||||
var p_end = parseShadows(tween.end);
|
|
||||||
var maxShadowCount = Math.max(p_begin.length, p_end.length);
|
|
||||||
var i;
|
|
||||||
for(i = 0; i < maxShadowCount; i++) {
|
|
||||||
p_end[i] = $.extend({}, p_begin[i], p_end[i]);
|
|
||||||
if (p_begin[i]) {
|
|
||||||
if (!('color' in p_begin[i]) || $.isArray(p_begin[i].color) === false) {
|
|
||||||
p_begin[i].color = p_end[i].color || [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p_begin[i] = parseShadows('0 0 0 0 rgba(0,0,0,0)')[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tween['run'] = function(progress) {
|
|
||||||
var rs = calculateShadows(p_begin, p_end, progress);
|
|
||||||
style[boxShadowProperty] = rs;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate an in-between shadow.
|
|
||||||
function calculateShadows(beginList, endList, pos) {
|
|
||||||
var shadows = [];
|
|
||||||
$.each(beginList, function(i) {
|
|
||||||
var parts = [], begin = beginList[i], end = endList[i];
|
|
||||||
|
|
||||||
if (begin.inset) {
|
|
||||||
parts.push('inset');
|
|
||||||
}
|
|
||||||
if (typeof end.left !== 'undefined') {
|
|
||||||
parts.push(parseFloat(begin.left + pos * (end.left - begin.left)) + 'px '
|
|
||||||
+ parseFloat(begin.top + pos * (end.top - begin.top)) + 'px');
|
|
||||||
}
|
|
||||||
if (typeof end.blur !== 'undefined') {
|
|
||||||
parts.push(parseFloat(begin.blur + pos * (end.blur - begin.blur)) + 'px');
|
|
||||||
}
|
|
||||||
if (typeof end.spread !== 'undefined') {
|
|
||||||
parts.push(parseFloat(begin.spread + pos * (end.spread - begin.spread)) + 'px');
|
|
||||||
}
|
|
||||||
if (typeof end.color !== 'undefined') {
|
|
||||||
var color = 'rgb' + ($.support['rgba'] ? 'a' : '') + '('
|
|
||||||
+ parseInt((begin.color[0] + pos * (end.color[0] - begin.color[0])), 10) + ','
|
|
||||||
+ parseInt((begin.color[1] + pos * (end.color[1] - begin.color[1])), 10) + ','
|
|
||||||
+ parseInt((begin.color[2] + pos * (end.color[2] - begin.color[2])), 10);
|
|
||||||
if ($.support['rgba']) {
|
|
||||||
color += ',' + parseFloat(begin.color[3] + pos * (end.color[3] - begin.color[3]));
|
|
||||||
}
|
|
||||||
color += ')';
|
|
||||||
parts.push(color);
|
|
||||||
}
|
|
||||||
shadows.push(parts.join(' '));
|
|
||||||
});
|
|
||||||
return shadows.join(', ');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the shadow value and extract the values.
|
|
||||||
function parseShadows(shadow) {
|
|
||||||
var parsedShadows = [];
|
|
||||||
var parsePosition = 0;
|
|
||||||
var parseLength = shadow.length;
|
|
||||||
|
|
||||||
function findInset() {
|
|
||||||
var m = /^inset\b/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsedShadow.inset = true;
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function findOffsets() {
|
|
||||||
var m = /^(-?[0-9\.]+)(?:px)?\s+(-?[0-9\.]+)(?:px)?(?:\s+(-?[0-9\.]+)(?:px)?)?(?:\s+(-?[0-9\.]+)(?:px)?)?/.exec(
|
|
||||||
shadow.substring(parsePosition)
|
|
||||||
);
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsedShadow.left = parseInt(m[1], 10);
|
|
||||||
parsedShadow.top = parseInt(m[2], 10);
|
|
||||||
parsedShadow.blur = (m[3] ? parseInt(m[3], 10) : 0);
|
|
||||||
parsedShadow.spread = (m[4] ? parseInt(m[4], 10) : 0);
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function findColor() {
|
|
||||||
var m = /^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsedShadow.color = [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16), 1];
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
m = /^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsedShadow.color = [parseInt(m[1], 16) * 17, parseInt(m[2], 16) * 17, parseInt(m[3], 16) * 17, 1];
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
m = /^rgb\(\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*\)/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsedShadow.color = [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), 1];
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
m = /^rgba\(\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*,\s*([0-9\.]+)\s*\)/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsedShadow.color = [parseInt(m[1], 10), parseInt(m[2], 10), parseInt(m[3], 10), parseFloat(m[4])];
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function findWhiteSpace() {
|
|
||||||
var m = /^\s+/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function findComma() {
|
|
||||||
var m = /^\s*,\s*/.exec(shadow.substring(parsePosition));
|
|
||||||
if (m !== null && m.length > 0) {
|
|
||||||
parsePosition += m[0].length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function normalizeShadow(shadow) {
|
|
||||||
if ($.isPlainObject(shadow)) {
|
|
||||||
var i, sColor, cLength = 0, color = [];
|
|
||||||
if ($.isArray(shadow.color)) {
|
|
||||||
sColor = shadow.color;
|
|
||||||
cLength = sColor.length;
|
|
||||||
}
|
|
||||||
for(i = 0; i < 4; i++) {
|
|
||||||
if (i < cLength) {
|
|
||||||
color.push(sColor[i]);
|
|
||||||
} else if (i === 3) {
|
|
||||||
color.push(1);
|
|
||||||
} else {
|
|
||||||
color.push(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $.extend({
|
|
||||||
'left': 0,
|
|
||||||
'top': 0,
|
|
||||||
'blur': 0,
|
|
||||||
'spread': 0
|
|
||||||
}, shadow);
|
|
||||||
}
|
|
||||||
var parsedShadow = normalizeShadow();
|
|
||||||
|
|
||||||
while (parsePosition < parseLength) {
|
|
||||||
if (findInset()) {
|
|
||||||
findWhiteSpace();
|
|
||||||
} else if (findOffsets()) {
|
|
||||||
findWhiteSpace();
|
|
||||||
} else if (findColor()) {
|
|
||||||
findWhiteSpace();
|
|
||||||
} else if (findComma()) {
|
|
||||||
parsedShadows.push(normalizeShadow(parsedShadow));
|
|
||||||
parsedShadow = {};
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parsedShadows.push(normalizeShadow(parsedShadow));
|
|
||||||
return parsedShadows;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
1867
amd/src/jscolor.js
1867
amd/src/jscolor.js
File diff suppressed because it is too large
Load Diff
|
@ -1,151 +0,0 @@
|
||||||
/*eslint no-var: "error" */
|
|
||||||
/*eslint no-unused-vars: "off" */
|
|
||||||
/*eslint-env es6*/
|
|
||||||
// Put this file in path/to/plugin/amd/src
|
|
||||||
// You can call it anything you like
|
|
||||||
|
|
||||||
define(['jquery', 'block_gradelevel/jquery.animate-shadow', 'core/str', 'core/ajax', 'block_gradelevel/jscolor',
|
|
||||||
'block_gradelevel/handlers', 'block_gradelevel/debugger'], function ($, $shadow, str, ajax, jscolor, handlers, Debugger) {
|
|
||||||
|
|
||||||
let debug = new Debugger("leveleditor");
|
|
||||||
debug.enable();
|
|
||||||
|
|
||||||
let skill_id = null;
|
|
||||||
let $skill_table = null;
|
|
||||||
|
|
||||||
let self = {
|
|
||||||
init: function init() {
|
|
||||||
|
|
||||||
// Find skill table and skill id
|
|
||||||
$skill_table = $("table#level_config");
|
|
||||||
skill_id = Number($skill_table.attr('data-skill'));
|
|
||||||
|
|
||||||
if (!skill_id && skill_id !== 0 && skill_id !== '0') {
|
|
||||||
debug.error("Cannot find configured skill id");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure all uint type numbers are not able to go below 0
|
|
||||||
$(document).on('input', "input[type=number].uint", function (e) {
|
|
||||||
let $this = $(this);
|
|
||||||
if ($this.val() < 0) {
|
|
||||||
$this.val(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// On click handler for add level link
|
|
||||||
$("a[data-action=addlevel]").on('click', function (e) {
|
|
||||||
self.add_levelrow(-255, '', '7F7F7F');
|
|
||||||
});
|
|
||||||
|
|
||||||
// On click handler for save changes button
|
|
||||||
$("button[data-action=savechanges]").on('click', self.submit);
|
|
||||||
// On click handler for save changes button
|
|
||||||
$("button[data-action=resetlevels]").on('click', self.resetlevels);
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
add_levelrow: function (id, points, color) {
|
|
||||||
// create new row
|
|
||||||
let $newtr = $("<tr data-rowid='"+id+"'>"
|
|
||||||
+ "<td><input data-name='points' type='number' class='uint' value='"+points+"'></td>"
|
|
||||||
+ "<td><input type='text' data-name='color' class='jscolor' value='"+color+"'></td></tr>");
|
|
||||||
|
|
||||||
// apply jscolor to new row
|
|
||||||
$newtr.find("input.jscolor").each(function () {
|
|
||||||
let picker = new jscolor(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
// and add to the body of the table
|
|
||||||
$skill_table.find("tbody").append($newtr);
|
|
||||||
},
|
|
||||||
refresh: function refresh() {
|
|
||||||
debug.info("Attempting to refresh");
|
|
||||||
|
|
||||||
// perform refresh call
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_list_levels',
|
|
||||||
args: { skill_id: skill_id },
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].done(self.success_refill_table).fail(self.fail_report_exception);
|
|
||||||
},
|
|
||||||
submit: function submit(evt) {
|
|
||||||
let $table = $("table#level_config");
|
|
||||||
|
|
||||||
let level_data = [];
|
|
||||||
$table.find("tbody tr[data-rowid]").each(function () {
|
|
||||||
let $this = $(this);
|
|
||||||
let row = {
|
|
||||||
id: Number($this.attr('data-rowid')),
|
|
||||||
points: $this.find("input[data-name=points]").val(),
|
|
||||||
badgecolor: $this.find("input[data-name=color]").val(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (row.points === "") { row.points = -255; }
|
|
||||||
row.points = Number(row.points);
|
|
||||||
|
|
||||||
level_data.push(row);
|
|
||||||
});
|
|
||||||
|
|
||||||
//debug.info("Attempting to submit", level_data);
|
|
||||||
|
|
||||||
// perform ajax call
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_submit_levels',
|
|
||||||
args: { skill_id: skill_id, levels: level_data },
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].done(self.success_refill_table).fail(handlers.fail_report_exception);
|
|
||||||
},
|
|
||||||
resetlevels: function resetlevels(evt) {
|
|
||||||
let $table = $("table#level_config");
|
|
||||||
|
|
||||||
// Send a request to delete all rows
|
|
||||||
let level_data = [];
|
|
||||||
$table.find("tbody tr[data-rowid]").each(function () {
|
|
||||||
let $this = $(this);
|
|
||||||
let row = {
|
|
||||||
id: Number($this.attr('data-rowid')),
|
|
||||||
points: -255, // means: delete row
|
|
||||||
badgecolor: "", // totally irrelevent when requesting a delete
|
|
||||||
};
|
|
||||||
|
|
||||||
level_data.push(row);
|
|
||||||
});
|
|
||||||
|
|
||||||
//debug.info("Attempting to submit", level_data);
|
|
||||||
|
|
||||||
// perform ajax call
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_submit_levels',
|
|
||||||
args: { skill_id: skill_id, levels: level_data },
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].done(self.success_refill_table).fail(handlers.fail_report_exception);
|
|
||||||
},
|
|
||||||
success_refill_table: function success_refill_table(response) {
|
|
||||||
//debug.info("Response from webservice: ", response);
|
|
||||||
let $tbody = $skill_table.find('tbody');
|
|
||||||
$tbody.empty();
|
|
||||||
for (let idx in response) {
|
|
||||||
let lvl = response[idx];
|
|
||||||
//debug.info("Level:", lvl);
|
|
||||||
self.add_levelrow(lvl.id, lvl.points, lvl.badgecolor);
|
|
||||||
}
|
|
||||||
let $inputs = $tbody.find("input[data-name='points']");
|
|
||||||
|
|
||||||
$inputs
|
|
||||||
.animate({ boxShadow: '0px 0px 5px 3px #3FDFCF'}, 400)
|
|
||||||
.delay(200)
|
|
||||||
.animate({ boxShadow: 'none'}, 800);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
return self;
|
|
||||||
});
|
|
|
@ -1,254 +0,0 @@
|
||||||
/*eslint no-var: "error"*/
|
|
||||||
/*eslint-env es6*/
|
|
||||||
// Put this file in path/to/plugin/amd/src
|
|
||||||
// You can call it anything you like
|
|
||||||
|
|
||||||
define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], function ($, str, ajax, Debugger) {
|
|
||||||
let debug = Debugger("renderbadge");
|
|
||||||
debug.enable();
|
|
||||||
|
|
||||||
// function is used to overcome Edge's non-support of CSS4 hex rgba notation (@nov 2018)
|
|
||||||
/* eslint-disable no-bitwise*/
|
|
||||||
function hexToRgbA(hex){
|
|
||||||
/*eslint no-bitwise: "off"*/
|
|
||||||
if(/^#([A-Fa-f0-9]{3})$/.test(hex)){
|
|
||||||
let h= hex.substring(1).split('');
|
|
||||||
let c= '0x'+[h[0], h[0], h[1], h[1], h[2], h[2]].join('');
|
|
||||||
return 'rgb('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+')';
|
|
||||||
}
|
|
||||||
if(/^#([A-Fa-f0-9]{6})$/.test(hex)){
|
|
||||||
let h= hex.substring(1).split('');
|
|
||||||
let c= '0x'+h.join('');
|
|
||||||
return 'rgb('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+')';
|
|
||||||
}
|
|
||||||
if(/^#([A-Fa-f0-9]{8})$/.test(hex)){
|
|
||||||
let h= hex.substring(1).split('');
|
|
||||||
let c = '0x' + [h[0],h[1],h[2],h[3],h[4],h[5],].join('');
|
|
||||||
let a= '0x' + [h[6],h[7],].join('');
|
|
||||||
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+a/255.0+')';
|
|
||||||
}
|
|
||||||
throw Error('Invalid hex code: ' + hex);
|
|
||||||
}
|
|
||||||
/* eslint-enable no-bitwise */
|
|
||||||
let self = {
|
|
||||||
init: function init() {
|
|
||||||
debug.info("Setting up badge renderers");
|
|
||||||
// Put whatever you like here. $ is available
|
|
||||||
// to you as normal.
|
|
||||||
$("figure.levelbadge").each(function () {
|
|
||||||
self.setup_badge(this,true);
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
setup_badge: function setup_Badge(figure, allowskip) {
|
|
||||||
let $figure = $(figure);
|
|
||||||
let props = $(figure).data('badge-props');
|
|
||||||
debug.info("Setting up skill badge on ", figure, props);
|
|
||||||
if (props && allowskip) {
|
|
||||||
debug.info(" skill badge was already configured. Skipping process...");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
props = self.fetchProperties(figure);
|
|
||||||
let $canvas = $("<canvas height= '" + props.height + "' width = '" + props.width + "'/>");
|
|
||||||
$('canvas', figure).remove();// clear out any existing canvas
|
|
||||||
$figure.append($canvas); // Put the new canvas in there
|
|
||||||
self.render($canvas[0], props);
|
|
||||||
// Store properties
|
|
||||||
$figure.data("badge-props", props);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render: function render(canvas, props) {
|
|
||||||
let ctx = canvas.getContext("2d");
|
|
||||||
// Color configuration
|
|
||||||
let colors = {
|
|
||||||
base: props.color,
|
|
||||||
light: self.shadeBlendConvert(0.6, props.color), // 60% lighter
|
|
||||||
dark: self.shadeBlendConvert(0.3, props.color), // 30% lighter
|
|
||||||
lightPoint: self.shadeBlendConvert(0.8, props.color), // 80% lighter
|
|
||||||
reflection: {
|
|
||||||
lightest: "#ffffff51",
|
|
||||||
darkest: "#ffffff20",
|
|
||||||
},
|
|
||||||
radialGradient: {
|
|
||||||
x0: 0.75,
|
|
||||||
y0: 0.25,
|
|
||||||
r0: 0.05,
|
|
||||||
x1: 0.6,
|
|
||||||
y1: 0.4,
|
|
||||||
r1: 0.4,
|
|
||||||
},
|
|
||||||
levelText: "white",
|
|
||||||
|
|
||||||
};
|
|
||||||
// size and position configuration
|
|
||||||
let config = {
|
|
||||||
size: Math.min(props.height, props.width),
|
|
||||||
borderWidth: 0.05, // factor of image size
|
|
||||||
reflection: {
|
|
||||||
angle: -20, // relative to horizontal
|
|
||||||
offset: 0.125, // relative to radius
|
|
||||||
},
|
|
||||||
levelText: {
|
|
||||||
x: 0.5,
|
|
||||||
y: 0.9,
|
|
||||||
size: 0.2,
|
|
||||||
font: "Open Sans, Arial, helvetica, sans-serif",
|
|
||||||
},
|
|
||||||
icon: {
|
|
||||||
x: 0.5,
|
|
||||||
y: 0.47,
|
|
||||||
scale: 0.7, // scale to this fraction of image size
|
|
||||||
}
|
|
||||||
};
|
|
||||||
debug.info(" Config", config);
|
|
||||||
debug.info(" Colors", colors);
|
|
||||||
debug.info(" Props", props);
|
|
||||||
|
|
||||||
// draw main circle
|
|
||||||
let baseGradient = ctx.createRadialGradient(
|
|
||||||
config.size * colors.radialGradient.x0,
|
|
||||||
config.size * colors.radialGradient.y0,
|
|
||||||
(config.size ) * colors.radialGradient.r0,
|
|
||||||
config.size * colors.radialGradient.x1,
|
|
||||||
config.size * colors.radialGradient.y1,
|
|
||||||
(config.size ) * colors.radialGradient.r1
|
|
||||||
);
|
|
||||||
baseGradient.addColorStop(0, hexToRgbA(colors.lightPoint));
|
|
||||||
baseGradient.addColorStop(1, hexToRgbA(colors.base));
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.fillStyle = baseGradient;
|
|
||||||
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
|
|
||||||
// draw main reflection
|
|
||||||
let rflOffset = Math.asin(config.reflection.offset);
|
|
||||||
let rflAngleRad = (config.reflection.angle / 360.0) * 2 * Math.PI;
|
|
||||||
|
|
||||||
debug.info("rflAngleRad:",rflAngleRad);
|
|
||||||
let rflGradient = ctx.createLinearGradient(
|
|
||||||
(0.5 - config.reflection.offset * Math.sin(rflAngleRad))/2 * config.size,
|
|
||||||
(0.5 + config.reflection.offset * Math.cos(rflAngleRad))/2 * config.size,
|
|
||||||
Math.sin(rflAngleRad)/2 * config.size,
|
|
||||||
Math.cos(rflAngleRad)/2 * config.size
|
|
||||||
);
|
|
||||||
debug.info("rflGradient",rflGradient);
|
|
||||||
rflGradient.addColorStop(0, hexToRgbA(colors.reflection.lightest));
|
|
||||||
rflGradient.addColorStop(1, hexToRgbA(colors.reflection.darkest));
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.fillStyle = rflGradient;
|
|
||||||
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2,
|
|
||||||
0 + rflOffset + rflAngleRad,
|
|
||||||
Math.PI - rflOffset + rflAngleRad);
|
|
||||||
ctx.fill();
|
|
||||||
debug.info("Starting with border");
|
|
||||||
// draw empty border
|
|
||||||
let strokeWidth = config.size * config.borderWidth;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.strokeStyle = colors.light;
|
|
||||||
ctx.lineWidth = strokeWidth;
|
|
||||||
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2 - strokeWidth / 2, 0, 2 * Math.PI);
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
// draw current progress border
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.strokeStyle = colors.dark;
|
|
||||||
ctx.lineWidth = strokeWidth;
|
|
||||||
ctx.arc(0.5 * config.size, 0.5 * config.size, config.size / 2 - strokeWidth / 2,
|
|
||||||
0 - Math.PI / 2, // -90 degrees (top)
|
|
||||||
props.progress * 2 * Math.PI - Math.PI / 2 // fraction of whole circle offset with -90 degrees
|
|
||||||
);
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
if (props.level) {
|
|
||||||
// write level in lower part
|
|
||||||
ctx.font = "" + config.size * config.levelText.size + "px " + config.levelText.font;
|
|
||||||
ctx.fillStyle = colors.levelText;
|
|
||||||
ctx.textAlign = "center";
|
|
||||||
ctx.fillText("" + props.level, config.size * config.levelText.x, config.size * config.levelText.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
var imageObj = new Image();
|
|
||||||
imageObj.onload = function () {
|
|
||||||
ctx.drawImage(this, 15, 15, 120, 120);
|
|
||||||
};
|
|
||||||
imageObj.src = "https://dev.miqra.nl/blocks/gradelevel/pix/undefinedskill.svg";
|
|
||||||
*/
|
|
||||||
|
|
||||||
// paint image in center
|
|
||||||
if (props.image) {
|
|
||||||
let iconImg = new Image();
|
|
||||||
iconImg.onload = function () {
|
|
||||||
let imPos = {
|
|
||||||
x: 0, // to be determined later
|
|
||||||
y: 0, // to be determined later
|
|
||||||
w: config.size * config.icon.scale,
|
|
||||||
h: config.size * config.icon.scale,
|
|
||||||
};
|
|
||||||
|
|
||||||
// preserve aspect ratio
|
|
||||||
if (this.width > this.height) {
|
|
||||||
imPos.h *= this.height / this.width;
|
|
||||||
} else {
|
|
||||||
imPos.w *= this.width / this.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate x and y
|
|
||||||
imPos.x = (config.size * config.icon.x) - (imPos.w / 2);
|
|
||||||
imPos.y = (config.size * config.icon.y) - (imPos.h / 2);
|
|
||||||
|
|
||||||
ctx.drawImage(this, imPos.x, imPos.y, imPos.w, imPos.h);
|
|
||||||
};
|
|
||||||
//debug.info("Image: ",props.image);
|
|
||||||
iconImg.src = props.image;
|
|
||||||
}
|
|
||||||
|
|
||||||
// complete
|
|
||||||
},
|
|
||||||
fetchProperties: function fetchProperties(figure) {
|
|
||||||
let $figure = $(figure);
|
|
||||||
let $image = $figure.find("img");
|
|
||||||
let image = null;
|
|
||||||
if ($image.length > 0) {
|
|
||||||
image = $image.attr("src");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
progress: $figure.attr("data-progress"),
|
|
||||||
width: $figure.attr("data-width"),
|
|
||||||
height: $figure.attr("data-height"),
|
|
||||||
color: "#"+$figure.attr("data-color"),
|
|
||||||
level: $figure.attr("data-level"),
|
|
||||||
image: image,
|
|
||||||
};
|
|
||||||
|
|
||||||
},
|
|
||||||
shadeBlendConvert: function shadeBlendConvert(p, from, to) {
|
|
||||||
/* eslint-disable no-bitwise, max-len, curly, no-var, no-unused-expressions */
|
|
||||||
// Code for this function was taken from https://github.com/PimpTrizkit/PJs pSBC.js
|
|
||||||
if (typeof (p) != "number" || p < -1 || p > 1 || typeof (from) != "string" || (from[0] != 'r' && from[0] != '#') || (to && typeof (to) != "string")) return null; //ErrorCheck
|
|
||||||
if (!this.sbcRip) this.sbcRip = (d) => {
|
|
||||||
let l = d.length, RGB = {};
|
|
||||||
if (l > 9) {
|
|
||||||
d = d.split(",");
|
|
||||||
if (d.length < 3 || d.length > 4) return null;//ErrorCheck
|
|
||||||
RGB[0] = i(d[0].split("(")[1]), RGB[1] = i(d[1]), RGB[2] = i(d[2]), RGB[3] = d[3] ? parseFloat(d[3]) : -1;
|
|
||||||
} else {
|
|
||||||
if (l == 8 || l == 6 || l < 4) return null; //ErrorCheck
|
|
||||||
if (l < 6) d = "#" + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (l > 4 ? d[4] + "" + d[4] : ""); //3 or 4 digit
|
|
||||||
d = i(d.slice(1), 16), RGB[0] = d >> 16 & 255, RGB[1] = d >> 8 & 255, RGB[2] = d & 255, RGB[3] = -1;
|
|
||||||
if (l == 9 || l == 5) RGB[3] = r((RGB[2] / 255) * 10000) / 10000, RGB[2] = RGB[1], RGB[1] = RGB[0], RGB[0] = d >> 24 & 255;
|
|
||||||
}
|
|
||||||
return RGB;
|
|
||||||
};
|
|
||||||
var i = parseInt, r = Math.round, h = from.length > 9, h = typeof (to) == "string" ? to.length > 9 ? true : to == "c" ? !h : false : h, b = p < 0, p = b ? p * -1 : p, to = to && to != "c" ? to : b ? "#000000" : "#FFFFFF", f = this.sbcRip(from), t = this.sbcRip(to);
|
|
||||||
if (!f || !t) return null; //ErrorCheck
|
|
||||||
if (h) return "rgb" + (f[3] > -1 || t[3] > -1 ? "a(" : "(") + r((t[0] - f[0]) * p + f[0]) + "," + r((t[1] - f[1]) * p + f[1]) + "," + r((t[2] - f[2]) * p + f[2]) + (f[3] < 0 && t[3] < 0 ? ")" : "," + (f[3] > -1 && t[3] > -1 ? r(((t[3] - f[3]) * p + f[3]) * 10000) / 10000 : t[3] < 0 ? f[3] : t[3]) + ")");
|
|
||||||
else return "#" + (0x100000000 + r((t[0] - f[0]) * p + f[0]) * 0x1000000 + r((t[1] - f[1]) * p + f[1]) * 0x10000 + r((t[2] - f[2]) * p + f[2]) * 0x100 + (f[3] > -1 && t[3] > -1 ? r(((t[3] - f[3]) * p + f[3]) * 255) : t[3] > -1 ? r(t[3] * 255) : f[3] > -1 ? r(f[3] * 255) : 255)).toString(16).slice(1, f[3] > -1 || t[3] > -1 ? undefined : -2);
|
|
||||||
/* eslint-enable no-bitwise, max-len, curly, no-var, no-unused-expressions */
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
return self;
|
|
||||||
});
|
|
|
@ -1,179 +0,0 @@
|
||||||
/*eslint no-var: "error"*/
|
|
||||||
/*eslint no-unused-vars: "off" */
|
|
||||||
/*eslint-env es6*/
|
|
||||||
// Put this file in path/to/plugin/amd/src
|
|
||||||
// You can call it anything you like
|
|
||||||
|
|
||||||
define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/renderbadge', 'block_gradelevel/handlers',
|
|
||||||
'block_gradelevel/debugger', 'core/modal_factory', 'core/modal_events'],
|
|
||||||
function ($, str, ajax, mdlcfg, renderbadge, handlers, Debugger, ModalFactory, ModalEvents)
|
|
||||||
{
|
|
||||||
|
|
||||||
let debug = Debugger("skilleditor");
|
|
||||||
debug.enable();
|
|
||||||
|
|
||||||
let $skillset_div = null;
|
|
||||||
const uploadFilter = ".png,.svg";
|
|
||||||
|
|
||||||
let self = {
|
|
||||||
init: function init() {
|
|
||||||
// Find skill table and skill id
|
|
||||||
$skillset_div = $("div#skill_set");
|
|
||||||
// Run initialization code on all items.
|
|
||||||
debug.info("Initializing editors");
|
|
||||||
$skillset_div.find("li.skill_info").each(function () {
|
|
||||||
self.initialize_item(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
debug.info("Attaching function to addskill link");
|
|
||||||
$skillset_div.find("a[data-action='addskill']").on('click', function (e) {
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_add_skill',
|
|
||||||
args: { name: null, icon: null },
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].fail(handlers.fail_report_exception).done(function (data) {
|
|
||||||
let $newskill = $(data.html);
|
|
||||||
$skillset_div.find('ul').append($newskill);
|
|
||||||
$newskill.each(function () {
|
|
||||||
self.initialize_item(this);
|
|
||||||
});
|
|
||||||
$newskill.find('figure.levelbadge').each(function () {
|
|
||||||
renderbadge.setup_badge(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
initialize_item: function initialize_item(li) {
|
|
||||||
let $li = $(li);
|
|
||||||
let skill_id = $li.data('id');
|
|
||||||
|
|
||||||
// Attach edit name pencil
|
|
||||||
$li.find("a[data-action='editname']").on('click', function (e) {
|
|
||||||
let $span = $li.find("figcaption span[data-type='label']");
|
|
||||||
if ($span.length > 0) {
|
|
||||||
let name = $span.text();
|
|
||||||
let $input = $("<input type='text'/>").val(name);// value='" + name + "' />");
|
|
||||||
|
|
||||||
$span.replaceWith($input);
|
|
||||||
$input.on("keyup", function input_keypress(e) {
|
|
||||||
let keycode = (e.keyCode ? e.keyCode : e.which);
|
|
||||||
if (keycode == '13') {
|
|
||||||
debug.info("Saving name");
|
|
||||||
// save the new name
|
|
||||||
let new_name = $input.val();
|
|
||||||
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_update_skill',
|
|
||||||
args: { id: skill_id, name: new_name, icon: null },
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].fail(handlers.fail_report_exception).done(function (data) {
|
|
||||||
$input.replaceWith($("<span data-type='label'>" + data.name + "</span>"));
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
if (keycode == '27') {
|
|
||||||
debug.info("Cancelled editing");
|
|
||||||
$input.replaceWith($("<span data-type='label'>" + name + "</span>"));
|
|
||||||
}
|
|
||||||
}).on("focusout", function input_cancel(e) {
|
|
||||||
debug.info("Cancelled editing");
|
|
||||||
$input.replaceWith($("<span data-type='label'>" + name + "</span>"));
|
|
||||||
});
|
|
||||||
$input.focus();
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let $textinput = $li.find("figurecaption input[type=text]");
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Attach edit icon pencil
|
|
||||||
$li.find("a[data-action='editicon']").on('click', function (e) {
|
|
||||||
let $uploader = $("<input type='file' style='display: none;' accept='" + uploadFilter + "'/>");
|
|
||||||
|
|
||||||
$uploader.on('change', function (e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
let file = e.originalEvent.target.files[0];
|
|
||||||
let fr = new FileReader();
|
|
||||||
$(fr).on('load', function (e) {
|
|
||||||
let dataURI = e.target.result;
|
|
||||||
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_update_skill',
|
|
||||||
args: { id: skill_id, name: null, icon: dataURI },
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].fail(handlers.fail_report_exception).done(function (data) {
|
|
||||||
|
|
||||||
let $figure = $li.find("figure.levelbadge");
|
|
||||||
|
|
||||||
$figure.empty();
|
|
||||||
$figure.append($("<img style='display:none;' src='"+data.icon+"'/>"));
|
|
||||||
|
|
||||||
$figure.each(function () {
|
|
||||||
renderbadge.setup_badge(this);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$uploader.remove(); // delete the uploader after it's done
|
|
||||||
});
|
|
||||||
fr.readAsDataURL(file);
|
|
||||||
|
|
||||||
});
|
|
||||||
$li.append($uploader);
|
|
||||||
$uploader.trigger('click');
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Attach edit levels link
|
|
||||||
$li.find("a[data-action='editlevels']").attr('href',
|
|
||||||
mdlcfg.wwwroot + "/blocks/gradelevel/cfg_skilllevels.php?skill_id=" + skill_id);
|
|
||||||
|
|
||||||
// Attach delete function to any existing functional delete link
|
|
||||||
$li.find("a[data-action='deleteskill']").each(function () {
|
|
||||||
let $trigger = $(this);
|
|
||||||
// Attach delete button code
|
|
||||||
ModalFactory.create({
|
|
||||||
type: ModalFactory.types.SAVE_CANCEL,
|
|
||||||
title: str.get_string('title_confirmdelete', 'block_gradelevel'),
|
|
||||||
body: str.get_string('dialog_confirmdeleteskill', 'block_gradelevel'),
|
|
||||||
}, $trigger).done(function (modal) {
|
|
||||||
// Do what you want with your new modal.
|
|
||||||
debug.info("Modal done", modal);
|
|
||||||
modal.setSaveButtonText(str.get_string('delete', 'core'));
|
|
||||||
modal.getRoot().on(ModalEvents.save, function (e) {
|
|
||||||
debug.info("Delete Confirmed");
|
|
||||||
//e.preventDefault(); if you don't want to close the window
|
|
||||||
|
|
||||||
// call the delete function
|
|
||||||
let promises = ajax.call([{
|
|
||||||
methodname: 'block_gradelevel_delete_skill',
|
|
||||||
args: { id: skill_id},
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// and link promise returns to callbacks
|
|
||||||
promises[0].fail(handlers.fail_report_exception).done(function (data) {
|
|
||||||
|
|
||||||
if (data.deleted) {
|
|
||||||
$li.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return self;
|
|
||||||
});
|
|
|
@ -1,90 +0,0 @@
|
||||||
<?php
|
|
||||||
require_once($CFG->libdir.'/gradelib.php');
|
|
||||||
require_once($CFG->dirroot.'/grade/querylib.php');
|
|
||||||
require_once($CFG->dirroot.'/blocks/gradelevel/lib.php');
|
|
||||||
|
|
||||||
use block_gradelevel;
|
|
||||||
|
|
||||||
class block_gradelevel extends block_base {
|
|
||||||
|
|
||||||
public $levelset;
|
|
||||||
|
|
||||||
public function init() {
|
|
||||||
global $PAGE;
|
|
||||||
global $COURSE;
|
|
||||||
|
|
||||||
$this->title = get_config('gradelevel', 'blocktitle');
|
|
||||||
if(empty($this->title))
|
|
||||||
{
|
|
||||||
$this->title = get_string('title', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
|
|
||||||
// include javascript and run badge renderer when page loading is complete
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
|
|
||||||
|
|
||||||
// find or create the levelset for this course
|
|
||||||
$this->levelset = block_gradelevel_levelset::find_by_course($COURSE->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The PHP tag and the curly bracket for the class definition
|
|
||||||
// will only be closed after there is another function added in the next section.
|
|
||||||
|
|
||||||
public function html_attributes() {
|
|
||||||
$attributes = parent::html_attributes(); // Get default values
|
|
||||||
$attributes['class'] .= ' block_'. $this->name(); // Append our class to class attribute
|
|
||||||
return $attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_content() {
|
|
||||||
global $CFG;
|
|
||||||
global $USER;
|
|
||||||
global $COURSE;
|
|
||||||
|
|
||||||
if ($this->content !== null) {
|
|
||||||
return $this->content;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->content = new stdClass;
|
|
||||||
|
|
||||||
if(empty($this->levelset))
|
|
||||||
{
|
|
||||||
$this->content->text = "<figure class='dummybadge'><img height='150px' width='150px' src='{$CFG->wwwroot}/blocks/gradelevel/pix/brokenbadge.svg' /></figure>";
|
|
||||||
$this->content->footer = get_string("unattached_course",'block_gradelevel');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// below can be a single call to $this->levelset->get_user_leveldata() once the need for debugging (fixed point total) is gone
|
|
||||||
$pointstotal = round($this->levelset->get_levelset_grade($USER->id),1);
|
|
||||||
$level_info = $this->levelset->calculate_level($pointstotal);
|
|
||||||
|
|
||||||
|
|
||||||
$this->content->text = $this->levelset->render_badge($pointstotal);
|
|
||||||
|
|
||||||
if($level_info->levelup_total > 0)
|
|
||||||
{
|
|
||||||
$this->content->footer = "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$pointstotal}</span>/<span class='leveluppoints'>{$level_info->next_at}</span></div>";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->content->footer = "<div class='pointinfo complete'>".get_string('levelup_done','block_gradelevel')."</div>";
|
|
||||||
}
|
|
||||||
|
|
||||||
$coursecontext = context_course::instance($COURSE->id);
|
|
||||||
|
|
||||||
if(has_capability('block/gradelevel:viewresults', $coursecontext))
|
|
||||||
{
|
|
||||||
$this->content->footer .= "\n<div class='teachermode'><a href='{$CFG->wwwroot}/blocks/gradelevel/view-results.php?courseid={$COURSE->id}'>".get_string('teacher_view_results','block_gradelevel')."</a></div>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->content;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function hide_header() { return !get_config('gradelevel', 'showtitle'); }
|
|
||||||
|
|
||||||
public function has_config() { return true; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
91
block_mytreestudyplan.php
Normal file
91
block_mytreestudyplan.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
use local_treestudyplan\studyplan;
|
||||||
|
|
||||||
|
class block_mytreestudyplan extends \block_base {
|
||||||
|
|
||||||
|
public $levelset;
|
||||||
|
|
||||||
|
public function init() {
|
||||||
|
global $PAGE;
|
||||||
|
global $CFG;
|
||||||
|
$this->title = get_string('title', 'block_mytreestudyplan');
|
||||||
|
$systemcontext = \context_system::instance();
|
||||||
|
$teachermode = has_capability("local/treestudyplan:viewuserreports",$systemcontext);
|
||||||
|
|
||||||
|
// Load CSS files from treestudyplan
|
||||||
|
try{
|
||||||
|
$PAGE->requires->css(new \moodle_url($CFG->wwwroot.'/local/treestudyplan/css/bootstrap-vue.min.css'));
|
||||||
|
$PAGE->requires->css(new \moodle_url($CFG->wwwroot.'/local/treestudyplan/css/devstyles.css'));
|
||||||
|
// include javascript and run studyplan renderer when page loading is complete
|
||||||
|
$PAGE->requires->js_call_amd('block_mytreestudyplan/block_mytreestudyplan', 'init',[$teachermode?'teaching':'myreport']);
|
||||||
|
} catch( Exception $x) {
|
||||||
|
// On some occasions (Plugin management), the plugin is loaded after HEAD has been printed. In those cases we don't want to show the block anyway,
|
||||||
|
// so ignore the error that gets inevitably thrown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function applicable_formats()
|
||||||
|
{
|
||||||
|
// Limit this block to the site index and the dashboard (my) pages
|
||||||
|
return [
|
||||||
|
'admin' => false,
|
||||||
|
'site-index' => true,
|
||||||
|
'course-view' => false,
|
||||||
|
'mod' => false,
|
||||||
|
'my' => true
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function get_content() {
|
||||||
|
global $CFG;
|
||||||
|
global $USER;
|
||||||
|
global $COURSE;
|
||||||
|
global $OUTPUT;
|
||||||
|
|
||||||
|
if ($this->content !== null) {
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
$coursecontext = \context_course::instance($COURSE->id);
|
||||||
|
$systemcontext = \context_system::instance();
|
||||||
|
$teachermode = has_capability("local/treestudyplan:viewuserreports",$systemcontext);
|
||||||
|
|
||||||
|
$this->content = new \stdClass;
|
||||||
|
$this->content->text = "";
|
||||||
|
|
||||||
|
$mystudyplans = studyplan::find_for_user($USER->id);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'teachermode' => $teachermode,
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->content->text = $OUTPUT->render_from_template("block_mytreestudyplan/block",$data);
|
||||||
|
|
||||||
|
$invite_url =$CFG->wwwroot.'/local/treestudyplan/invitations.php';
|
||||||
|
$invite_text = get_string('manage_invites','local_treestudyplan');
|
||||||
|
|
||||||
|
|
||||||
|
if($teachermode){
|
||||||
|
$this->content->footer = "<a class='btn btn-primary' href='{$invite_url}'>".get_string("view_plan","local_treestudyplan")."</a>";
|
||||||
|
if(has_capability("local/treestudyplan:editstudyplan",$systemcontext)){
|
||||||
|
$this->content->footer .= " <a class='btn btn-primary' href='{$invite_url}'>".get_string("cfg_plans","local_treestudyplan")."</a>";
|
||||||
|
}
|
||||||
|
} else if (count($mystudyplans) > 0) {
|
||||||
|
$this->content->footer = "<a class='btn btn-primary' href='{$invite_url}' id='manage_invites'><i class='fa fa-share'></i>{$invite_text}</a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function hide_header() { return false; }
|
||||||
|
|
||||||
|
public function has_config() { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
<?php
|
|
||||||
if(isset($_SERVER['SCRIPT_FILENAME']))
|
|
||||||
{
|
|
||||||
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
|
|
||||||
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
|
||||||
error_log("Using {$root}/config.php");
|
|
||||||
require_once($root."/config.php");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
|
||||||
require_once("../../config.php");
|
|
||||||
}
|
|
||||||
|
|
||||||
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
|
|
||||||
|
|
||||||
require_once($CFG->libdir.'/adminlib.php');
|
|
||||||
|
|
||||||
|
|
||||||
admin_externalpage_setup("block_gradelevel_default_levels");
|
|
||||||
|
|
||||||
$systemcontext = context_system::instance();
|
|
||||||
// Check if user has capability to manage skills
|
|
||||||
require_capability('block/gradelevel:skillmanager', $systemcontext);
|
|
||||||
|
|
||||||
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
|
|
||||||
|
|
||||||
print $OUTPUT->header();
|
|
||||||
print $OUTPUT->heading(get_string('cfgpage_globallevels', 'block_gradelevel'));
|
|
||||||
|
|
||||||
// render page for skill level 0 (global)
|
|
||||||
print block_gradelevel_skillmgmtservice::render_leveltable(0);
|
|
||||||
print $OUTPUT->footer();
|
|
|
@ -1,48 +0,0 @@
|
||||||
<?php
|
|
||||||
if(isset($_SERVER['SCRIPT_FILENAME']))
|
|
||||||
{
|
|
||||||
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
|
|
||||||
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
|
||||||
error_log("Using {$root}/config.php");
|
|
||||||
require_once($root."/config.php");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
|
||||||
require_once("../../config.php");
|
|
||||||
}
|
|
||||||
|
|
||||||
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
|
|
||||||
|
|
||||||
require_once($CFG->libdir.'/adminlib.php');
|
|
||||||
|
|
||||||
|
|
||||||
admin_externalpage_setup("block_gradelevel_config_skills");
|
|
||||||
|
|
||||||
|
|
||||||
$skill_id = required_param('skill_id', PARAM_INT);
|
|
||||||
|
|
||||||
$systemcontext = context_system::instance();
|
|
||||||
// Check if user has capability to manage skills
|
|
||||||
require_capability('block/gradelevel:skillmanager', $systemcontext);
|
|
||||||
|
|
||||||
$skill = block_gradelevel_levelset::find_by_id($skill_id);
|
|
||||||
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/skilleditor', 'init');
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/leveleditor', 'init');
|
|
||||||
|
|
||||||
print $OUTPUT->header();
|
|
||||||
|
|
||||||
// render skill editor
|
|
||||||
print $OUTPUT->heading(get_string('cfgpage_editskill','block_gradelevel')." ".$skill->getName());
|
|
||||||
print block_gradelevel_skillmgmtservice::render_skill_editor($skill_id);
|
|
||||||
|
|
||||||
// render level editor
|
|
||||||
print $OUTPUT->heading(get_string('cfgpage_skilllevels','block_gradelevel'));
|
|
||||||
print block_gradelevel_skillmgmtservice::render_leveltable($skill_id);
|
|
||||||
|
|
||||||
// add back button to return to skill management page
|
|
||||||
$cfg_skills_url = $CFG->wwwroot."/blocks/gradelevel/cfg_skills.php";
|
|
||||||
print "<button class='btn' onclick='window.location=\"{$cfg_skills_url}\";'>".get_string('back','core')."</button>";
|
|
||||||
print $OUTPUT->footer();
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?php
|
|
||||||
if(isset($_SERVER['SCRIPT_FILENAME']))
|
|
||||||
{
|
|
||||||
// If SCRIPT_FILENAME is set, use that so the symlinked directories the developmen environment uses are handled correctly
|
|
||||||
$root = dirname(dirname(dirname($_SERVER['SCRIPT_FILENAME'])));
|
|
||||||
error_log("Using {$root}/config.php");
|
|
||||||
require_once($root."/config.php");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If not, assume the cwd is not symlinked and proceed as we are used to
|
|
||||||
require_once("../../config.php");
|
|
||||||
}
|
|
||||||
|
|
||||||
// HOW DID WE ENSURE ONLY ADMINS CAN VIEW THIS PAGE?
|
|
||||||
|
|
||||||
require_once($CFG->libdir.'/adminlib.php');
|
|
||||||
|
|
||||||
|
|
||||||
admin_externalpage_setup("block_gradelevel_config_skills");
|
|
||||||
|
|
||||||
$systemcontext = context_system::instance();
|
|
||||||
// Check if user has capability to manage skills
|
|
||||||
require_capability('block/gradelevel:skillmanager', $systemcontext);
|
|
||||||
|
|
||||||
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/skilleditor', 'init');
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
|
|
||||||
|
|
||||||
print $OUTPUT->header();
|
|
||||||
print $OUTPUT->heading(get_string('cfgpage_skills', 'block_gradelevel'));
|
|
||||||
|
|
||||||
// render page for skill level 0 (global)
|
|
||||||
print block_gradelevel_skillmgmtservice::render_skill_list(0);
|
|
||||||
print $OUTPUT->footer();
|
|
|
@ -1,499 +0,0 @@
|
||||||
<?php
|
|
||||||
require_once($CFG->libdir.'/gradelib.php');
|
|
||||||
require_once($CFG->dirroot.'/grade/querylib.php');
|
|
||||||
|
|
||||||
//namespace block_gradelevel;
|
|
||||||
|
|
||||||
class block_gradelevel_levelset {
|
|
||||||
const UNDEFINED_BADGE_COLOR="#3F3F3F";
|
|
||||||
const NULL_BADGE_COLOR = "000000";
|
|
||||||
const DEFAULT_ICON = "/blocks/gradelevel/pix/undefinedskill.svg";
|
|
||||||
|
|
||||||
const GLOBAL_DEFAULTS = array(
|
|
||||||
0 => "#320000",
|
|
||||||
250 => "#2ad4ff", // + 250
|
|
||||||
750 => "#cd7f32", // + 500
|
|
||||||
1750 => "#92A1A6", // + 1000
|
|
||||||
2750 => "#f6ae00", // + 2000
|
|
||||||
);
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
private $data;
|
|
||||||
private $levels = null;
|
|
||||||
private $global_levels = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a levelset object for an existing database item
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private function __construct($id = null, $dataObject = null)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
$this->id = $id;
|
|
||||||
if($id != null)
|
|
||||||
{
|
|
||||||
if(isset($dataObject) && isset($dataObject->id) && $dataObject->id == $id) // slight sanity check
|
|
||||||
{
|
|
||||||
$this->data = $dataObject;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// database validity check went south, retrieve again
|
|
||||||
$this->data = $DB->get_record('block_gradelevel_levelset', array('id' => $this->id));
|
|
||||||
}
|
|
||||||
|
|
||||||
//retrieve levels for this levelset
|
|
||||||
$this->levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => $this->id));
|
|
||||||
|
|
||||||
usort( $this->levels, function( $a, $b) {
|
|
||||||
return ( $a->points < $b->points ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
|
||||||
// retrieve global levels
|
|
||||||
$this->global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
|
|
||||||
|
|
||||||
usort( $this->global_levels, function( $a, $b) {
|
|
||||||
return ( $a->points < $b->points ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
// if no global levels are defined, insert default global levels
|
|
||||||
if(count($this->global_levels) == 0)
|
|
||||||
{
|
|
||||||
foreach(static::GLOBAL_DEFAULTS as $points => $color)
|
|
||||||
{
|
|
||||||
// setup default
|
|
||||||
$row = new stdClass;
|
|
||||||
$row->levelset_id = 0;
|
|
||||||
$row->points = $points;
|
|
||||||
$row->badgecolor = $color;
|
|
||||||
// insert into db
|
|
||||||
if(!$DB->insert_record('block_gradelevel_levels',$row)){
|
|
||||||
print_error('inserterror', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// and reload global levels;
|
|
||||||
$this->global_levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
|
|
||||||
|
|
||||||
usort( $this->global_levels, function( $a, $b) {
|
|
||||||
return ( $a->points < $b->points ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId() : string
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setName(string $name)
|
|
||||||
{
|
|
||||||
$this->data->name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName() : string
|
|
||||||
{
|
|
||||||
return $this->data->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setIcon(string $iconname)
|
|
||||||
{
|
|
||||||
$this->data->icon = $iconname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIcon() : string
|
|
||||||
{
|
|
||||||
$icon = $this->data->icon;
|
|
||||||
if(empty($icon))
|
|
||||||
{
|
|
||||||
$icon = static::DEFAULT_ICON;
|
|
||||||
}
|
|
||||||
return $icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a levelset for a given course
|
|
||||||
*
|
|
||||||
* @params int $course_id The id of the course to find a levelset for
|
|
||||||
* @return levelset The levelset for this course or null if none found;
|
|
||||||
*/
|
|
||||||
static public function find_by_course($course_id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// FIXME: Make this more efficient by joining it into one sql statement.
|
|
||||||
$records = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id));
|
|
||||||
if(count($records) > 0)
|
|
||||||
{
|
|
||||||
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => array_values($records)[0]->levelset_id));
|
|
||||||
if($levelset)
|
|
||||||
{
|
|
||||||
return new static($levelset->id,$levelset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception $x){} // catch error if table does not (yet exist)
|
|
||||||
return null; // return null if no current levelset linked
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function find_by_id(int $id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
$levelset = $DB->get_record('block_gradelevel_levelset', array('id' => $id));
|
|
||||||
if($levelset)
|
|
||||||
{
|
|
||||||
return new static($levelset->id,$levelset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List attached courses for this levelset
|
|
||||||
*
|
|
||||||
* @return array An array with the id's of attached courses
|
|
||||||
*/
|
|
||||||
public function list_courses()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$list = array();
|
|
||||||
$links = $DB->get_records('block_gradelevel_course_link', array('levelset_id' => $this->id));
|
|
||||||
foreach($links as $link)
|
|
||||||
{
|
|
||||||
$list[] = $link->course_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attach a course to this levelset. The course will be detached from any other levelsets.
|
|
||||||
*
|
|
||||||
* @params int $course_id The id of the course to attach
|
|
||||||
*/
|
|
||||||
public function attach_course($course_id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
// check if course attachement is already done
|
|
||||||
if(!in_array($course_id,$this->list_courses))
|
|
||||||
{
|
|
||||||
// no, now find an existing attachment for this course
|
|
||||||
$rows = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id));
|
|
||||||
if(empty($rows))
|
|
||||||
{
|
|
||||||
// create new attachment if existing link was not found
|
|
||||||
$row = new stdClass;
|
|
||||||
$row->levelset_id = $this->id;
|
|
||||||
$row->course_id = $course_id;
|
|
||||||
// insert new row
|
|
||||||
if(!$DB->insert_record('block_gradelevel_course_link',$row)){
|
|
||||||
print_error('inserterror', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// update existing link (automatically detaches course from its previous levelset)
|
|
||||||
$row = array_values($rows)[0];
|
|
||||||
|
|
||||||
$row->course_id = $course_id;
|
|
||||||
// update existing row
|
|
||||||
if(!$DB->update_record('block_gradelevel_course_link',$row)){
|
|
||||||
print_error('updateerror', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detache a course from this levelset.
|
|
||||||
*
|
|
||||||
* @params int $course_id The id of the course to detach
|
|
||||||
*/
|
|
||||||
public function detach_course($course_id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$rows = $DB->get_records('block_gradelevel_course_link', array('course_id' => $course_id, 'levelset_id' => $this->id));
|
|
||||||
if(!empty($rows))
|
|
||||||
{
|
|
||||||
if(!$DB->delete_records('block_gradelevel_course_link', array('id' => array_values($rows)[0]->id)))
|
|
||||||
{
|
|
||||||
print_error('deleteerror','block_gradelevel');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store changes made to the levelset data parameter containing levelset data
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function save_data()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
if($this->data->id == $this->id) // sanity check so we don't kill everything
|
|
||||||
{
|
|
||||||
if(!$DB->update_record('block_gradelevel_levelset',$this->data)){
|
|
||||||
print_error('updateerror', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_error('datarowchanged_error', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve point total for all attached courses for a given user
|
|
||||||
*
|
|
||||||
* @param int $user_id The id
|
|
||||||
* @return int Total points for this user in this levelset
|
|
||||||
*/
|
|
||||||
public function get_levelset_grade($user_id)
|
|
||||||
{
|
|
||||||
// loop through all attached courses and add up the grade points gathered
|
|
||||||
$points = 0;
|
|
||||||
foreach($this->list_courses() as $course_id)
|
|
||||||
{
|
|
||||||
$result = grade_get_course_grade($user_id,$course_id);
|
|
||||||
$points += $result->grade;
|
|
||||||
}
|
|
||||||
return $points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the levelup data for a given userid in this levelset
|
|
||||||
*
|
|
||||||
* @param int $user_id The id
|
|
||||||
* @return stdClass A stdClass containing the level data for the specified number of point
|
|
||||||
*/
|
|
||||||
public function get_user_leveldata($user_id)
|
|
||||||
{
|
|
||||||
$points = $this->get_levelset_grade($user_id);
|
|
||||||
return $this->calculate_level($points);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new levelset
|
|
||||||
*
|
|
||||||
* @params string $name Optional name of the new levelset
|
|
||||||
* @return levelset The new levelset
|
|
||||||
*/
|
|
||||||
static public function create_new($name="New levelset")
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
// create a new levelset
|
|
||||||
|
|
||||||
$row = new stdClass;
|
|
||||||
$row->name = $name;
|
|
||||||
|
|
||||||
if(!$id = $DB->insert_record('block_gradelevel_levelset',$row, true)){
|
|
||||||
print_error('inserterror', 'block_gradelevel');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$rows = $DB->get_records('block_gradelevel_levelset', array('id' => $id));
|
|
||||||
if(count($rows) > 0)
|
|
||||||
{
|
|
||||||
return new static($id,array_values($rows)[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException("Could not create new levelset");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List all levelsets
|
|
||||||
*
|
|
||||||
* @return array Array of levelset
|
|
||||||
*/
|
|
||||||
static public function list_all()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$list = array();
|
|
||||||
$levelsets = $DB->get_records('block_gradelevel_levelset');
|
|
||||||
|
|
||||||
foreach($levelsets as $lset)
|
|
||||||
{
|
|
||||||
$list[] = new static($lset->id,$lset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $list;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the levelup data, given a specified set of points
|
|
||||||
*
|
|
||||||
* @params int points The amount of points to calculate for
|
|
||||||
* @return stdClass A stdClass containing the level data for the specified number of point
|
|
||||||
*/
|
|
||||||
public function calculate_level($points){
|
|
||||||
|
|
||||||
$levels = $this->badgelevels();
|
|
||||||
|
|
||||||
$level = -1;
|
|
||||||
$badge_color = static::NULL_BADGE_COLOR;
|
|
||||||
$current_at = 0;
|
|
||||||
$next_at = 0;
|
|
||||||
foreach($levels as $threshold => $badgeColor)
|
|
||||||
{
|
|
||||||
if($points >= $threshold){
|
|
||||||
$level++;
|
|
||||||
$badge_color = $badgeColor;
|
|
||||||
$current_at = $threshold;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$next_at = $threshold;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$levelup_points = $next_at - $current_at;
|
|
||||||
$points_in_level = $points - $current_at;
|
|
||||||
if($levelup_points <= 0){ // at max level
|
|
||||||
$progress = 0;
|
|
||||||
$points_in_level = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$progress = $points_in_level / $levelup_points;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = new stdClass;
|
|
||||||
$result->level = $level;
|
|
||||||
$result->badge_color = $badge_color;
|
|
||||||
$result->progress = $progress;
|
|
||||||
$result->next_at = round($next_at);
|
|
||||||
$result->levelup_total = round($levelup_points);
|
|
||||||
$result->points_in_level = round($points_in_level);
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplified list of levels and associated badge colors for this levelset
|
|
||||||
* Takes data from global levelset if more specialized data is not set
|
|
||||||
*
|
|
||||||
* @return array An array of points (keys) and badge color (values), sorted by level
|
|
||||||
*/
|
|
||||||
public function badgelevels()
|
|
||||||
{
|
|
||||||
|
|
||||||
$level_info = array();
|
|
||||||
|
|
||||||
// If we have levels defined, use those, otherwise use the global levels
|
|
||||||
if(!empty($this->levels))
|
|
||||||
{
|
|
||||||
if(array_values($this->levels)[0]->points > 0)
|
|
||||||
{
|
|
||||||
// insert level 0
|
|
||||||
$level_info[0] = static::NULL_BADGE_COLOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach($this->levels as $lvl)
|
|
||||||
{
|
|
||||||
// Check if color is properly set or needs to be retrieved from global config
|
|
||||||
if(!empty($lvl->badgecolor)) {
|
|
||||||
$color = $lvl->badgecolor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$color = static::UNDEFINED_BADGE_COLOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
$level_info[$lvl->points] = $color;
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(empty($this->global_levels) || array_values($this->global_levels)[0]->points > 0)
|
|
||||||
{
|
|
||||||
// insert level 1 if levels don't start at 0 points,
|
|
||||||
// or if no global levels are defined. - At least start somewhere...
|
|
||||||
$level_info[0] = static::NULL_BADGE_COLOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use global levels if levelset is not defined.
|
|
||||||
foreach($this->global_levels as $lvl)
|
|
||||||
{
|
|
||||||
// Check if color is properly set
|
|
||||||
if(!empty($lvl->badgecolor)) {
|
|
||||||
$color = $lvl->badgecolor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$color = static::UNDEFINED_BADGE_COLOR;
|
|
||||||
}
|
|
||||||
$level_info[$lvl->points] = $color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $level_info;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render_badge(int $points,int $size=150){
|
|
||||||
global $CFG;
|
|
||||||
|
|
||||||
$info = $this->calculate_level($points);
|
|
||||||
|
|
||||||
$image = $this->getIcon();
|
|
||||||
if(strncmp($image,"data:",5) == 0)
|
|
||||||
{
|
|
||||||
$image_url = $CFG->wwwroot."/blocks/gradelevel/view-icon.php?skillid=".$this->id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$image_url = $image;
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = "<figure class='levelbadge weird'";
|
|
||||||
$html .= " data-color='{$info->badge_color}'";
|
|
||||||
$html .= " data-progress='{$info->progress}'";
|
|
||||||
$html .= " data-level='{$info->level}'";
|
|
||||||
$html .= " data-width='{$size}'";
|
|
||||||
$html .= " data-height='{$size}'";
|
|
||||||
$html .= ">";
|
|
||||||
if(!empty($image))
|
|
||||||
{
|
|
||||||
$html .= "<img style='display:none' src='{$image_url}' />";
|
|
||||||
}
|
|
||||||
$html .= "</figure>";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render_demo_badge(int $size=100, $level=null)
|
|
||||||
{
|
|
||||||
$levels = $this->badgelevels();
|
|
||||||
if($level === null || $level > count($levels))
|
|
||||||
{
|
|
||||||
$points = array_pop(array_keys($levels));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$points = array_keys($levels)[$level];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render_badge($points, $size);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,473 +0,0 @@
|
||||||
<?php
|
|
||||||
require_once($CFG->libdir.'/gradelib.php');
|
|
||||||
require_once($CFG->libdir.'/externallib.php');
|
|
||||||
require_once($CFG->dirroot.'/grade/querylib.php');
|
|
||||||
|
|
||||||
//namespace block_gradelevel;
|
|
||||||
|
|
||||||
|
|
||||||
class block_gradelevel_skillmgmtservice extends external_api
|
|
||||||
{
|
|
||||||
const DEBUG = false; // enable debug logging
|
|
||||||
const DEMOBADGE_SIZE = 150; // size of demo badge
|
|
||||||
|
|
||||||
private static function log($message)
|
|
||||||
{
|
|
||||||
if(self::DEBUG)
|
|
||||||
{
|
|
||||||
error_log($message."\n",3,"/tmp/block_gradelevel.log");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function list_courses($skill_id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$list = array();
|
|
||||||
$links = $DB->get_records('block_gradelevel_course_link', array('levelset_id' => $skill_id));
|
|
||||||
foreach($links as $link)
|
|
||||||
{
|
|
||||||
$list[] = $link->course_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input parameter config
|
|
||||||
public static function submit_levels_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters(
|
|
||||||
array(
|
|
||||||
'skill_id' => new external_value(PARAM_INT, 'id of skill'),
|
|
||||||
'levels' => new external_multiple_structure(
|
|
||||||
new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'id of level'),
|
|
||||||
'points' => new external_value(PARAM_INT, 'number of points for this level'),
|
|
||||||
'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function list_levels_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters(
|
|
||||||
array(
|
|
||||||
'skill_id' => new external_value(PARAM_INT, 'id of skill'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function list_skills_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters( array() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get_skill_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'id of skill'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function update_skill_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'id of skill'),
|
|
||||||
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
||||||
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function add_skill_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters(
|
|
||||||
array(
|
|
||||||
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
||||||
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function delete_skill_parameters()
|
|
||||||
{
|
|
||||||
return new external_function_parameters(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output parameter config
|
|
||||||
public static function submit_levels_returns()
|
|
||||||
{
|
|
||||||
return new external_multiple_structure(
|
|
||||||
new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'id of level'),
|
|
||||||
'points' => new external_value(PARAM_INT, 'number of points for this level'),
|
|
||||||
'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function list_levels_returns()
|
|
||||||
{
|
|
||||||
return new external_multiple_structure(
|
|
||||||
new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'id of level'),
|
|
||||||
'points' => new external_value(PARAM_INT, 'number of points for this level'),
|
|
||||||
'badgecolor' => new external_value(PARAM_TEXT, 'color of level badge'),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function list_skills_returns()
|
|
||||||
{
|
|
||||||
return new external_multiple_structure(
|
|
||||||
new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
||||||
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
||||||
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
||||||
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get_skill_returns()
|
|
||||||
{
|
|
||||||
return new external_single_structure(
|
|
||||||
array(
|
|
||||||
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
||||||
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
||||||
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function update_skill_returns()
|
|
||||||
{
|
|
||||||
return new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
||||||
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
||||||
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
||||||
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function add_skill_returns()
|
|
||||||
{
|
|
||||||
return new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
||||||
'name' => new external_value(PARAM_TEXT, 'Name of skill'),
|
|
||||||
'icon' => new external_value(PARAM_RAW, 'Icon for skill'),
|
|
||||||
'html' => new external_value(PARAM_RAW, 'Demo badge'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function delete_skill_returns()
|
|
||||||
{
|
|
||||||
return new external_single_structure(
|
|
||||||
array(
|
|
||||||
'id' => new external_value(PARAM_INT, 'Id of skill'),
|
|
||||||
'deleted' => new external_value(PARAM_BOOL, 'Deletion succesful'),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actual functions
|
|
||||||
public static function submit_levels(int $skill_id, array $levels)
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
self::log("submit_levels called, skill_id: {$skill_id}, levels: \n".print_r($levels,true));
|
|
||||||
|
|
||||||
$systemcontext = context_system::instance();
|
|
||||||
self::validate_context($systemcontext);
|
|
||||||
|
|
||||||
|
|
||||||
foreach($levels as $lvl_raw)
|
|
||||||
{
|
|
||||||
// convert level array to stdObj
|
|
||||||
$lvl = (object) $lvl_raw;
|
|
||||||
$lvl->levelset_id = $skill_id;
|
|
||||||
|
|
||||||
self::log("Processing level: ".print_r($lvl,true));
|
|
||||||
|
|
||||||
if($lvl->points >= 0)
|
|
||||||
{
|
|
||||||
if($lvl->id >= 0)
|
|
||||||
{
|
|
||||||
// Update record
|
|
||||||
self::log("updating row {$lvl->id}: {$lvl->points}, {$lvl->badgecolor} @ {$lvl->levelset_id}");
|
|
||||||
$DB->update_record('block_gradelevel_levels',$lvl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// unset invalid id before insert
|
|
||||||
unset($lvl->id);
|
|
||||||
self::log("inserting new row {$lvl->points}, {$lvl->badgecolor} @ {$lvl->levelset_id}");
|
|
||||||
// Insert record
|
|
||||||
$DB->insert_record('block_gradelevel_levels',$lvl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// points is empty: delete record if we have a valid id.
|
|
||||||
if($lvl->id >= 0)
|
|
||||||
{
|
|
||||||
self::log("deleting empty row {$lvl->id}");
|
|
||||||
$DB->delete_records('block_gradelevel_levels', array('id' => $lvl->id));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self::log("ignoring empty row");
|
|
||||||
}
|
|
||||||
|
|
||||||
}/**/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return static::list_levels($skill_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function list_levels(int $skill_id)
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
|
|
||||||
$levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => $skill_id));
|
|
||||||
|
|
||||||
if($skill_id == 0 || count($levels) > 0)
|
|
||||||
{
|
|
||||||
// If global level, or skills are defined, return those
|
|
||||||
|
|
||||||
// Sort by points
|
|
||||||
usort( $levels, function( $a, $b) {
|
|
||||||
return ( $a->points < $b->points ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
return $levels;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Else, return a nameless clone of the default levels).
|
|
||||||
$levels = $DB->get_records('block_gradelevel_levels', array('levelset_id' => 0));
|
|
||||||
|
|
||||||
// Sort by points
|
|
||||||
usort( $levels, function( $a, $b) {
|
|
||||||
return ( $a->points < $b->points ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
foreach($levels as $lvl)
|
|
||||||
{
|
|
||||||
$lvl->id = -255; // replace level id with -255, which is code for "new level" when returned
|
|
||||||
}
|
|
||||||
|
|
||||||
return $levels;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function list_skills()
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
|
|
||||||
$skills = $DB->get_records('block_gradelevel_levelset');
|
|
||||||
|
|
||||||
// Sort by points
|
|
||||||
usort( $skills, function( $a, $b) {
|
|
||||||
return ( $a->name < $b->name) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
foreach($skills as $skill )
|
|
||||||
{
|
|
||||||
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $skills;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function get_skill(int $id)
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
|
|
||||||
$skill = $DB->get_record('block_gradelevel_levels', array('id' => $id));
|
|
||||||
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
|
||||||
|
|
||||||
return $skill;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function update_skill(int $id, $name, $icon )
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
|
|
||||||
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $id));
|
|
||||||
|
|
||||||
if($name != null){
|
|
||||||
$skill->name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($icon != null){
|
|
||||||
$skill->icon = $icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
$DB->update_record('block_gradelevel_levelset',$skill);
|
|
||||||
|
|
||||||
|
|
||||||
$skill->html = block_gradelevel_levelset::find_by_id($skill->id)->render_demo_badge(static::DEMOBADGE_SIZE);
|
|
||||||
|
|
||||||
return $skill;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function add_skill($name, $icon)
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
|
|
||||||
$skill = new stdClass;
|
|
||||||
|
|
||||||
if(empty($name)){
|
|
||||||
$skill->name = get_string('defaults_name','block_gradelevel');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$skill->name = $name;
|
|
||||||
}
|
|
||||||
if(empty($icon)){
|
|
||||||
$skill->icon = "/blocks/gradelevel/pix/undefinedskill.svg";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$skill->icon = $icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $DB->insert_record('block_gradelevel_levelset',$skill, true);
|
|
||||||
|
|
||||||
$skill->id = $id;
|
|
||||||
$skill->html = static::single_skill_editor_item(block_gradelevel_levelset::find_by_id($skill->id));
|
|
||||||
|
|
||||||
return $skill;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function delete_skill(int $id)
|
|
||||||
{
|
|
||||||
global $CFG, $DB;
|
|
||||||
|
|
||||||
$skill = block_gradelevel_levelset::find_by_id($id);
|
|
||||||
if(count($skill->list_courses()) > 0)
|
|
||||||
{
|
|
||||||
throw new Exception("Cannot delete skills that have courses attached");
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = array('id' => $id);
|
|
||||||
$result['deleted'] = ($DB->delete_records('block_gradelevel_levelset',array('id' => $id)))?true:false;
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Other public functions
|
|
||||||
|
|
||||||
public static function render_leveltable($skill_id)
|
|
||||||
{
|
|
||||||
$levels = static::list_levels($skill_id);
|
|
||||||
|
|
||||||
$s = "<p>".get_string('levelcfg_description','block_gradelevel')."</p>";
|
|
||||||
$s .= "<table id='level_config' class='level_config' data-skill='{$skill_id}'>";
|
|
||||||
$s .= "<thead><tr><th>".get_string('levelcfg_head_points','block_gradelevel')."</th><th>".get_string('levelcfg_head_color','block_gradelevel')."</th></tr></thead>";
|
|
||||||
$s .= "<tbody>";
|
|
||||||
foreach($levels as $lvl)
|
|
||||||
{
|
|
||||||
$color = ltrim($lvl->badgecolor,"#"); // trim any leading hashes
|
|
||||||
$s .= "<tr data-rowid='{$lvl->id}'><td><input data-name='points' type='number' class='uint' value='{$lvl->points}'></td><td><input type='text' data-name='color' class='jscolor' value='{$color}'></td></tr>";
|
|
||||||
|
|
||||||
}
|
|
||||||
$s .= "</tbody>";
|
|
||||||
$s .= "<tfoot><tr><td class='block_gradelevel_addlevel' colspan='2'><a data-action='addlevel' href='#' onclick='return false;'>".get_string("levelcfg_addlevel",'block_gradelevel')."</a></td></td></tfoot>";
|
|
||||||
$s .= "</table>";
|
|
||||||
$s .= "<br><p><button class='btn btn-primary' data-action='savechanges'>".get_string('savechanges','core')."</button>";
|
|
||||||
if($skill_id > 0)
|
|
||||||
{
|
|
||||||
$s .= " <button class='btn' data-action='resetlevels'>".get_string('cfg_resetlevels','block_gradelevel')."</button>";
|
|
||||||
}
|
|
||||||
$s .= "</p>";
|
|
||||||
|
|
||||||
return $s;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function render_skill_list()
|
|
||||||
{
|
|
||||||
global $CFG;
|
|
||||||
$skills = block_gradelevel_levelset::list_all();
|
|
||||||
|
|
||||||
// Sort by points
|
|
||||||
usort( $skills, function( $a, $b) {
|
|
||||||
return ( $a->getName() < $b->getName()) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
$s = "<div id='skill_set' class='skill_set'><ul>";
|
|
||||||
foreach($skills as $skill)
|
|
||||||
{
|
|
||||||
$s .= static::single_skill_editor_item($skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
$s .= "</ul>";
|
|
||||||
$s .= "<a href='#' onclick='return false;' data-action='addskill'>".get_string('cfg_addskill','block_gradelevel')."</a>";
|
|
||||||
$s .= "</div>";
|
|
||||||
|
|
||||||
return $s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function render_skill_editor(int $skill_id)
|
|
||||||
{
|
|
||||||
$skill = block_gradelevel_levelset::find_by_id($skill_id);
|
|
||||||
|
|
||||||
$s = "<div id='skill_set' class='skill_set'><ul>";
|
|
||||||
$s .= static::single_skill_editor_item($skill,true);
|
|
||||||
$s .= "</ul></div>";
|
|
||||||
|
|
||||||
return $s;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function single_skill_editor_item($skill,$single=false)
|
|
||||||
{
|
|
||||||
global $OUTPUT;
|
|
||||||
|
|
||||||
$skill_id = $skill->getId();
|
|
||||||
$s = "<li class='skill_info' data-id='{$skill_id}'>";
|
|
||||||
if(!$single){
|
|
||||||
$s .= "<a data-action='editlevels' href='#'>";
|
|
||||||
}
|
|
||||||
$s .= $skill->render_demo_badge(static::DEMOBADGE_SIZE)."</a>";
|
|
||||||
|
|
||||||
if(!$single){
|
|
||||||
$s .= "<a data-action='editlevels' href='#'>";
|
|
||||||
if(count($skill->list_courses()) == 0){
|
|
||||||
$s .= "<a class='deleteskill' data-action='deleteskill' onclick='return false;' href='#'><i class='icon fa fa-minus-circle fa-fw' title='".get_string('tooltip_deleteskill','block_gradelevel')."'></i></a>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$s .= "<a class='editicon' data-action='editicon' onclick='return false;' href='#'><i class='icon fa fa-pencil fa-fw' title='".get_string('tooltip_editicon','block_gradelevel')."'></i></a>";
|
|
||||||
$s .= "<figcaption data-for='name'><span data-type='label'>".$skill->getName()."</span>";
|
|
||||||
$s .= "<a class='editname' data-action='editname' onclick='return false;' href='#'><i class='icon fa fa-pencil fa-fw' title='".get_string('tooltip_editname','block_gradelevel')."'></i></a>";
|
|
||||||
$s .= "</figcaption></li>";
|
|
||||||
return $s;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
$capabilities = array(
|
$capabilities = array(
|
||||||
|
|
||||||
'block/gradelevel:myaddinstance' => array(
|
'block/mytreestudyplan:addinstance' => array(
|
||||||
'captype' => 'write',
|
|
||||||
'contextlevel' => CONTEXT_SYSTEM,
|
|
||||||
'archetypes' => array(
|
|
||||||
'user' => CAP_ALLOW
|
|
||||||
),
|
|
||||||
|
|
||||||
'clonepermissionsfrom' => 'moodle/my:manageblocks'
|
|
||||||
),
|
|
||||||
|
|
||||||
'block/gradelevel:addinstance' => array(
|
|
||||||
'riskbitmask' => RISK_SPAM | RISK_XSS,
|
'riskbitmask' => RISK_SPAM | RISK_XSS,
|
||||||
|
|
||||||
'captype' => 'write',
|
'captype' => 'write',
|
||||||
|
@ -24,26 +14,5 @@
|
||||||
'clonepermissionsfrom' => 'moodle/site:manageblocks'
|
'clonepermissionsfrom' => 'moodle/site:manageblocks'
|
||||||
),
|
),
|
||||||
|
|
||||||
'block/gradelevel:skillmanager' => array(
|
|
||||||
'riskbitmask' => RISK_CONFIG | RISK_DATALOSS | RISK_XSS,
|
|
||||||
|
|
||||||
'captype' => 'write',
|
|
||||||
'contextlevel' => CONTEXT_SYSTEM,
|
|
||||||
'archetypes' => array(
|
|
||||||
'manager' => CAP_ALLOW
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
'block/gradelevel:viewresults' => array(
|
|
||||||
'riskbitmask' => RISK_DATALOSS | RISK_XSS,
|
|
||||||
|
|
||||||
'captype' => 'write',
|
|
||||||
'contextlevel' => CONTEXT_BLOCK,
|
|
||||||
'archetypes' => array(
|
|
||||||
'editingteacher' => CAP_ALLOW,
|
|
||||||
'manager' => CAP_ALLOW
|
|
||||||
),
|
|
||||||
|
|
||||||
),
|
|
||||||
|
|
||||||
);
|
);
|
|
@ -1,44 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<XMLDB PATH="blocks/gradelevel/db" VERSION="20180917" COMMENT="XMLDB file for Moodle blocks/gradelevel"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
|
||||||
>
|
|
||||||
<TABLES>
|
|
||||||
<TABLE NAME="block_gradelevel_levelset" COMMENT="Level set table">
|
|
||||||
<FIELDS>
|
|
||||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
|
||||||
<FIELD NAME="name" TYPE="char" LENGTH="128" NOTNULL="false" SEQUENCE="false" COMMENT="Name of this level set"/>
|
|
||||||
<FIELD NAME="parent_id" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Optional parent for this level set (references another level set)"/>
|
|
||||||
<FIELD NAME="icon" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
|
|
||||||
</FIELDS>
|
|
||||||
<KEYS>
|
|
||||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
|
||||||
<KEY NAME="parent_id_idx" TYPE="foreign" FIELDS="parent_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Parent index for nested levelsets"/>
|
|
||||||
</KEYS>
|
|
||||||
</TABLE>
|
|
||||||
<TABLE NAME="block_gradelevel_levels" COMMENT="Level references">
|
|
||||||
<FIELDS>
|
|
||||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
|
||||||
<FIELD NAME="levelset_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Reference to specific levelset"/>
|
|
||||||
<FIELD NAME="points" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Number of points needed to reach this level"/>
|
|
||||||
<FIELD NAME="badgecolor" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Color of the level badge. Leave null to use default color (of the levelset 0 set)"/>
|
|
||||||
</FIELDS>
|
|
||||||
<KEYS>
|
|
||||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
|
||||||
<KEY NAME="levelset_id_idx" TYPE="foreign" FIELDS="levelset_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Index for levelset reference"/>
|
|
||||||
</KEYS>
|
|
||||||
</TABLE>
|
|
||||||
<TABLE NAME="block_gradelevel_course_link" COMMENT="Link courses to level sets">
|
|
||||||
<FIELDS>
|
|
||||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
|
||||||
<FIELD NAME="course_id" TYPE="int" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="Id of the course to link"/>
|
|
||||||
<FIELD NAME="levelset_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the levelset a course links to"/>
|
|
||||||
</FIELDS>
|
|
||||||
<KEYS>
|
|
||||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
|
||||||
<KEY NAME="course_id_idx" TYPE="foreign-unique" FIELDS="course_id" REFTABLE="mdl_course" REFFIELDS="id" COMMENT="Course Id index"/>
|
|
||||||
<KEY NAME="levelset_id_idx" TYPE="foreign" FIELDS="levelset_id" REFTABLE="block_gradelevel_levelset" REFFIELDS="id" COMMENT="Levelset id reference"/>
|
|
||||||
</KEYS>
|
|
||||||
</TABLE>
|
|
||||||
</TABLES>
|
|
||||||
</XMLDB>
|
|
|
@ -1,93 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
$services = array(
|
|
||||||
"Gradelevel Level Management" => array(
|
|
||||||
'functions' => array('block_gradelevel_submit_levels', 'block_gradelevel_list_levels'),
|
|
||||||
'requiredcapability' => 'block/gradelevel:changelevels',
|
|
||||||
'shortname'=> 'block_gradelevel_levelmgmt',
|
|
||||||
'restrictedusers' => 0,
|
|
||||||
'enabled' => 0,
|
|
||||||
'ajax' => true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
$functions = array(
|
|
||||||
'block_gradelevel_submit_levels' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'submit_levels', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'Update level settings for a given skill', //human readable description of the web service function
|
|
||||||
'type' => 'write', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
'block_gradelevel_list_levels' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'list_levels', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'List level settings for a given skill', //human readable description of the web service function
|
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
'block_gradelevel_list_skills' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'list_skills', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'List skills', //human readable description of the web service function
|
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
'block_gradelevel_get_skill' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'get_skill', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'Retrieve skill information', //human readable description of the web service function
|
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
'block_gradelevel_update_skill' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'update_skill', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'Update a skill', //human readable description of the web service function
|
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
'block_gradelevel_add_skill' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'add_skill', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'Add a new skill', //human readable description of the web service function
|
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
'block_gradelevel_delete_skill' => array( //web service function name
|
|
||||||
'classname' => 'block_gradelevel_skillmgmtservice', //class containing the external function
|
|
||||||
'methodname' => 'delete_skill', //external function name
|
|
||||||
'classpath' => 'blocks/gradelevel/skillmgmtservice.php', //file containing the class/external function
|
|
||||||
'description' => 'Delete a skill', //human readable description of the web service function
|
|
||||||
'type' => 'read', //database rights of the web service function (read, write)
|
|
||||||
'ajax' => true,
|
|
||||||
'capabilities' => 'block/gradelevel:skillmanager',
|
|
||||||
'loginrequired' => true,
|
|
||||||
'services' => array('block_gradelevel_levelmgmt'),
|
|
||||||
),
|
|
||||||
|
|
||||||
);
|
|
|
@ -1,70 +0,0 @@
|
||||||
<?php
|
|
||||||
function xmldb_block_gradelevel_upgrade($oldversion) {
|
|
||||||
global $DB;
|
|
||||||
$dbman = $DB->get_manager();
|
|
||||||
|
|
||||||
/// Add a new column newcol to the mdl_myqtype_options
|
|
||||||
if ($oldversion < 2018091600) {
|
|
||||||
|
|
||||||
// Define table block_gradelevel_levelset to be created.
|
|
||||||
$table = new xmldb_table('block_gradelevel_levelset');
|
|
||||||
|
|
||||||
// Adding fields to table block_gradelevel_levelset.
|
|
||||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
|
||||||
$table->add_field('name', XMLDB_TYPE_CHAR, '128', null, null, null, null);
|
|
||||||
$table->add_field('parent_id', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
|
||||||
$table->add_field('icon', XMLDB_TYPE_TEXT, null, null, null, null, null);
|
|
||||||
|
|
||||||
|
|
||||||
// Adding keys to table block_gradelevel_levelset.
|
|
||||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
|
||||||
$table->add_key('parent_id_idx', XMLDB_KEY_FOREIGN, array('parent_id'), 'block_gradelevel_levelset', array('id'));
|
|
||||||
|
|
||||||
// Conditionally launch create table for block_gradelevel_levelset.
|
|
||||||
if (!$dbman->table_exists($table)) {
|
|
||||||
$dbman->create_table($table);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define table block_gradelevel_levels to be created.
|
|
||||||
$table = new xmldb_table('block_gradelevel_levels');
|
|
||||||
|
|
||||||
// Adding fields to table block_gradelevel_levels.
|
|
||||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
|
||||||
$table->add_field('levelset_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
|
||||||
$table->add_field('points', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
|
|
||||||
$table->add_field('badgecolor', XMLDB_TYPE_CHAR, '10', null, null, null, null);
|
|
||||||
|
|
||||||
// Adding keys to table block_gradelevel_levels.
|
|
||||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
|
||||||
$table->add_key('levelset_id_idx', XMLDB_KEY_FOREIGN, array('levelset_id'), 'block_gradelevel_levelset', array('id'));
|
|
||||||
|
|
||||||
// Conditionally launch create table for block_gradelevel_levels.
|
|
||||||
if (!$dbman->table_exists($table)) {
|
|
||||||
$dbman->create_table($table);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define table block_gradelevel_course_link to be created.
|
|
||||||
$table = new xmldb_table('block_gradelevel_course_link');
|
|
||||||
|
|
||||||
// Adding fields to table block_gradelevel_course_link.
|
|
||||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
|
||||||
$table->add_field('course_id', XMLDB_TYPE_INTEGER, '20', null, XMLDB_NOTNULL, null, null);
|
|
||||||
$table->add_field('levelset_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
|
|
||||||
|
|
||||||
// Adding keys to table block_gradelevel_course_link.
|
|
||||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
|
||||||
$table->add_key('course_id_idx', XMLDB_KEY_FOREIGN_UNIQUE, array('course_id'), 'mdl_course', array('id'));
|
|
||||||
$table->add_key('levelset_id_idx', XMLDB_KEY_FOREIGN, array('levelset_id'), 'block_gradelevel_levelset', array('id'));
|
|
||||||
|
|
||||||
// Conditionally launch create table for block_gradelevel_course_link.
|
|
||||||
if (!$dbman->table_exists($table)) {
|
|
||||||
$dbman->create_table($table);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gradelevel savepoint reached.
|
|
||||||
upgrade_block_savepoint(true, 2018091600, 'gradelevel');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,184 +0,0 @@
|
||||||
USER: stdClass Object
|
|
||||||
(
|
|
||||||
[id] => 2
|
|
||||||
[auth] => manual
|
|
||||||
[confirmed] => 1
|
|
||||||
[policyagreed] => 0
|
|
||||||
[deleted] => 0
|
|
||||||
[suspended] => 0
|
|
||||||
[mnethostid] => 1
|
|
||||||
[username] => admin
|
|
||||||
[idnumber] =>
|
|
||||||
[firstname] => Admin
|
|
||||||
[lastname] => User
|
|
||||||
[email] => pm@miqra.nl
|
|
||||||
[emailstop] => 0
|
|
||||||
[icq] =>
|
|
||||||
[skype] =>
|
|
||||||
[yahoo] =>
|
|
||||||
[aim] =>
|
|
||||||
[msn] =>
|
|
||||||
[phone1] =>
|
|
||||||
[phone2] =>
|
|
||||||
[institution] =>
|
|
||||||
[department] =>
|
|
||||||
[address] =>
|
|
||||||
[city] =>
|
|
||||||
[country] =>
|
|
||||||
[lang] => en
|
|
||||||
[calendartype] => gregorian
|
|
||||||
[theme] =>
|
|
||||||
[timezone] => 99
|
|
||||||
[firstaccess] => 1530717879
|
|
||||||
[lastaccess] => 1536959033
|
|
||||||
[lastlogin] => 1530732921
|
|
||||||
[currentlogin] => 1536953353
|
|
||||||
[lastip] => 2001:985:a081:1:5dfc:c799:21e1:4fdc
|
|
||||||
[secret] =>
|
|
||||||
[picture] => 0
|
|
||||||
[url] =>
|
|
||||||
[descriptionformat] => 1
|
|
||||||
[mailformat] => 1
|
|
||||||
[maildigest] => 0
|
|
||||||
[maildisplay] => 1
|
|
||||||
[autosubscribe] => 1
|
|
||||||
[trackforums] => 0
|
|
||||||
[timecreated] => 0
|
|
||||||
[timemodified] => 1530717931
|
|
||||||
[trustbitmask] => 0
|
|
||||||
[imagealt] =>
|
|
||||||
[lastnamephonetic] =>
|
|
||||||
[firstnamephonetic] =>
|
|
||||||
[middlename] =>
|
|
||||||
[alternatename] =>
|
|
||||||
[lastcourseaccess] => Array
|
|
||||||
(
|
|
||||||
[2] => 1530738819
|
|
||||||
)
|
|
||||||
|
|
||||||
[currentcourseaccess] => Array
|
|
||||||
(
|
|
||||||
[2] => 1536959033
|
|
||||||
)
|
|
||||||
|
|
||||||
[groupmember] => Array
|
|
||||||
(
|
|
||||||
)
|
|
||||||
|
|
||||||
[profile] => Array
|
|
||||||
(
|
|
||||||
)
|
|
||||||
|
|
||||||
[sesskey] => ejGT6VqIBv
|
|
||||||
[ajax_updatable_user_prefs] => Array
|
|
||||||
(
|
|
||||||
[drawer-open-nav] => alpha
|
|
||||||
[filepicker_recentrepository] => int
|
|
||||||
[filepicker_recentlicense] => safedir
|
|
||||||
[filepicker_recentviewmode] => int
|
|
||||||
[filemanager_recentviewmode] => int
|
|
||||||
)
|
|
||||||
|
|
||||||
[editing] => 1
|
|
||||||
[preference] => Array
|
|
||||||
(
|
|
||||||
[core_message_migrate_data] => 1
|
|
||||||
[auth_manual_passwordupdatetime] => 1530717931
|
|
||||||
[email_bounce_count] => 1
|
|
||||||
[email_send_count] => 1
|
|
||||||
[filepicker_recentrepository] => 4
|
|
||||||
[filepicker_recentlicense] => allrightsreserved
|
|
||||||
[login_failed_count_since_success] => 6
|
|
||||||
[ifirst] =>
|
|
||||||
[ilast] =>
|
|
||||||
[_lastloaded] => 1536959033
|
|
||||||
)
|
|
||||||
|
|
||||||
[enrol] => Array
|
|
||||||
(
|
|
||||||
[enrolled] => Array
|
|
||||||
(
|
|
||||||
[2] => 2147483647
|
|
||||||
)
|
|
||||||
|
|
||||||
[tempguest] => Array
|
|
||||||
(
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
[grade_last_report] => Array
|
|
||||||
(
|
|
||||||
[2] => grader
|
|
||||||
)
|
|
||||||
|
|
||||||
[gradeediting] => Array
|
|
||||||
(
|
|
||||||
[2] => 0
|
|
||||||
)
|
|
||||||
|
|
||||||
[access] => Array
|
|
||||||
(
|
|
||||||
[ra] => Array
|
|
||||||
(
|
|
||||||
[/1] => Array
|
|
||||||
(
|
|
||||||
[7] => 7
|
|
||||||
)
|
|
||||||
|
|
||||||
[/1/2] => Array
|
|
||||||
(
|
|
||||||
[8] => 8
|
|
||||||
)
|
|
||||||
|
|
||||||
[/1/40/23] => Array
|
|
||||||
(
|
|
||||||
[3] => 3
|
|
||||||
[5] => 5
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
[time] => 1536958657
|
|
||||||
[rsw] => Array
|
|
||||||
(
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
COURSE: stdClass Object
|
|
||||||
(
|
|
||||||
[id] => 2
|
|
||||||
[category] => 2
|
|
||||||
[sortorder] => 20001
|
|
||||||
[fullname] => PIC Microcontrollers programmeren
|
|
||||||
[shortname] => PIC-MCU3
|
|
||||||
[idnumber] =>
|
|
||||||
[summary] => Programmeren van PIC18 microcontrollers van microchip.
|
|
||||||
[summaryformat] => 1
|
|
||||||
[format] => topics
|
|
||||||
[showgrades] => 1
|
|
||||||
[newsitems] => 0
|
|
||||||
[startdate] => 1526594400
|
|
||||||
[enddate] => 0
|
|
||||||
[marker] => 0
|
|
||||||
[maxbytes] => 0
|
|
||||||
[legacyfiles] => 0
|
|
||||||
[showreports] => 0
|
|
||||||
[visible] => 1
|
|
||||||
[visibleold] => 1
|
|
||||||
[groupmode] => 0
|
|
||||||
[groupmodeforce] => 0
|
|
||||||
[defaultgroupingid] => 0
|
|
||||||
[lang] =>
|
|
||||||
[calendartype] =>
|
|
||||||
[theme] =>
|
|
||||||
[timecreated] => 1526555879
|
|
||||||
[timemodified] => 1536956992
|
|
||||||
[requested] => 0
|
|
||||||
[enablecompletion] => 1
|
|
||||||
[completionnotify] => 0
|
|
||||||
[cacherev] => 1536956992
|
|
||||||
)
|
|
|
@ -1,82 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
require_once($CFG->dirroot.'/blocks/gradelevel/lib.php');
|
|
||||||
|
|
||||||
class block_gradelevel_edit_form extends block_edit_form {
|
|
||||||
|
|
||||||
|
|
||||||
protected function specific_definition($mform) {
|
|
||||||
global $CFG;
|
|
||||||
// retrieve levelset
|
|
||||||
$levelset = $this->block->levelset;
|
|
||||||
|
|
||||||
// Section header title according to language file.
|
|
||||||
$mform->addElement('header', 'config_header', get_string('blocksettings', 'block'));
|
|
||||||
|
|
||||||
$skills = block_gradelevel_levelset::list_all();
|
|
||||||
// sort by name
|
|
||||||
usort( $skills, function( $a, $b) {
|
|
||||||
return ( $a->getName() < $b->getName()) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
$options = array( '-1' => get_string('edit_noneskill', 'block_gradelevel'));
|
|
||||||
foreach($skills as $skill)
|
|
||||||
{
|
|
||||||
$options[$skill->getId()] = $skill->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A sample string variable with a default value.
|
|
||||||
$mform->addElement('select', 'attached_skill', get_string('edit_pickskill', 'block_gradelevel'), $options);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set_data($defaults)
|
|
||||||
{
|
|
||||||
global $COURSE;
|
|
||||||
|
|
||||||
$defaults->attached_skill = -1;
|
|
||||||
// retrieve levelset
|
|
||||||
$skill = block_gradelevel_levelset::find_by_course($COURSE->id);
|
|
||||||
if(isset($skill)){
|
|
||||||
$defaults->attached_skill = $skill->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
parent::set_data($defaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function get_data()
|
|
||||||
{
|
|
||||||
$data = parent::get_data();
|
|
||||||
|
|
||||||
if(isset($data))
|
|
||||||
{
|
|
||||||
$this->save_data($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function save_data($data)
|
|
||||||
{
|
|
||||||
global $COURSE;
|
|
||||||
// retrieve levelset
|
|
||||||
|
|
||||||
if(isset($data->attached_skill))
|
|
||||||
{
|
|
||||||
$currentskill = block_gradelevel_levelset::find_by_course($COURSE->id);
|
|
||||||
if(isset($currentskill))
|
|
||||||
{
|
|
||||||
$currentskill->detach_course($COURSE->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$skill = block_gradelevel_levelset::find_by_id($data->attached_skill);
|
|
||||||
if(isset($skill)){
|
|
||||||
$skill->attach_course($COURSE->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
<?php
|
|
||||||
$string['pluginname'] = 'Grade Levelup';
|
|
||||||
$string['gradelevel'] = 'GradeLevel';
|
|
||||||
$string['title'] = 'Progress level';
|
|
||||||
$string['gradelevel:addinstance'] = 'Add a new Grade Level block';
|
|
||||||
$string['gradelevel:myaddinstance'] = 'Add a new Grade Level block to the My Moodle page';
|
|
||||||
$string['blockstring'] = 'Text in the block';
|
|
||||||
$string['levelup_at'] = 'Progress: ';
|
|
||||||
$string['levelup_done'] = 'Complete';
|
|
||||||
$string['unattached_course'] = 'Please attach this course to a skill in the block settings';
|
|
||||||
|
|
||||||
$string['teacher_view_results'] = 'View student results';
|
|
||||||
|
|
||||||
$string['edit_pickskill'] = "Attach to skill";
|
|
||||||
$string['edit_noneskill'] = "None";
|
|
||||||
|
|
||||||
$string['cfgpage_generic'] = "Grade Level settings";
|
|
||||||
$string['cfgpage_globallevels'] = "Default levels";
|
|
||||||
$string['cfgpage_skilllevels'] = "Edit levels";
|
|
||||||
$string['cfgpage_skills'] = "Manage skills";
|
|
||||||
$string['cfgpage_editskill'] = "Edit skill";
|
|
||||||
|
|
||||||
$string['results_heading'] = "Results for skill ";
|
|
||||||
$string['results_ungrouped'] = "Other";
|
|
||||||
|
|
||||||
$string['descconfig'] = "Configuration for Grade Level block";
|
|
||||||
|
|
||||||
$string['labeltitle'] = "Title of gradelevel block";
|
|
||||||
$string['desctitle'] = "The title of the gradelevel block in the courses";
|
|
||||||
|
|
||||||
$string['labelshowtitle'] = "Show title bar in block";
|
|
||||||
$string['descshowtitle'] = "Whether the block should show a title bar or not";
|
|
||||||
|
|
||||||
|
|
||||||
$string['labelnumlevels'] = "Number of deault levels";
|
|
||||||
$string['descnumlevels'] = "The number of levels that is set by default for all skills";
|
|
||||||
|
|
||||||
$string['levelcfg_description'] = "Levels will be sorted based on points. Make sure to set the points incrementally. Leave points empty to remove level";
|
|
||||||
$string['levelcfg_head_points'] = "Points";
|
|
||||||
$string['levelcfg_head_color'] = "Medal color";
|
|
||||||
$string['levelcfg_addlevel'] = "Add level";
|
|
||||||
|
|
||||||
$string['tooltip_editicon'] = "Edit icon";
|
|
||||||
$string['tooltip_editname'] = "Edit name";
|
|
||||||
$string['tooltip_deleteskill'] = "Delete skill";
|
|
||||||
$string['tooltip_deleteskill_disabled'] = "Cannot delete skill, because there are attached courses";
|
|
||||||
|
|
||||||
$string['defaults_name'] = "New skill";
|
|
||||||
$string['cfg_resetlevels'] = "Reset levels to default";
|
|
||||||
$string['cfg_addskill'] = "Add skill";
|
|
||||||
|
|
||||||
$string['title_confirmdelete'] = "Confirm delete";
|
|
||||||
$string['dialog_confirmdeleteskill'] = "Are you sure you want to delete this skill?";
|
|
||||||
//$string[''] = "";
|
|
6
lang/en/block_mytreestudyplan.php
Normal file
6
lang/en/block_mytreestudyplan.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
$string['pluginname'] = 'My Treestudyplan';
|
||||||
|
$string['mytreestudyplan'] = 'MyTreestudyplan';
|
||||||
|
$string['title'] = 'My Studyplan';
|
||||||
|
$string['mytreestudyplan:addinstance'] = 'Add my studyplan block';
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
<?php
|
|
||||||
$string['pluginname'] = 'Cijferniveaus';
|
|
||||||
$string['gradelevel'] = 'GradeLevel';
|
|
||||||
$string['title'] = 'Voortgang Level';
|
|
||||||
$string['gradelevel:addinstance'] = 'Voeg een GradeLevel block toe';
|
|
||||||
$string['gradelevel:myaddinstance'] = 'Voeg een GradeLevel block aan mijn moodle toe';
|
|
||||||
$string['blockstring'] = 'Tekst in het blok';
|
|
||||||
$string['levelup_at'] = 'Voortgang: ';
|
|
||||||
$string['levelup_done'] = 'Klaar';
|
|
||||||
$string['unattached_course'] = 'Koppel deze cursus aan een skill in de eigenschappen van het blok.';
|
|
||||||
|
|
||||||
$string['teacher_view_results'] = 'Bekijk resultaten studenten';
|
|
||||||
|
|
||||||
$string['edit_pickskill'] = "Koppelen aan skill";
|
|
||||||
$string['edit_noneskill'] = "Geen";
|
|
||||||
|
|
||||||
$string['cfgpage_generic'] = "GradeLevel instellingen";
|
|
||||||
$string['cfgpage_globallevels'] = "Standaard levels";
|
|
||||||
$string['cfgpage_skilllevels'] = "Levels aanpassen";
|
|
||||||
$string['cfgpage_skills'] = "Skills beheren";
|
|
||||||
$string['cfgpage_editskill'] = "Skill aanpassen";
|
|
||||||
|
|
||||||
$string['results_heading'] = "Resultaten voor ";
|
|
||||||
$string['results_ungrouped'] = "Overig";
|
|
||||||
|
|
||||||
$string['descconfig'] = "Instellingen voor GradeLevel blok";
|
|
||||||
|
|
||||||
$string['labeltitle'] = "Titel van het gradelevel blok";
|
|
||||||
$string['desctitle'] = "De titel van het blok in de cursus";
|
|
||||||
|
|
||||||
$string['labelshowtitle'] = "Laat titelbalk in het blok zien";
|
|
||||||
$string['descshowtitle'] = "Geef aan of wel of niet de titel van het blok moet worden getoond";
|
|
||||||
|
|
||||||
$string['levelcfg_description'] = "Levels worden na opslaan gesorteerd op punten. Laat aantel punten leeg om een level te verwijderen";
|
|
||||||
$string['levelcfg_head_points'] = "Punten";
|
|
||||||
$string['levelcfg_head_color'] = "Badgekleur";
|
|
||||||
$string['levelcfg_addlevel'] = "Level toevoegen";
|
|
||||||
|
|
||||||
$string['tooltip_editicon'] = "Icoon aanpassen";
|
|
||||||
$string['tooltip_editname'] = "Naam aanpassen";
|
|
||||||
$string['tooltip_deleteskill'] = "Skill verwijderen";
|
|
||||||
$string['tooltip_deleteskill_disabled'] = "Skill kan niet worden verwijderd, omdat er cursussen aan gekoppeld zijn.";
|
|
||||||
|
|
||||||
$string['defaults_name'] = "Nieuwe skill";
|
|
||||||
$string['cfg_resetlevels'] = "Reset levels naar standaard";
|
|
||||||
$string['cfg_addskill'] = "Skill toevoegen";
|
|
||||||
|
|
||||||
$string['title_confirmdelete'] = "Bevestig verwijderen";
|
|
||||||
$string['dialog_confirmdeleteskill'] = "Week je zeker dat je deze skill witl verwijderen?";
|
|
||||||
//$string[''] = "";
|
|
6
lang/nl/block_mytreestudyplan.php
Normal file
6
lang/nl/block_mytreestudyplan.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
$string['pluginname'] = 'Mijn Treestudyplan';
|
||||||
|
$string['mytreestudyplan'] = 'MyTreestudyplan';
|
||||||
|
$string['title'] = 'Mijn Studieplan';
|
||||||
|
$string['mytreestudyplan:addinstance'] = 'Voeg mijn studieplan block toe';
|
||||||
|
|
3
lib.php
3
lib.php
|
@ -1,4 +1 @@
|
||||||
<?php
|
<?php
|
||||||
require_once($CFG->libdir.'/gradelib.php');
|
|
||||||
require_once($CFG->dirroot.'/grade/querylib.php');
|
|
||||||
|
|
||||||
|
|
3
package-lock.json
generated
3
package-lock.json
generated
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"lockfileVersion": 1
|
|
||||||
}
|
|
2601
pix/brokenbadge.svg
2601
pix/brokenbadge.svg
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 92 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB |
|
@ -1,772 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="25mm"
|
|
||||||
height="25mm"
|
|
||||||
viewBox="0 0 25.000001 25"
|
|
||||||
version="1.1"
|
|
||||||
id="svg11763"
|
|
||||||
inkscape:version="0.92.1 r15371"
|
|
||||||
sodipodi:docname="base.svg">
|
|
||||||
<defs
|
|
||||||
id="defs11757">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient26476"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
id="stop26472"
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#f0f0f0;stop-opacity:1" />
|
|
||||||
<stop
|
|
||||||
id="stop26474"
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#a6a6a6;stop-opacity:1" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient7518"
|
|
||||||
inkscape:collect="always">
|
|
||||||
<stop
|
|
||||||
id="stop7514"
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#fbfbfb;stop-opacity:0.31764707" />
|
|
||||||
<stop
|
|
||||||
id="stop7516"
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#ffffff;stop-opacity:0.1255814" />
|
|
||||||
</linearGradient>
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12749"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12765"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12781"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12797"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12813"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12829"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12845"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12861"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12877"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12893"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="Arrow2Mend"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path8574"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker12913"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path12911"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker12917"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path12915"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient12919"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker12937"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path12935"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<radialGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient26476"
|
|
||||||
id="radialGradient13236"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
cx="50"
|
|
||||||
cy="92"
|
|
||||||
fx="50"
|
|
||||||
fy="92"
|
|
||||||
r="15.5" />
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient7518"
|
|
||||||
id="linearGradient13238"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="translate(-35.116754,0.0704092)"
|
|
||||||
x1="80"
|
|
||||||
y1="98"
|
|
||||||
x2="87.273346"
|
|
||||||
y2="109.53979" />
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="Arrow2Mend-5"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path8574-9"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker13272"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path13270"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker13276"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path13274"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker13280"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path13278"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="marker13284"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path13282"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<marker
|
|
||||||
inkscape:stockid="Arrow2Mend"
|
|
||||||
orient="auto"
|
|
||||||
refY="0"
|
|
||||||
refX="0"
|
|
||||||
id="Arrow2Mend-2"
|
|
||||||
style="overflow:visible"
|
|
||||||
inkscape:isstock="true">
|
|
||||||
<path
|
|
||||||
id="path8574-2"
|
|
||||||
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:#f9f9f9;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
|
||||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
|
||||||
transform="scale(-0.6)"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</marker>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3314">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#dcdcdc;stop-opacity:1"
|
|
||||||
id="stop3316" />
|
|
||||||
<stop
|
|
||||||
offset="0.0729612"
|
|
||||||
style="stop-color:#e8e8e8;stop-opacity:1"
|
|
||||||
id="stop3322" />
|
|
||||||
<stop
|
|
||||||
offset="0.39346588"
|
|
||||||
style="stop-color:#e2e2e2;stop-opacity:1"
|
|
||||||
id="stop3324" />
|
|
||||||
<stop
|
|
||||||
offset="0.50066584"
|
|
||||||
style="stop-color:#bcbcbc;stop-opacity:1"
|
|
||||||
id="stop3326" />
|
|
||||||
<stop
|
|
||||||
offset="0.6425212"
|
|
||||||
style="stop-color:#dedede;stop-opacity:1"
|
|
||||||
id="stop3330" />
|
|
||||||
<stop
|
|
||||||
offset="0.94838297"
|
|
||||||
style="stop-color:#dddddd;stop-opacity:1"
|
|
||||||
id="stop3328" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#dcdcdc;stop-opacity:1"
|
|
||||||
id="stop3318" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3298">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#919191;stop-opacity:1"
|
|
||||||
id="stop3300" />
|
|
||||||
<stop
|
|
||||||
offset="0.30858582"
|
|
||||||
style="stop-color:#919191;stop-opacity:1"
|
|
||||||
id="stop3302" />
|
|
||||||
<stop
|
|
||||||
offset="0.51132685"
|
|
||||||
style="stop-color:#5c5c5c;stop-opacity:1"
|
|
||||||
id="stop3304" />
|
|
||||||
<stop
|
|
||||||
offset="0.69885707"
|
|
||||||
style="stop-color:#919191;stop-opacity:1"
|
|
||||||
id="stop3306" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#919191;stop-opacity:1"
|
|
||||||
id="stop3308" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3270">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#929295;stop-opacity:1"
|
|
||||||
id="stop3272" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#b9b9b9;stop-opacity:1"
|
|
||||||
id="stop3274" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3246">
|
|
||||||
<stop
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#007d12;stop-opacity:1"
|
|
||||||
id="stop3248" />
|
|
||||||
<stop
|
|
||||||
offset="0.46926689"
|
|
||||||
style="stop-color:#007d12;stop-opacity:1"
|
|
||||||
id="stop3254" />
|
|
||||||
<stop
|
|
||||||
offset="0.51132685"
|
|
||||||
style="stop-color:#5e7c62;stop-opacity:1"
|
|
||||||
id="stop3256" />
|
|
||||||
<stop
|
|
||||||
offset="0.5669955"
|
|
||||||
style="stop-color:#007d12;stop-opacity:1"
|
|
||||||
id="stop3258" />
|
|
||||||
<stop
|
|
||||||
offset="1"
|
|
||||||
style="stop-color:#007d12;stop-opacity:1"
|
|
||||||
id="stop3250" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient3246"
|
|
||||||
id="linearGradient3252"
|
|
||||||
y2="299.70178"
|
|
||||||
x2="849.7998"
|
|
||||||
y1="463.29184"
|
|
||||||
x1="153.0388" />
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient3270"
|
|
||||||
id="linearGradient3276"
|
|
||||||
y2="418.82431"
|
|
||||||
x2="241.64479"
|
|
||||||
y1="425.34058"
|
|
||||||
x1="171.59496" />
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient3270"
|
|
||||||
id="linearGradient3286"
|
|
||||||
y2="294.47226"
|
|
||||||
x2="755.3006"
|
|
||||||
y1="269.49326"
|
|
||||||
x1="830.32367" />
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient3298"
|
|
||||||
id="linearGradient3296"
|
|
||||||
y2="450.36261"
|
|
||||||
x2="896.48633"
|
|
||||||
y1="600.70026"
|
|
||||||
x1="197.66" />
|
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
xlink:href="#linearGradient3314"
|
|
||||||
id="linearGradient3320"
|
|
||||||
y2="265.29617"
|
|
||||||
x2="780.50598"
|
|
||||||
y1="396.72012"
|
|
||||||
x1="233.33572" />
|
|
||||||
<filter
|
|
||||||
id="filter3587">
|
|
||||||
<feGaussianBlur
|
|
||||||
inkscape:collect="always"
|
|
||||||
stdDeviation="9.2928517"
|
|
||||||
id="feGaussianBlur3589" />
|
|
||||||
</filter>
|
|
||||||
<filter
|
|
||||||
id="filter3631">
|
|
||||||
<feGaussianBlur
|
|
||||||
inkscape:collect="always"
|
|
||||||
stdDeviation="14.191705"
|
|
||||||
id="feGaussianBlur3633" />
|
|
||||||
</filter>
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="1.979899"
|
|
||||||
inkscape:cx="125.57529"
|
|
||||||
inkscape:cy="10.242677"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:pagecheckerboard="true"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="1672"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
showguides="false">
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid14028"
|
|
||||||
units="mm"
|
|
||||||
spacingx="1"
|
|
||||||
spacingy="1"
|
|
||||||
dotted="true"
|
|
||||||
empspacing="5" />
|
|
||||||
<inkscape:grid
|
|
||||||
type="xygrid"
|
|
||||||
id="grid14036" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<metadata
|
|
||||||
id="metadata11760">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-96.700309,-96.926329)">
|
|
||||||
<g
|
|
||||||
inkscape:transform-center-y="2.0000018"
|
|
||||||
inkscape:transform-center-x="1.7354122"
|
|
||||||
id="use5329"
|
|
||||||
transform="matrix(204.05634,0,0,204.05634,-135784.74,75153.402)">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect12450"
|
|
||||||
width="4"
|
|
||||||
height="11"
|
|
||||||
x="273.52917"
|
|
||||||
y="-149" />
|
|
||||||
<rect
|
|
||||||
y="-146"
|
|
||||||
x="277.52917"
|
|
||||||
height="5"
|
|
||||||
width="3"
|
|
||||||
id="rect12452"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="m 281,-145.00002 5,2e-5 v 0.47083 h 2 V -144 h 5 v 1 h -5 v 0.52917 h -2 V -142 l -5,-2e-5 z"
|
|
||||||
id="path12454"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ccccccccccccc" />
|
|
||||||
<g
|
|
||||||
id="g12460"
|
|
||||||
transform="translate(0.52916667,-2)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path12456"
|
|
||||||
d="m 287.99999,-140.47083 v 2 H 290 Z"
|
|
||||||
style="fill:#ffffff;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
y="-138"
|
|
||||||
x="288"
|
|
||||||
height="7"
|
|
||||||
width="2"
|
|
||||||
id="rect12458"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
inkscape:transform-center-y="2.0000018"
|
|
||||||
inkscape:transform-center-x="1.7354122"
|
|
||||||
id="use5329-5"
|
|
||||||
transform="matrix(204.05634,0,0,204.05634,-135784.74,75153.402)">
|
|
||||||
<rect
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="rect12508"
|
|
||||||
width="4"
|
|
||||||
height="11"
|
|
||||||
x="273.52917"
|
|
||||||
y="-149" />
|
|
||||||
<rect
|
|
||||||
y="-146"
|
|
||||||
x="277.52917"
|
|
||||||
height="5"
|
|
||||||
width="3"
|
|
||||||
id="rect12510"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="m 281,-145.00002 5,2e-5 v 0.47083 h 2 V -144 h 5 v 1 h -5 v 0.52917 h -2 V -142 l -5,-2e-5 z"
|
|
||||||
id="path12512"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="ccccccccccccc" />
|
|
||||||
<g
|
|
||||||
id="g12518"
|
|
||||||
transform="translate(0.52916667,-2)">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path12514"
|
|
||||||
d="m 287.99999,-140.47083 v 2 H 290 Z"
|
|
||||||
style="fill:#ffffff;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<rect
|
|
||||||
y="-138"
|
|
||||||
x="288"
|
|
||||||
height="7"
|
|
||||||
width="2"
|
|
||||||
id="rect12516"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="use26239"
|
|
||||||
transform="translate(41252296,-26435496)">
|
|
||||||
<g
|
|
||||||
transform="matrix(157375.71,0,0,157375.71,-87067038,35086817)"
|
|
||||||
id="g13228">
|
|
||||||
<circle
|
|
||||||
style="opacity:1;fill:url(#radialGradient13236);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="circle13220"
|
|
||||||
cx="45"
|
|
||||||
cy="97"
|
|
||||||
r="15" />
|
|
||||||
<path
|
|
||||||
style="opacity:1;fill:url(#linearGradient13238);fill-opacity:1;stroke:none;stroke-width:0.97674406;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
d="m 58.593623,92.350616 c 2.385905,6.962784 -0.972423,14.538754 -7.252029,17.704604 -6.581851,3.31823 -14.445868,1.16906 -18.535439,-4.95045"
|
|
||||||
id="path13222"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
inkscape:transform-center-x="-1.0852379"
|
|
||||||
inkscape:transform-center-y="4.9804617"
|
|
||||||
sodipodi:nodetypes="csc" />
|
|
||||||
<circle
|
|
||||||
r="15"
|
|
||||||
cy="97"
|
|
||||||
cx="45"
|
|
||||||
id="circle13224"
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#ebebeb;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
sodipodi:open="true"
|
|
||||||
d="m 44.897568,82.00035 a 15,15 0 0 1 14.369022,10.36668 15,15 0 0 1 -5.536793,16.83095 15,15 0 0 1 -17.71726,-0.18859"
|
|
||||||
sodipodi:end="2.2132531"
|
|
||||||
sodipodi:start="4.7055601"
|
|
||||||
sodipodi:ry="15"
|
|
||||||
sodipodi:rx="15"
|
|
||||||
sodipodi:cy="97"
|
|
||||||
sodipodi:cx="45"
|
|
||||||
sodipodi:type="arc"
|
|
||||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#d3d3d3;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
|
||||||
id="path13226" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
id="g13232">
|
|
||||||
<g
|
|
||||||
transform="matrix(3.7795276,0,0,3.7795276,-2219.735,1371.8767)"
|
|
||||||
id="use13230"
|
|
||||||
inkscape:transform-center-x="0.99999954"
|
|
||||||
inkscape:transform-center-y="0.60193146">
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458332"
|
|
||||||
x="240"
|
|
||||||
y="-105"
|
|
||||||
id="text13242"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan13240"
|
|
||||||
x="240"
|
|
||||||
y="-105"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.28888893px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffffff;stroke:#ffffff;stroke-width:0.26458332">M</tspan></text>
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cccc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path13244"
|
|
||||||
d="m 258,-101 -3,4 h 6 z"
|
|
||||||
style="fill:#ffffff;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<circle
|
|
||||||
r="2"
|
|
||||||
cy="-99"
|
|
||||||
cx="241"
|
|
||||||
id="circle13246"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path13248"
|
|
||||||
d="m 237,-101.47083 h 24"
|
|
||||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path13250"
|
|
||||||
d="m 249,-100 v 7"
|
|
||||||
style="fill:none;stroke:#f9f9f9;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)" />
|
|
||||||
<text
|
|
||||||
id="text13256"
|
|
||||||
y="-91.737373"
|
|
||||||
x="250.36359"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-size:3.52777767px;fill:#ffffff;stroke-width:0.26458332"
|
|
||||||
y="-91.737373"
|
|
||||||
x="250.36359"
|
|
||||||
id="tspan13254"
|
|
||||||
sodipodi:role="line">F<tspan
|
|
||||||
id="tspan13252"
|
|
||||||
style="font-size:1.41111112px;fill:#ffffff">Z</tspan></tspan></text>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="matrix(204.05634,0,0,204.05634,-135917.88,75008.797)"
|
|
||||||
id="use5478"
|
|
||||||
inkscape:transform-center-x="0.99999954"
|
|
||||||
inkscape:transform-center-y="0.60193146">
|
|
||||||
<text
|
|
||||||
xml:space="preserve"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458332"
|
|
||||||
x="240"
|
|
||||||
y="-105"
|
|
||||||
id="text13402"><tspan
|
|
||||||
sodipodi:role="line"
|
|
||||||
id="tspan13400"
|
|
||||||
x="240"
|
|
||||||
y="-105"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.28888893px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffffff;stroke:#ffffff;stroke-width:0.26458332">M</tspan></text>
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cccc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path13404"
|
|
||||||
d="m 258,-101 -3,4 h 6 z"
|
|
||||||
style="fill:#ffffff;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<circle
|
|
||||||
r="2"
|
|
||||||
cy="-99"
|
|
||||||
cx="241"
|
|
||||||
id="circle13406"
|
|
||||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path13408"
|
|
||||||
d="m 237,-101.47083 h 24"
|
|
||||||
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path13410"
|
|
||||||
d="m 249,-100 v 7"
|
|
||||||
style="fill:none;stroke:#f9f9f9;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)" />
|
|
||||||
<text
|
|
||||||
id="text13416"
|
|
||||||
y="-91.737373"
|
|
||||||
x="250.36359"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-size:3.52777767px;fill:#ffffff;stroke-width:0.26458332"
|
|
||||||
y="-91.737373"
|
|
||||||
x="250.36359"
|
|
||||||
id="tspan13414"
|
|
||||||
sodipodi:role="line">F<tspan
|
|
||||||
id="tspan13412"
|
|
||||||
style="font-size:1.41111112px;fill:#ffffff">Z</tspan></tspan></text>
|
|
||||||
</g>
|
|
||||||
<text
|
|
||||||
id="text26490"
|
|
||||||
y="108.77583"
|
|
||||||
x="98.945969"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.26458332"
|
|
||||||
xml:space="preserve"><tspan
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#ffffff;stroke:#ffffff;stroke-width:0.26458332"
|
|
||||||
y="108.77583"
|
|
||||||
x="98.945969"
|
|
||||||
id="tspan26488"
|
|
||||||
sodipodi:role="line">S</tspan></text>
|
|
||||||
<path
|
|
||||||
id="path4840"
|
|
||||||
d="m 116.70664,100.3512 c -0.14496,-0.002 -0.29126,0.006 -0.43659,0.01 -1.17718,0.0362 -2.33828,0.9636 -2.42672,2.18313 -0.29727,1.25439 -0.50828,2.57197 -1.15103,3.70509 -2.1609,2.16336 -4.48161,4.16303 -6.70887,6.25817 -0.90253,0.86304 -1.86084,1.67552 -2.6889,2.61168 -0.6963,1.00578 0.0217,2.73204 1.30443,2.72455 1.01064,-0.0331 1.59865,-1.0163 2.25453,-1.64313 2.44276,-2.6581 4.68431,-5.49976 7.19592,-8.09519 0.66341,-0.54689 1.58373,-0.59881 2.3884,-0.81925 0.54078,-0.13455 1.11301,-0.17869 1.63466,-0.36816 0.9358,-0.59434 1.60138,-1.6614 1.70207,-2.76612 0.0333,-0.26301 -0.26095,-0.18064 -0.26095,-0.18064 l -1.62107,0.74703 -1.23842,-1.02247 -0.20786,-1.15326 c 0,0 0.37664,-0.37309 0.54518,-0.40539 l 1.59106,-0.59363 c -0.0633,-0.65793 -0.8946,-0.98875 -1.44713,-1.1386 -0.14025,-0.0381 -0.28388,-0.0511 -0.42884,-0.0536 z m -1.20876,4.4606 0.72444,1.71223 -0.65567,0.26423 -0.0142,-0.0329 0.17926,-0.0746 -0.0342,-0.082 0.0375,-0.009 0.0862,-0.0193 -0.0386,-0.17219 -0.086,0.0191 -0.068,0.0152 -0.0859,-0.20546 0.0367,-0.009 0.0862,-0.0193 -0.0384,-0.1722 -0.0862,0.0192 -0.0674,0.015 -0.0859,-0.20563 0.0362,-0.008 0.0862,-0.0192 -0.0386,-0.17236 -0.086,0.0193 -0.0667,0.015 -0.0859,-0.20581 0.0353,-0.008 0.0862,-0.0191 -0.0384,-0.17236 -0.0862,0.0193 -0.0661,0.0149 -0.11963,-0.28682 c -0.12696,0.0512 -0.13397,0.0554 -0.19581,0.081 l -0.0148,-0.0347 c 0.22143,-0.0893 0.44287,-0.17845 0.66429,-0.26768 z m -1.15554,0.46556 0.0168,0.0393 c -0.0598,0.0247 -0.0613,0.0265 -0.17426,0.072 l 0.0576,0.13702 -0.0298,0.007 -0.0862,0.0193 0.0386,0.17218 0.086,-0.0193 0.0609,-0.0136 0.0865,0.20563 -0.0302,0.007 -0.0862,0.0193 0.0384,0.1722 0.0862,-0.0193 0.0612,-0.0136 0.0863,0.20546 -0.0305,0.007 -0.0862,0.0193 0.0386,0.17219 0.086,-0.0191 0.0617,-0.0138 0.0863,0.20545 -0.0308,0.007 -0.0862,0.0193 0.0384,0.1722 0.0862,-0.0192 0.0621,-0.0138 0.0978,0.23252 0.18598,-0.0774 0.0117,0.0273 -0.61448,0.24751 -0.7241,-1.71222 c 0.20185,-0.0814 0.40366,-0.16274 0.60552,-0.24406 z m -9.51337,9.71898 a 1.0178768,1.0178768 0 0 1 1.01779,1.01797 1.0178768,1.0178768 0 0 1 -1.01779,1.01779 1.0178768,1.0178768 0 0 1 -1.01779,-1.01779 1.0178768,1.0178768 0 0 1 1.01779,-1.01797 z"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
style="fill:#ffffff;stroke-width:0.08825012" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 31 KiB |
38
settings.php
38
settings.php
|
@ -1,40 +1,2 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$ADMIN->add('blocksettings', new admin_category('block_gradelevel', get_string('cfgpage_generic', 'block_gradelevel')));
|
|
||||||
|
|
||||||
|
|
||||||
$settings->add(new admin_setting_configcheckbox(
|
|
||||||
'gradelevel/showtitle',
|
|
||||||
get_string('labelshowtitle', 'block_gradelevel'),
|
|
||||||
get_string('descshowtitle', 'block_gradelevel'),
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
$settings->add(new admin_setting_configtext(
|
|
||||||
'gradelevel/blocktitle',
|
|
||||||
get_string('labeltitle', 'block_gradelevel'),
|
|
||||||
get_string('desctitle', 'block_gradelevel'),
|
|
||||||
get_string('title', 'block_gradelevel')
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
$ADMIN->add("block_gradelevel", $settings);
|
|
||||||
|
|
||||||
// Add the default levels page
|
|
||||||
$ADMIN->add("block_gradelevel", new admin_externalpage(
|
|
||||||
'block_gradelevel_default_levels',
|
|
||||||
get_string('cfgpage_globallevels', 'block_gradelevel'),
|
|
||||||
$CFG->wwwroot . '/blocks/gradelevel/cfg_globallevels.php'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add the skill configpage
|
|
||||||
$ADMIN->add("block_gradelevel", new admin_externalpage(
|
|
||||||
'block_gradelevel_config_skills',
|
|
||||||
get_string('cfgpage_skills', 'block_gradelevel'),
|
|
||||||
$CFG->wwwroot . '/blocks/gradelevel/cfg_skills.php'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
$settings = null;
|
|
149
styles.css
149
styles.css
|
@ -1,145 +1,10 @@
|
||||||
figure.levelbadge, figure.dummybadge {
|
/* stylelint-disable length-zero-no-unit, color-hex-case, color-hex-length*/
|
||||||
text-align: center;
|
|
||||||
|
.path-block-mytreestudyplan [v-cloak] {
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.pointinfo {
|
.path-block-mytreestudyplan .vue-loader {
|
||||||
text-align: center;
|
width: 32px;
|
||||||
font-family: "Open Sans", Arial, helvetica, sans-serif;
|
margin: auto;
|
||||||
}
|
|
||||||
|
|
||||||
div.pointinfo.complete {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.pointinfo span.currentpoints {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.pointinfo span.leveluppoints {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.teachermode {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.block_gradelevel_addlevel {
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
}
|
|
||||||
input.jscolor[type=text] {
|
|
||||||
width: 5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
div.skill_set ul {
|
|
||||||
padding-left: 0px;
|
|
||||||
margin-left: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.skill_set li.skill_info {
|
|
||||||
position: relative; /* needed to have absolute positions be relative to this li */
|
|
||||||
list-style: none;
|
|
||||||
display: inline-block;
|
|
||||||
width: 220px;
|
|
||||||
height: 220px;
|
|
||||||
border-color: #ccc;
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
margin: 5px;
|
|
||||||
padding: 5px;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
div.skill_set li.skill_info figcaption {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.skill_set li.skill_info input[type=text] {
|
|
||||||
width: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.skill_set li.skill_info a.editicon {
|
|
||||||
position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.skill_set li.skill_info a.deleteskill {
|
|
||||||
position: absolute;
|
|
||||||
top: 5px;
|
|
||||||
left: 7px;
|
|
||||||
}
|
|
||||||
div.skill_set li.skill_info a.deleteskill i.icon {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.skill_set li.skill_info a.deleteskill i.icon.disabled {
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.skill_set li.skill_info a.editname {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.level_config tr[data-rowid='-255'] {
|
|
||||||
}
|
|
||||||
|
|
||||||
table.level_config tr[data-rowid='-255'] td {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
table.level_config tr[data-rowid='-255'] input[data-name='points'] {
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.block_gradelevel_results ul {
|
|
||||||
padding-left: 0px;
|
|
||||||
margin-left: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div .block_gradelevel_results li.result_badge {
|
|
||||||
position: relative; /* needed to have absolute positions be relative to this li */
|
|
||||||
list-style: none;
|
|
||||||
display: inline-block;
|
|
||||||
width: 190px;
|
|
||||||
height: 210px;
|
|
||||||
border-color: #ccc;
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
margin: 5px;
|
|
||||||
padding: 5px;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
div.block_gradelevel_results li.result_badge figcaption {
|
|
||||||
text-align: center;
|
|
||||||
height: 3em;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.block_gradelevel_results li.result_badge div.pointinfo {
|
|
||||||
font-size: 85%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.block_gradelevel_results li.result_badge figcaption span.namepart {
|
|
||||||
break-inside: avoid;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.block_gradelevel_results figure.levelset_icon {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure.levelset_icon {
|
|
||||||
background-color: #ccc;
|
|
||||||
background-image: -moz-linear-gradient(45deg, #aaa 25%, transparent 25%), -moz-linear-gradient(-45deg, #aaa 25%, transparent 25%), -moz-linear-gradient(45deg, transparent 75%, #aaa 75%), -moz-linear-gradient(-45deg, transparent 75%, #aaa 75%);
|
|
||||||
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #aaa), color-stop(.25, transparent)), -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #aaa), color-stop(.25, transparent)), -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #aaa)), -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #aaa));
|
|
||||||
-moz-background-size: 32px 32px;
|
|
||||||
background-size: 32px 33px;
|
|
||||||
-webkit-background-size: 32px 33px; /* override value for shitty webkit */
|
|
||||||
background-position: 0 0, 16px 0, 16px -16px, 0px 16px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
51
templates/block.mustache
Normal file
51
templates/block.mustache
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{{!
|
||||||
|
This file is part of Moodle - https://moodle.org/
|
||||||
|
|
||||||
|
Moodle is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Moodle is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
}}
|
||||||
|
{{!
|
||||||
|
@template plugintype_pluginname/template_name
|
||||||
|
|
||||||
|
Template purpose and description.
|
||||||
|
|
||||||
|
Classes required for JS:
|
||||||
|
* none
|
||||||
|
|
||||||
|
Data attributes required for JS:
|
||||||
|
* none
|
||||||
|
|
||||||
|
Context variables required for this template:
|
||||||
|
* none
|
||||||
|
|
||||||
|
Example context (json):
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
<div id='block_mytreestudyplan' class='path-local-treestudyplan'>
|
||||||
|
<div class='vue-loader' v-show='false'>
|
||||||
|
<div class='spinner-border text-primary' role='status'>
|
||||||
|
<span class='sr-only'>Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-cloak>
|
||||||
|
{{^teachermode}}
|
||||||
|
<r-report v-model='studyplans'></r-report>
|
||||||
|
{{/teachermode}}
|
||||||
|
{{#teachermode}}
|
||||||
|
<r-report v-model='studyplans' teachermode></r-report>
|
||||||
|
{{/teachermode}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
10
version.php
10
version.php
|
@ -1,4 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
$plugin->component = 'block_gradelevel'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
|
$plugin->component = 'block_mytreestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494)
|
||||||
$plugin->version = 2019100900; // YYYYMMDDHH (year, month, day, iteration)
|
$plugin->version = 2022061600; // YYYYMMDDHH (year, month, day, iteration)
|
||||||
$plugin->requires = 2018050800; // YYYYMMDDHH (This is the release version for Moodle 3.5)
|
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11)
|
||||||
|
|
||||||
|
$plugin->dependencies = [
|
||||||
|
'local_treestudyplan' => 2022061100,
|
||||||
|
];
|
|
@ -1,49 +0,0 @@
|
||||||
<?php
|
|
||||||
//header("Content-type: image/svg+xml");
|
|
||||||
//ob_start();
|
|
||||||
require_once("../../config.php");
|
|
||||||
|
|
||||||
global $CFG;
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
$skillid = required_param('skillid', PARAM_INT);
|
|
||||||
$skill = $DB->get_record('block_gradelevel_levelset', array('id' => $skillid));
|
|
||||||
|
|
||||||
if(is_object($skill))
|
|
||||||
{
|
|
||||||
$image = $skill->icon;
|
|
||||||
|
|
||||||
if(strncmp($image,"data:",5) == 0)
|
|
||||||
{
|
|
||||||
$parts = explode(",",ltrim(substr($image,5)),2);
|
|
||||||
$typeinfo = explode(";",$parts[0]);
|
|
||||||
if(count($typeinfo) > 1 && $typeinfo[1] == "base64")
|
|
||||||
{
|
|
||||||
$binary = base64_decode($parts[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$binary = $parts[0];
|
|
||||||
}
|
|
||||||
$mime = $typeinfo[0];
|
|
||||||
|
|
||||||
// set header
|
|
||||||
header("Content-type: {$mime}");
|
|
||||||
header("Pragma:");
|
|
||||||
// Allow cache for 5 seconds
|
|
||||||
header("Cache-Control: public, max-age=5");
|
|
||||||
// print data
|
|
||||||
print $binary;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// redirect to specified url
|
|
||||||
header("Location: {$image}",true,302);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
http_response_code(404);
|
|
||||||
print "Image not found";
|
|
||||||
}
|
|
107
view-results.php
107
view-results.php
|
@ -1,107 +0,0 @@
|
||||||
<?php
|
|
||||||
require_once("../../config.php");
|
|
||||||
|
|
||||||
global $DB;
|
|
||||||
global $CFG;
|
|
||||||
|
|
||||||
const BADGE_SIZE = 100;
|
|
||||||
|
|
||||||
// Do sanity and access checks on course
|
|
||||||
$courseid = required_param('courseid', PARAM_INT);
|
|
||||||
$COURSE = get_course($courseid);
|
|
||||||
$coursecontext = context_course::instance($courseid);
|
|
||||||
$skill = block_gradelevel_levelset::find_by_course($courseid);
|
|
||||||
|
|
||||||
require_login($COURSE);
|
|
||||||
require_capability('block/gradelevel:viewresults', $coursecontext);
|
|
||||||
|
|
||||||
|
|
||||||
$PAGE->set_url('/blocks/gradelevel/view-results.php', array('courseid' => $courseid));
|
|
||||||
$PAGE->set_pagelayout('standard');
|
|
||||||
|
|
||||||
$PAGE->requires->js_call_amd('block_gradelevel/renderbadge', 'init');
|
|
||||||
|
|
||||||
print $OUTPUT->header();
|
|
||||||
print $OUTPUT->heading(get_string('results_heading', 'block_gradelevel') . " " . $skill->getName());
|
|
||||||
print "<p>".get_string('course', 'core')." " . $COURSE->fullname."</p>";
|
|
||||||
|
|
||||||
//retrieve groups
|
|
||||||
$course_groups = groups_get_all_groups($COURSE->id);
|
|
||||||
// retrieve users
|
|
||||||
$remaining_users = get_enrolled_users($coursecontext);
|
|
||||||
|
|
||||||
print "<div class='block_gradelevel_results'>";
|
|
||||||
if(count($course_groups > 0))
|
|
||||||
{
|
|
||||||
// loop through all groups first
|
|
||||||
foreach($course_groups as $grp)
|
|
||||||
{
|
|
||||||
// Get members
|
|
||||||
$members = get_enrolled_users($coursecontext,'mod/assignment:submit',$grp->id);
|
|
||||||
$count_members = count($members);
|
|
||||||
|
|
||||||
// show group name
|
|
||||||
print $OUTPUT->heading($grp->name." ({$count_members})",4,array('groupname'));
|
|
||||||
|
|
||||||
// Sort on last name
|
|
||||||
usort( $members, function( $a, $b) {
|
|
||||||
return ( $a->lastname < $b->lastname ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
print "<ul class='skill_results'>";
|
|
||||||
foreach($members as $usr)
|
|
||||||
{
|
|
||||||
$pointstotal = round($skill->get_levelset_grade($usr->id),1);
|
|
||||||
$level_info = $skill->calculate_level($pointstotal);
|
|
||||||
|
|
||||||
print "<li class='result_badge'>";
|
|
||||||
print $skill->render_badge($pointstotal,BADGE_SIZE);
|
|
||||||
print "<figcaption><span class='namepart'>{$usr->firstname}</span> <span class='namepart'>{$usr->lastname}</span></figcaption>";
|
|
||||||
|
|
||||||
if($level_info->levelup_total > 0)
|
|
||||||
{
|
|
||||||
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$pointstotal}</span>/<span class='leveluppoints'>{$level_info->next_at}</span></div>";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print "<div class='pointinfo complete'>".get_string('levelup_done','block_gradelevel')."</div>";
|
|
||||||
}
|
|
||||||
|
|
||||||
print "</li>";
|
|
||||||
unset($remaining_users[$usr->id]);
|
|
||||||
}
|
|
||||||
print "</ul>";
|
|
||||||
}
|
|
||||||
|
|
||||||
$count_members = count($remaining_users);
|
|
||||||
print $OUTPUT->heading(get_string('results_ungrouped','block_gradelevel')." ({$count_members})" ,4,array('groupname'));
|
|
||||||
|
|
||||||
}
|
|
||||||
usort( $remaining_users, function( $a, $b) {
|
|
||||||
return ( $a->lastname < $b->lastname ) ? -1 : 1;
|
|
||||||
} );
|
|
||||||
|
|
||||||
print "<ul class='skill_results other'>";
|
|
||||||
foreach($remaining_users as $usr)
|
|
||||||
{
|
|
||||||
$pointstotal = round($skill->get_levelset_grade($usr->id),1);
|
|
||||||
$level_info = $skill->calculate_level($pointstotal);
|
|
||||||
print "<li class='result_badge'>";
|
|
||||||
print $skill->render_badge($pointstotal,BADGE_SIZE);
|
|
||||||
print "<figcaption><span class='namepart'>{$usr->firstname}</span> <span class='namepart'>{$usr->lastname}</span></figcaption>";
|
|
||||||
if($level_info->levelup_total > 0)
|
|
||||||
{
|
|
||||||
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$pointstotal}</span>/<span class='leveluppoints'>{$level_info->next_at}</span></div>";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print "<div class='pointinfo complete'>".get_string('levelup_done','block_gradelevel')."</div>";
|
|
||||||
}
|
|
||||||
print "</li>";
|
|
||||||
|
|
||||||
}
|
|
||||||
print "</ul>";
|
|
||||||
|
|
||||||
print "</div>";
|
|
||||||
|
|
||||||
print $OUTPUT->footer();
|
|
Loading…
Reference in New Issue
Block a user