Implemented self enrol buttons
This commit is contained in:
parent
61256207be
commit
8382c4a117
26 changed files with 738 additions and 106 deletions
2
amd/build/report-viewer-components.min.js
vendored
2
amd/build/report-viewer-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/studyplan-editor-components.min.js
vendored
2
amd/build/studyplan-editor-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/studyplan-report-components.min.js
vendored
2
amd/build/studyplan-report-components.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
amd/build/util/date-helper.min.js
vendored
2
amd/build/util/date-helper.min.js
vendored
|
@ -1,3 +1,3 @@
|
||||||
define("local_treestudyplan/util/date-helper",["exports"],(function(_exports){function format_date(d,short){d instanceof Date||(d=new Date(d));let monthformat="short";return!0===short?monthformat="numeric":!1===short&&(monthformat="long"),d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})}function studyplanDates(plan){let earliestStart=null,latestEnd=null,openEnded=!1;for(const ix in plan.pages){const page=plan.pages[ix],s=new Date(page.startdate);if(page.enddate||(openEnded=!0),(!earliestStart||s<earliestStart)&&(earliestStart=s),page.enddate){const e=new Date(page.enddate);(!latestEnd||e>latestEnd)&&(latestEnd=e)}}return{start:earliestStart,end:openEnded?null:latestEnd}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_days=function(datestr,days){const date=new Date(datestr);return function(date){const d=new Date(date);let month=""+(d.getMonth()+1),day=""+d.getDate();const year=d.getFullYear();month.length<2&&(month="0"+month);day.length<2&&(day="0"+day);return[year,month,day].join("-")}(new Date(date.getTime()+864e5*days))},_exports.datespaninfo=function(first,last){first instanceof Date||(first=new Date(first));last instanceof Date||(last=new Date(last));first.setHours(0),first.setMinutes(0),first.setSeconds(0),first.setMilliseconds(0),last.setHours(23),last.setMinutes(59),last.setSeconds(59),last.setMilliseconds(999);const dayspan=Math.round((last-first+1)/864e5),years=Math.floor(dayspan/365),ydaysleft=dayspan%365,weeks=Math.floor(ydaysleft/7);return{first:first,last:last,totaldays:dayspan,years:years,weeks:weeks,days:ydaysleft%7,formatted:{first:format_date(first),last:format_date(last)}}},_exports.format_date=format_date,_exports.format_datetime=function(d,short){d instanceof Date||(d=new Date(d));let monthformat="short";!0===short?monthformat="numeric":!1===short&&(monthformat="long");return d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})+" "+d.toLocaleTimeString(document.documentElement.lang,{timeStyle:"short"})},_exports.studyplanDates=studyplanDates,_exports.studyplanPageTiming=function(page){const now=(new Date).getTime(),start=new Date(page.startdate),end=page.enddate?new Date(page.enddate):null;return start<now?end&&now>end?"past":"present":"future"},_exports.studyplanTiming=function(plan){const now=(new Date).getTime(),dates=studyplanDates(plan);return dates.start<now?dates.end&&now>dates.end?"past":"present":"future"}}));
|
define("local_treestudyplan/util/date-helper",["exports"],(function(_exports){function format_date(d,short){d instanceof Date||("number"==typeof d&&(d*=1e3),d=new Date(d));let monthformat="short";return!0===short?monthformat="numeric":!1===short&&(monthformat="long"),d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})}function studyplanDates(plan){let earliestStart=null,latestEnd=null,openEnded=!1;for(const ix in plan.pages){const page=plan.pages[ix],s=new Date(page.startdate);if(page.enddate||(openEnded=!0),(!earliestStart||s<earliestStart)&&(earliestStart=s),page.enddate){const e=new Date(page.enddate);(!latestEnd||e>latestEnd)&&(latestEnd=e)}}return{start:earliestStart,end:openEnded?null:latestEnd}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.add_days=function(datestr,days){const date=new Date(datestr);return function(date){const d=new Date(date);let month=""+(d.getMonth()+1),day=""+d.getDate();const year=d.getFullYear();month.length<2&&(month="0"+month);day.length<2&&(day="0"+day);return[year,month,day].join("-")}(new Date(date.getTime()+864e5*days))},_exports.datespaninfo=function(first,last){first instanceof Date||(first=new Date(first));last instanceof Date||(last=new Date(last));first.setHours(0),first.setMinutes(0),first.setSeconds(0),first.setMilliseconds(0),last.setHours(23),last.setMinutes(59),last.setSeconds(59),last.setMilliseconds(999);const dayspan=Math.round((last-first+1)/864e5),years=Math.floor(dayspan/365),ydaysleft=dayspan%365,weeks=Math.floor(ydaysleft/7);return{first:first,last:last,totaldays:dayspan,years:years,weeks:weeks,days:ydaysleft%7,formatted:{first:format_date(first),last:format_date(last)}}},_exports.format_date=format_date,_exports.format_datetime=function(d,short){d instanceof Date||("number"==typeof d&&(d*=1e3),d=new Date(d));let monthformat="short";!0===short?monthformat="numeric":!1===short&&(monthformat="long");return d.toLocaleDateString(document.documentElement.lang,{year:"numeric",month:monthformat,day:"numeric"})+" "+d.toLocaleTimeString(document.documentElement.lang,{timeStyle:"short"})},_exports.studyplanDates=studyplanDates,_exports.studyplanPageTiming=function(page){const now=(new Date).getTime(),start=new Date(page.startdate),end=page.enddate?new Date(page.enddate):null;return start<now?end&&now>end?"past":"present":"future"},_exports.studyplanTiming=function(plan){const now=(new Date).getTime(),dates=studyplanDates(plan);return dates.start<now?dates.end&&now>dates.end?"past":"present":"future"}}));
|
||||||
|
|
||||||
//# sourceMappingURL=date-helper.min.js.map
|
//# sourceMappingURL=date-helper.min.js.map
|
File diff suppressed because one or more lines are too long
2
amd/build/util/svgarc.min.js
vendored
2
amd/build/util/svgarc.min.js
vendored
|
@ -1,3 +1,3 @@
|
||||||
define("local_treestudyplan/util/svgarc",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.svgarcpath=_exports.svgarc=void 0;const cos=Math.cos,sin=Math.sin,π=Math.PI,f_matrix_times=(_ref,_ref2)=>{let[[a,b],[c,d]]=_ref,[x,y]=_ref2;return[a*x+b*y,c*x+d*y]},f_vec_add=(_ref3,_ref4)=>{let[a1,a2]=_ref3,[b1,b2]=_ref4;return[a1+b1,a2+b2]},svgarcpath=(_ref5,_ref6,_ref7,φ)=>{let[cx,cy]=_ref5,[rx,ry]=_ref6,[t1,Δ]=_ref7;Δ%=2*π;const rotMatrix=[[cos(x=φ),-sin(x)],[sin(x),cos(x)]];var x;const[sX,sY]=f_vec_add(f_matrix_times(rotMatrix,[rx*cos(t1),ry*sin(t1)]),[cx,cy]),[eX,eY]=f_vec_add(f_matrix_times(rotMatrix,[rx*cos(t1+Δ),ry*sin(t1+Δ)]),[cx,cy]);return"M "+sX+" "+sY+" A "+[rx,ry,φ/(2*π)*360,Δ>π?1:0,Δ>0?1:0,eX,eY].join(" ")};_exports.svgarcpath=svgarcpath;_exports.svgarc=(_ref8,_ref9,_ref10,φ)=>{let[cx,cy]=_ref8,[rx,ry]=_ref9,[t1,Δ]=_ref10;const path_2wk2r=document.createElementNS("http://www.w3.org/2000/svg","path"),d=svgarcpath([cx,cy],[rx,ry],[t1,Δ],φ);return path_2wk2r.setAttribute("d",d),path_2wk2r}}));
|
define("local_treestudyplan/util/svgarc",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.svgarcpath=_exports.svgarc=void 0;const cos=Math.cos,sin=Math.sin,π=Math.PI,f_matrix_times=(_ref,_ref2)=>{let[[a,b],[c,d]]=_ref,[x,y]=_ref2;return[a*x+b*y,c*x+d*y]},f_vec_add=(_ref3,_ref4)=>{let[a1,a2]=_ref3,[b1,b2]=_ref4;return[a1+b1,a2+b2]},svgarcpath=(_ref5,_ref6,_ref7,φ)=>{let[cx,cy]=_ref5,[rx,ry]=_ref6,[t1,Δ]=_ref7;Δ%=2*π;const rotMatrix=[[cos(x=φ),-sin(x)],[sin(x),cos(x)]];var x;const[sX,sY]=f_vec_add(f_matrix_times(rotMatrix,[rx*cos(t1),ry*sin(t1)]),[cx,cy]),[eX,eY]=f_vec_add(f_matrix_times(rotMatrix,[rx*cos(t1+Δ),ry*sin(t1+Δ)]),[cx,cy]),fA=Δ>π?1:0,fS=Δ>0?1:0;return isNaN(eY)||isNaN(eX)?"":"M "+sX+" "+sY+" A "+[rx,ry,φ/(2*π)*360,fA,fS,eX,eY].join(" ")};_exports.svgarcpath=svgarcpath;_exports.svgarc=(_ref8,_ref9,_ref10,φ)=>{let[cx,cy]=_ref8,[rx,ry]=_ref9,[t1,Δ]=_ref10;const path_2wk2r=document.createElementNS("http://www.w3.org/2000/svg","path"),d=svgarcpath([cx,cy],[rx,ry],[t1,Δ],φ);return path_2wk2r.setAttribute("d",d),path_2wk2r}}));
|
||||||
|
|
||||||
//# sourceMappingURL=svgarc.min.js.map
|
//# sourceMappingURL=svgarc.min.js.map
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"svgarc.min.js","sources":["../../src/util/svgarc.js"],"sourcesContent":["/*\nCopyright © 2020 Xah Lee, © 2023 P.M Kuipers\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the “Software”),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\nURL: SVG Circle Arc http://xahlee.info/js/svg_circle_arc.html\n*/\n\nconst cos = Math.cos;\nconst sin = Math.sin;\nconst π = Math.PI;\n\nconst f_matrix_times = (( [[a,b], [c,d]], [x,y]) => [ a * x + b * y, c * x + d * y]);\nconst f_rotate_matrix = (x => [[cos(x),-sin(x)], [sin(x), cos(x)]]);\nconst f_vec_add = (([a1, a2], [b1, b2]) => [a1 + b1, a2 + b2]);\n\n// function modified by pmkuipers for text params\n/**\n * Create svg path text for an arc\n * @param {*} center [cx,cy] center of ellipse\n * @param {*} radius [rx,ry] major minor radius\n * @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.\n * @param {*} φ rotation on the whole, in radian\n * @returns a SVG path element that represent a ellipse. Text describing the arc path in an svg path element\n */\nconst svgarcpath = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {\n Δ = Δ % (2*π);\n const rotMatrix = f_rotate_matrix (φ);\n const [sX, sY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1), ry * sin(t1)] ), [cx,cy] ) );\n const [eX, eY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1+Δ), ry * sin(t1+Δ)] ), [cx,cy] ) );\n const fA = ( ( Δ > π ) ? 1 : 0 );\n const fS = ( ( Δ > 0 ) ? 1 : 0 );\n return \"M \" + sX + \" \" + sY + \" A \" + [ rx , ry , φ / (2*π) *360, fA, fS, eX, eY ].join(\" \");\n});\n\n/**\n * Create an svg arc element\n * @param {*} center [cx,cy] center of ellipse\n * @param {*} radius [rx,ry] major minor radius\n * @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.\n * @param {*} φ rotation on the whole, in radian\n * @returns a SVG path element that represent a ellipse.\n */\nconst svgarc = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {\n const path_2wk2r = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n const d = svgarcpath([cx,cy],[rx,ry], [t1, Δ], φ );\n path_2wk2r.setAttribute(\"d\", d);\n return path_2wk2r;\n});\n\nexport {svgarc, svgarcpath};"],"names":["cos","Math","sin","π","PI","f_matrix_times","a","b","c","d","x","y","f_vec_add","a1","a2","b1","b2","svgarcpath","φ","cx","cy","rx","ry","t1","Δ","rotMatrix","sX","sY","eX","eY","join","path_2wk2r","document","createElementNS","setAttribute"],"mappings":"kLAoBMA,IAAMC,KAAKD,IACXE,IAAMD,KAAKC,IACXC,EAAIF,KAAKG,GAETC,eAAkB,oBAAIC,EAAEC,IAAKC,EAAEC,UAAMC,EAAEC,eAAO,CAAEL,EAAII,EAAIH,EAAII,EAAGH,EAAIE,EAAID,EAAIE,EAAzD,EAElBC,UAAa,oBAAEC,GAAIC,WAAMC,GAAIC,gBAAQ,CAACH,GAAKE,GAAID,GAAKE,GAAvC,EAWbC,WAAc,mBAA2BC,SAAzBC,GAAGC,WAAKC,GAAGC,WAAMC,GAAIC,SACvCA,GAAS,EAAErB,QACLsB,UAdoB,CAAC,CAACzB,IAAPU,EAccQ,IAdChB,IAAIQ,IAAK,CAACR,IAAIQ,GAAIV,IAAIU,KAArCA,YAedgB,GAAIC,IAAQf,UAAYP,eAAiBoB,UAAW,CAACJ,GAAKrB,IAAIuB,IAAKD,GAAKpB,IAAIqB,MAAQ,CAACJ,GAAGC,MACxFQ,GAAIC,IAAQjB,UAAYP,eAAiBoB,UAAW,CAACJ,GAAKrB,IAAIuB,GAAGC,GAAIF,GAAKpB,IAAIqB,GAAGC,KAAO,CAACL,GAAGC,WAG5F,KAAOM,GAAK,IAAMC,GAAK,MAAQ,CAAEN,GAAKC,GAAKJ,GAAK,EAAEf,GAAI,IAF7CqB,EAAIrB,EAAM,EAAI,EACdqB,EAAI,EAAM,EAAI,EAC4CI,GAAIC,IAAKC,KAAK,IAAxF,iDAWY,oBAA2BZ,SAAzBC,GAAGC,WAAKC,GAAGC,WAAMC,GAAIC,gBAC7BO,WAAaC,SAASC,gBAAgB,6BAA8B,QACpExB,EAAIQ,WAAW,CAACE,GAAGC,IAAI,CAACC,GAAGC,IAAK,CAACC,GAAIC,GAAIN,UAC/Ca,WAAWG,aAAa,IAAKzB,GACtBsB,UAAP"}
|
{"version":3,"file":"svgarc.min.js","sources":["../../src/util/svgarc.js"],"sourcesContent":["/*\nCopyright © 2020 Xah Lee, © 2023 P.M Kuipers\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the “Software”),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\nTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\nURL: SVG Circle Arc http://xahlee.info/js/svg_circle_arc.html\n*/\n\nconst cos = Math.cos;\nconst sin = Math.sin;\nconst π = Math.PI;\n\nconst f_matrix_times = (( [[a,b], [c,d]], [x,y]) => [ a * x + b * y, c * x + d * y]);\nconst f_rotate_matrix = (x => [[cos(x),-sin(x)], [sin(x), cos(x)]]);\nconst f_vec_add = (([a1, a2], [b1, b2]) => [a1 + b1, a2 + b2]);\n\n// function modified by pmkuipers for text params\n/**\n * Create svg path text for an arc\n * @param {*} center [cx,cy] center of ellipse\n * @param {*} radius [rx,ry] major minor radius\n * @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.\n * @param {*} φ rotation on the whole, in radian\n * @returns a SVG path element that represent a ellipse. Text describing the arc path in an svg path element\n */\nconst svgarcpath = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {\n Δ = Δ % (2*π);\n const rotMatrix = f_rotate_matrix (φ);\n const [sX, sY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1), ry * sin(t1)] ), [cx,cy] ) );\n const [eX, eY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1+Δ), ry * sin(t1+Δ)] ), [cx,cy] ) );\n const fA = ( ( Δ > π ) ? 1 : 0 );\n const fS = ( ( Δ > 0 ) ? 1 : 0 );\n if ( isNaN(eY) || isNaN(eX) ) {\n return \"\";\n } else {\n return \"M \" + sX + \" \" + sY + \" A \" + [ rx , ry , φ / (2*π) *360, fA, fS, eX, eY ].join(\" \");\n }\n});\n\n/**\n * Create an svg arc element\n * @param {*} center [cx,cy] center of ellipse\n * @param {*} radius [rx,ry] major minor radius\n * @param {*} angle [t1, Δ] start angle, in radian, angle to sweep, in radian. positive.\n * @param {*} φ rotation on the whole, in radian\n * @returns a SVG path element that represent a ellipse.\n */\nconst svgarc = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {\n const path_2wk2r = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n const d = svgarcpath([cx,cy],[rx,ry], [t1, Δ], φ );\n path_2wk2r.setAttribute(\"d\", d);\n return path_2wk2r;\n});\n\nexport {svgarc, svgarcpath};"],"names":["cos","Math","sin","π","PI","f_matrix_times","a","b","c","d","x","y","f_vec_add","a1","a2","b1","b2","svgarcpath","φ","cx","cy","rx","ry","t1","Δ","rotMatrix","sX","sY","eX","eY","fA","fS","isNaN","join","path_2wk2r","document","createElementNS","setAttribute"],"mappings":"kLAoBMA,IAAMC,KAAKD,IACXE,IAAMD,KAAKC,IACXC,EAAIF,KAAKG,GAETC,eAAkB,oBAAIC,EAAEC,IAAKC,EAAEC,UAAMC,EAAEC,eAAO,CAAEL,EAAII,EAAIH,EAAII,EAAGH,EAAIE,EAAID,EAAIE,EAAzD,EAElBC,UAAa,oBAAEC,GAAIC,WAAMC,GAAIC,gBAAQ,CAACH,GAAKE,GAAID,GAAKE,GAAvC,EAWbC,WAAc,mBAA2BC,SAAzBC,GAAGC,WAAKC,GAAGC,WAAMC,GAAIC,SACvCA,GAAS,EAAErB,QACLsB,UAdoB,CAAC,CAACzB,IAAPU,EAccQ,IAdChB,IAAIQ,IAAK,CAACR,IAAIQ,GAAIV,IAAIU,KAArCA,YAedgB,GAAIC,IAAQf,UAAYP,eAAiBoB,UAAW,CAACJ,GAAKrB,IAAIuB,IAAKD,GAAKpB,IAAIqB,MAAQ,CAACJ,GAAGC,MACxFQ,GAAIC,IAAQjB,UAAYP,eAAiBoB,UAAW,CAACJ,GAAKrB,IAAIuB,GAAGC,GAAIF,GAAKpB,IAAIqB,GAAGC,KAAO,CAACL,GAAGC,KAC7FU,GAAUN,EAAIrB,EAAM,EAAI,EACxB4B,GAAUP,EAAI,EAAM,EAAI,SACzBQ,MAAMH,KAAOG,MAAMJ,IACb,GAEA,KAAOF,GAAK,IAAMC,GAAK,MAAQ,CAAEN,GAAKC,GAAKJ,GAAK,EAAEf,GAAI,IAAK2B,GAAIC,GAAIH,GAAIC,IAAKI,KAAK,qDAYhF,oBAA2Bf,SAAzBC,GAAGC,WAAKC,GAAGC,WAAMC,GAAIC,gBAC7BU,WAAaC,SAASC,gBAAgB,6BAA8B,QACpE3B,EAAIQ,WAAW,CAACE,GAAGC,IAAI,CAACC,GAAGC,IAAK,CAACC,GAAIC,GAAIN,UAC/CgB,WAAWG,aAAa,IAAK5B,GACtByB,UAAP"}
|
|
@ -9,7 +9,7 @@
|
||||||
import {SimpleLine} from './simpleline/simpleline';
|
import {SimpleLine} from './simpleline/simpleline';
|
||||||
import {get_strings} from 'core/str';
|
import {get_strings} from 'core/str';
|
||||||
import {load_strings} from './util/string-helper';
|
import {load_strings} from './util/string-helper';
|
||||||
import {format_date,studyplanPageTiming,studyplanTiming} from './util/date-helper';
|
import {format_date, format_datetime, studyplanPageTiming,studyplanTiming} from './util/date-helper';
|
||||||
import {call} from 'core/ajax';
|
import {call} from 'core/ajax';
|
||||||
import notification from 'core/notification';
|
import notification from 'core/notification';
|
||||||
import {svgarcpath} from './util/svgarc';
|
import {svgarcpath} from './util/svgarc';
|
||||||
|
@ -18,12 +18,37 @@ import Config from 'core/config';
|
||||||
import {ProcessStudyplan, ProcessStudyplanPage, objCopy} from './studyplan-processor';
|
import {ProcessStudyplan, ProcessStudyplanPage, objCopy} from './studyplan-processor';
|
||||||
import TSComponents from './treestudyplan-components';
|
import TSComponents from './treestudyplan-components';
|
||||||
import {eventTypes as editSwEventTypes} from 'core/edit_switch';
|
import {eventTypes as editSwEventTypes} from 'core/edit_switch';
|
||||||
|
import { premiumenabled, premiumstatus } from "./util/premium";
|
||||||
|
|
||||||
// Make π available as a constant
|
// Make π available as a constant
|
||||||
const π = Math.PI;
|
const π = Math.PI;
|
||||||
// Gravity value for arrow lines - determines how much a line is pulled in the direction of the start/end before changing direction
|
// Gravity value for arrow lines - determines how much a line is pulled in the direction of the start/end before changing direction
|
||||||
const LINE_GRAVITY = 1.3;
|
const LINE_GRAVITY = 1.3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Studyline is not enrollable
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
const ENROLLABLE_NONE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Studyline can be enrolled into by the student
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
const ENROLLABLE_SELF = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Studyline can be enrolled into by specific role(s)
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
const ENROLLABLE_ROLE = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Studyline can be enrolled by user and/or role
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
const ENROLLABLE_SELF_ROLE = 3;
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue/*,options*/){
|
install(Vue/*,options*/){
|
||||||
|
@ -160,6 +185,25 @@ export default {
|
||||||
details: 'studyplan_details',
|
details: 'studyplan_details',
|
||||||
overview: 'overviewreport:all',
|
overview: 'overviewreport:all',
|
||||||
oveviewperiod: 'overviewreport:period'
|
oveviewperiod: 'overviewreport:period'
|
||||||
|
},
|
||||||
|
lineheader: {
|
||||||
|
cannot_enrol: 'line_cannot_enrol',
|
||||||
|
can_enrol: 'line_can_enrol',
|
||||||
|
is_enrolled: 'line_is_enrolled',
|
||||||
|
enrol: 'line_enrol',
|
||||||
|
enrolled: 'line_enrolled',
|
||||||
|
notenrolled: 'line_notenrolled',
|
||||||
|
enrol_question: 'line_enrol_question',
|
||||||
|
enrollments: 'line_enrollments',
|
||||||
|
enrollment: 'line_enrollment',
|
||||||
|
info: 'info@core',
|
||||||
|
confirm: 'confirm@core',
|
||||||
|
yes: 'yes@core',
|
||||||
|
no: 'no@core',
|
||||||
|
enrolled_in: 'line_enrolled_in',
|
||||||
|
since: 'since@core',
|
||||||
|
byname: 'byname@core',
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -459,11 +503,11 @@ export default {
|
||||||
},
|
},
|
||||||
guestmode: {
|
guestmode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() { return false;},
|
default: false,
|
||||||
},
|
},
|
||||||
teachermode: {
|
teachermode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default() { return false;},
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -637,8 +681,12 @@ export default {
|
||||||
></s-studyline-header-heading>
|
></s-studyline-header-heading>
|
||||||
<r-studyline-heading v-for="(line,lineindex) in page.studylines"
|
<r-studyline-heading v-for="(line,lineindex) in page.studylines"
|
||||||
:key="line.id"
|
:key="line.id"
|
||||||
|
:teachermode="teachermode"
|
||||||
|
:guestmode="guestmode"
|
||||||
v-model="page.studylines[lineindex]"
|
v-model="page.studylines[lineindex]"
|
||||||
:layers='countLineLayers(line,page)+1'
|
:layers='countLineLayers(line,page)+1'
|
||||||
|
:studentid="value.userid"
|
||||||
|
@enrolupdate="page.studylines[lineindex].enrol = $event"
|
||||||
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
:class=" 't-studyline' + ((lineindex%2==0)?' odd ' :' even ' )
|
||||||
+ ((lineindex==0)?' first ':' ')
|
+ ((lineindex==0)?' first ':' ')
|
||||||
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
+ ((lineindex==page.studylines.length-1)?' last ':' ')"
|
||||||
|
@ -726,14 +774,28 @@ export default {
|
||||||
type: Object, // Studyline
|
type: Object, // Studyline
|
||||||
default: function(){ return {};},
|
default: function(){ return {};},
|
||||||
},
|
},
|
||||||
|
guestmode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
teachermode: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
layers: {
|
layers: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1,
|
default: 1,
|
||||||
},
|
},
|
||||||
|
studentid: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
layerHeights: {}
|
layerHeights: {},
|
||||||
|
text: strings.lineheader,
|
||||||
|
students: null,
|
||||||
|
can_unenrol: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -742,9 +804,45 @@ export default {
|
||||||
ItemEventBus.$on('lineHeightChange', this.onLineHeightChange);
|
ItemEventBus.$on('lineHeightChange', this.onLineHeightChange);
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
enrollable() {
|
||||||
|
return this.value.enrol.enrollable > ENROLLABLE_NONE;
|
||||||
|
},
|
||||||
|
enrollable_self() {
|
||||||
|
return [ENROLLABLE_SELF,ENROLLABLE_SELF_ROLE].includes(this.value.enrol.enrollable);
|
||||||
|
},
|
||||||
|
enrollable_role() {
|
||||||
|
return [ENROLLABLE_ROLE,ENROLLABLE_SELF_ROLE].includes(this.value.enrol.enrollable);
|
||||||
|
},
|
||||||
|
enrolled() {
|
||||||
|
return this.value.enrol.enrolled?true:false;
|
||||||
|
},
|
||||||
|
can_enrol() {
|
||||||
|
return this.value.enrol.can_enrol?true:false;
|
||||||
|
},
|
||||||
|
enrol_question() {
|
||||||
|
return this.text.enrol_question.replace('{$a}',this.value.name);
|
||||||
|
},
|
||||||
|
enrolled_in() {
|
||||||
|
return this.text.enrolled_in.replace('{$a}',this.value.name);
|
||||||
|
},
|
||||||
|
by() {
|
||||||
|
return this.text.byname.replace('{$a}','');
|
||||||
|
},
|
||||||
|
enrolldate() {
|
||||||
|
return format_datetime(this.value.enrol.enrolled_time);
|
||||||
|
},
|
||||||
|
enrolled_students() {
|
||||||
|
const list = [];
|
||||||
|
for (const s of this.students) {
|
||||||
|
if (s.enrolled) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
premiumenabled,
|
||||||
onLineHeightChange(lineid){
|
onLineHeightChange(lineid){
|
||||||
// All layers for this line have the first slot send an update message on layer height change.
|
// All layers for this line have the first slot send an update message on layer height change.
|
||||||
// When one of those updates is received, record the height and recalculate the total height of the
|
// When one of those updates is received, record the height and recalculate the total height of the
|
||||||
|
@ -764,15 +862,125 @@ export default {
|
||||||
const heightStyle=`${heightSum}px`;
|
const heightStyle=`${heightSum}px`;
|
||||||
this.$refs.mainEl.style.height = heightStyle;
|
this.$refs.mainEl.style.height = heightStyle;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
enrol_self() {
|
||||||
|
const self=this;
|
||||||
|
call([{
|
||||||
|
methodname: 'local_treestudyplan_line_enrol_self',
|
||||||
|
args: { id: self.value.id},
|
||||||
|
}])[0].then(function(response){
|
||||||
|
self.$emit('enrolupdate',response);
|
||||||
|
}).catch(notification.exception);
|
||||||
|
},
|
||||||
|
|
||||||
|
enrol_student(id) {
|
||||||
|
const self=this;
|
||||||
|
call([{
|
||||||
|
methodname: 'local_treestudyplan_line_enrol_students',
|
||||||
|
args: { id: self.value.id, users: [id] },
|
||||||
|
}])[0].then(function(response){
|
||||||
|
self.$emit('enrolupdate',response);
|
||||||
|
}).catch(notification.exception);
|
||||||
|
},
|
||||||
|
unenrol_student(id) {
|
||||||
|
const self=this;
|
||||||
|
call([{
|
||||||
|
methodname: 'local_treestudyplan_line_unenrol_students',
|
||||||
|
args: { id: self.value.id, users: [id] },
|
||||||
|
}])[0].then(function(response){
|
||||||
|
self.$emit('enrolupdate',response);
|
||||||
|
}).catch(notification.exception);
|
||||||
|
},
|
||||||
|
load_students() {
|
||||||
|
const self=this;
|
||||||
|
call([{
|
||||||
|
methodname: 'local_treestudyplan_list_line_enrolled_students',
|
||||||
|
args: { id: self.value.id },
|
||||||
|
}])[0].then(function(response){
|
||||||
|
self.students = response.userinfo;
|
||||||
|
self.can_unenrol = response.can_unenrol;
|
||||||
|
}).catch(notification.exception);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<div class="r-studyline r-studyline-heading "
|
<div class="r-studyline r-studyline-heading "
|
||||||
:data-studyline="value.id" ref="mainEl"
|
:data-studyline="value.id" ref="mainEl"
|
||||||
><div class="r-studyline-handle" :style="'background-color: ' + value.color"></div>
|
><div class="r-studyline-handle" :style="'background-color: ' + value.color"></div>
|
||||||
<div class="r-studyline-title">
|
<div class="r-studyline-title"><div>
|
||||||
<abbr v-b-tooltip.hover :title="value.name">{{ value.shortname }}</abbr>
|
<abbr v-b-tooltip.hover :title="value.name">{{ value.shortname }}</abbr>
|
||||||
</div>
|
<template v-if="premiumenabled() && enrollable">
|
||||||
|
<template v-if="teachermode">
|
||||||
|
<a v-if="!can_enrol"
|
||||||
|
href='#' @click.prevent=""
|
||||||
|
v-b-modal="'r-enrollments-'+value.id"
|
||||||
|
:title="text.cannot_enrol"
|
||||||
|
><i class='fa fa-lock text-danger'></i> {{text.enrollments}}</a>
|
||||||
|
<a v-else
|
||||||
|
href='#' @click.prevent=""
|
||||||
|
v-b-modal="'r-enrollments-'+value.id"
|
||||||
|
:title="text.can_enrol"
|
||||||
|
><i class='fa fa-unlock-alt text-success'></i> {{text.enrollments}}</a>
|
||||||
|
<b-modal
|
||||||
|
:id="'r-enrollments-'+value.id"
|
||||||
|
ok-only
|
||||||
|
scrollable
|
||||||
|
>
|
||||||
|
<table>
|
||||||
|
<tr v-if="students == null"><td>
|
||||||
|
<div class="spinner-border spinner-border-sm text-info" role="status"></div>
|
||||||
|
</td></tr>
|
||||||
|
<template v-if="students && can_enrol">
|
||||||
|
<tr v-for="student in students">
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<template v-else-if="students">
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</table>
|
||||||
|
</b-modal>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<a v-if="!enrolled && !can_enrol"
|
||||||
|
href='#' @click.prevent=""
|
||||||
|
v-b-tooltip.focus
|
||||||
|
:title="text.cannot_enrol"
|
||||||
|
><i class='fa fa-lock text-danger'></i> {{text.cannot_enrol}}</a>
|
||||||
|
<a v-else-if="!enrolled && can_enrol"
|
||||||
|
href='#' @click.prevent=""
|
||||||
|
v-b-modal="'r-enrol-'+value.id"
|
||||||
|
:title="text.can_enrol"
|
||||||
|
><i class='fa fa-unlock-alt text-success'></i> {{text.enrol}}</a>
|
||||||
|
<a v-else-if="enrolled"
|
||||||
|
href='#' @click.prevent=""
|
||||||
|
v-b-modal="'r-enrollment-'+value.id"
|
||||||
|
:title="text.enrolled"
|
||||||
|
><i class='fa fa-unlock text-success'></i> {{text.enrolled}}</a>
|
||||||
|
<b-modal
|
||||||
|
:id="'r-enrol-'+value.id"
|
||||||
|
:title="text.confirm"
|
||||||
|
:ok-title="text.yes"
|
||||||
|
:cancel-title="text.no"
|
||||||
|
ok-variant="success"
|
||||||
|
cancel-variant="danger"
|
||||||
|
@ok="enrol_self"
|
||||||
|
>
|
||||||
|
<p>{{enrol_question}}</p>
|
||||||
|
</b-modal>
|
||||||
|
<b-modal
|
||||||
|
:id="'r-enrollment-'+value.id"
|
||||||
|
ok-only
|
||||||
|
:title="text.enrollment"
|
||||||
|
>
|
||||||
|
<p>{{enrolled_in}}<p>
|
||||||
|
<p><b>{{text.since}}</b> {{enrolldate}}<br>
|
||||||
|
<b>{{by}}</b> {{this.value.enrol.enrolled_by}}</p>
|
||||||
|
</b-modal>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div></div>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -490,14 +490,14 @@ export default {
|
||||||
<p>{{ text.advanced_cascade_cohortsync_desc}}</p>
|
<p>{{ text.advanced_cascade_cohortsync_desc}}</p>
|
||||||
<p class="mt-2"><b-button
|
<p class="mt-2"><b-button
|
||||||
variant="info"
|
variant="info"
|
||||||
@click="cascade_cohortsync"
|
@click.prevent="cascade_cohortsync"
|
||||||
>{{ text.advanced_cascade_cohortsync}}</b-button></p>
|
>{{ text.advanced_cascade_cohortsync}}</b-button></p>
|
||||||
<h3>{{ text.advanced_bulk_course_timing}}</h3>
|
<h3>{{ text.advanced_bulk_course_timing}}</h3>
|
||||||
<p>{{ text.advanced_bulk_course_timing_desc}}</p>
|
<p>{{ text.advanced_bulk_course_timing_desc}}</p>
|
||||||
<p>{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
<p>{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
||||||
<p class="mt-2"><b-button
|
<p class="mt-2"><b-button
|
||||||
variant="info"
|
variant="info"
|
||||||
@click="bulk_course_timing"
|
@click.prevent="bulk_course_timing"
|
||||||
>{{ text.advanced_bulk_course_timing}}</b-button></p>
|
>{{ text.advanced_bulk_course_timing}}</b-button></p>
|
||||||
<template v-if="['bistate','tristate'].includes(value.aggregation)">
|
<template v-if="['bistate','tristate'].includes(value.aggregation)">
|
||||||
<h3>{{ text.advanced_force_scale_title}}</h3>
|
<h3>{{ text.advanced_force_scale_title}}</h3>
|
||||||
|
@ -508,7 +508,7 @@ export default {
|
||||||
<b-button
|
<b-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
:disabled="force_scales.selected_scale == null"
|
:disabled="force_scales.selected_scale == null"
|
||||||
@click="force_scales_start"
|
@click.prevent="force_scales_start"
|
||||||
>{{ text.advanced_force_scale_button}}</b-button>
|
>{{ text.advanced_force_scale_button}}</b-button>
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2">
|
<p class="mt-2">
|
||||||
|
@ -535,26 +535,26 @@ export default {
|
||||||
<h3>{{ text.advanced_backup }}</h3>
|
<h3>{{ text.advanced_backup }}</h3>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
@click="export_page('json')"
|
@click.prevent="export_page('json')"
|
||||||
>{{ text.advanced_backup_page }}</b-button>
|
>{{ text.advanced_backup_page }}</b-button>
|
||||||
{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
@click="export_plan('json')"
|
@click.prevent="export_plan('json')"
|
||||||
>{{ text.advanced_backup_plan }}</b-button></p>
|
>{{ text.advanced_backup_plan }}</b-button></p>
|
||||||
<h3>{{ text.advanced_restore }}</h3>
|
<h3>{{ text.advanced_restore }}</h3>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
@click="import_studylines"
|
@click.prevent="import_studylines"
|
||||||
>{{ text.advanced_restore_lines}}</b-button></p>
|
>{{ text.advanced_restore_lines}}</b-button></p>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
@click="import_pages"
|
@click.prevent="import_pages"
|
||||||
>{{ text.advanced_restore_pages }}</b-button></p>
|
>{{ text.advanced_restore_pages }}</b-button></p>
|
||||||
<h3>{{ text.advanced_export }}</h3>
|
<h3>{{ text.advanced_export }}</h3>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
@click="export_page('csv')"
|
@click.prevent="export_page('csv')"
|
||||||
>{{ text.advanced_export_csv_page }}</b-button>
|
>{{ text.advanced_export_csv_page }}</b-button>
|
||||||
{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
||||||
</b-tab>
|
</b-tab>
|
||||||
|
@ -563,12 +563,12 @@ export default {
|
||||||
<p>{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
<p>{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
@click="purge_studyplanpage"
|
@click.prevent="purge_studyplanpage"
|
||||||
>{{ text.advanced_purge_page}}</b-button></p>
|
>{{ text.advanced_purge_page}}</b-button></p>
|
||||||
<p>{{text.advanced_purge_plan_expl}}</p>
|
<p>{{text.advanced_purge_plan_expl}}</p>
|
||||||
<p><b-button
|
<p><b-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
@click="purge_studyplan"
|
@click.prevent="purge_studyplan"
|
||||||
>{{ text.advanced_purge_plan}}</b-button></p>
|
>{{ text.advanced_purge_plan}}</b-button></p>
|
||||||
</b-tab>
|
</b-tab>
|
||||||
</b-tabs>
|
</b-tabs>
|
||||||
|
@ -985,11 +985,11 @@ export default {
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row class='mt-2'>
|
<b-row class='mt-2'>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button variant='danger' @click="cohortDisassociate()"
|
<b-button variant='danger' @click.prevent="cohortDisassociate()"
|
||||||
><i class='fa fa-chain-broken'></i> {{text.delete_association}}</b-button>
|
><i class='fa fa-chain-broken'></i> {{text.delete_association}}</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button variant='success' @click="cohortAssociate()"
|
<b-button variant='success' @click.prevent="cohortAssociate()"
|
||||||
><i class='fa fa-link'></i> {{text.add_association}}</b-button>
|
><i class='fa fa-link'></i> {{text.add_association}}</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
@ -1031,11 +1031,11 @@ export default {
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row class='mt-2'>
|
<b-row class='mt-2'>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button variant='danger' @click="userDisassociate()"
|
<b-button variant='danger' @click.prevent="userDisassociate()"
|
||||||
><i class='fa fa-chain-broken'></i> {{text.delete_association}}</b-button>
|
><i class='fa fa-chain-broken'></i> {{text.delete_association}}</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-button variant='success' @click="userAssociate()"
|
<b-button variant='success' @click.prevent="userAssociate()"
|
||||||
><i class='fa fa-link'></i> {{text.add_association}}</b-button>
|
><i class='fa fa-link'></i> {{text.add_association}}</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
@ -1226,8 +1226,10 @@ export default {
|
||||||
name: '',
|
name: '',
|
||||||
shortname: '',
|
shortname: '',
|
||||||
color: '#DDDDDD',
|
color: '#DDDDDD',
|
||||||
|
enrol: {
|
||||||
enrollable: 0,
|
enrollable: 0,
|
||||||
enrolroles: [],
|
enrolroles: [],
|
||||||
|
}
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
id: -1,
|
id: -1,
|
||||||
|
@ -1243,8 +1245,10 @@ export default {
|
||||||
name: '',
|
name: '',
|
||||||
shortname: '',
|
shortname: '',
|
||||||
color: '#DDDDDD',
|
color: '#DDDDDD',
|
||||||
|
enrol: {
|
||||||
enrollable: 0,
|
enrollable: 0,
|
||||||
enrolroles: [],
|
enrolroles: [],
|
||||||
|
}
|
||||||
},
|
},
|
||||||
original: {},
|
original: {},
|
||||||
availableroles: [],
|
availableroles: [],
|
||||||
|
@ -1406,16 +1410,16 @@ export default {
|
||||||
'shortname': newlineinfo.shortname,
|
'shortname': newlineinfo.shortname,
|
||||||
'color': newlineinfo.color,
|
'color': newlineinfo.color,
|
||||||
'sequence': page.studylines.length,
|
'sequence': page.studylines.length,
|
||||||
'enrollable': newlineinfo.enrollable,
|
'enrollable': newlineinfo.enrol.enrollable,
|
||||||
'enrolroles': newlineinfo.enrolroles
|
'enrolroles': newlineinfo.enrol.enrolroles
|
||||||
}
|
}
|
||||||
}])[0].then(function(response){
|
}])[0].then(function(response){
|
||||||
page.studylines.push(response);
|
page.studylines.push(response);
|
||||||
newlineinfo.name = '';
|
newlineinfo.name = '';
|
||||||
newlineinfo.shortname = '';
|
newlineinfo.shortname = '';
|
||||||
newlineinfo.color = "#dddddd";
|
newlineinfo.color = "#dddddd";
|
||||||
newlineinfo.enrollable = 0;
|
newlineinfo.enrol.enrollable = 0;
|
||||||
newlineinfo.enrolroles = [];
|
newlineinfo.enrol.enrolroles = [];
|
||||||
}).catch(notification.exception);
|
}).catch(notification.exception);
|
||||||
},
|
},
|
||||||
editLineStart(line) {
|
editLineStart(line) {
|
||||||
|
@ -1434,15 +1438,15 @@ export default {
|
||||||
'name': editedline.name,
|
'name': editedline.name,
|
||||||
'shortname': editedline.shortname,
|
'shortname': editedline.shortname,
|
||||||
'color': editedline.color,
|
'color': editedline.color,
|
||||||
'enrollable': editedline.enrollable,
|
'enrollable': editedline.enrol.enrollable,
|
||||||
'enrolroles': editedline.enrolroles
|
'enrolroles': editedline.enrol.enrolroles
|
||||||
}
|
}
|
||||||
}])[0].then(function(response){
|
}])[0].then(function(response){
|
||||||
originalline['name'] = response['name'];
|
originalline.name = response.name;
|
||||||
originalline['shortname'] = response['shortname'];
|
originalline.shortname = response.shortname;
|
||||||
originalline['color'] = response['color'];
|
originalline.color = response.color;
|
||||||
originalline['enrollable'] = response['enrollable'];
|
originalline.enrol.enrollable = response.enrol.enrollable;
|
||||||
originalline['enrolroles'] = response['enrolroles'];
|
originalline.enrol.enrolroles = response.enrol.enrolroles;
|
||||||
}).catch(notification.exception);
|
}).catch(notification.exception);
|
||||||
},
|
},
|
||||||
deleteLine(page,line) {
|
deleteLine(page,line) {
|
||||||
|
@ -1615,7 +1619,7 @@ export default {
|
||||||
><i class='fa fa-gear'></i> {{text.edit$core}}</t-studyplan-edit>
|
><i class='fa fa-gear'></i> {{text.edit$core}}</t-studyplan-edit>
|
||||||
</span>
|
</span>
|
||||||
<span class='control deletable'>
|
<span class='control deletable'>
|
||||||
<a v-if='value.pages.length == 0' href='#' @click='deletePlan(value)'
|
<a v-if='value.pages.length == 0' href='#' @click.prevent='deletePlan(value)'
|
||||||
><i class='text-danger fa fa-trash'></i></a>
|
><i class='text-danger fa fa-trash'></i></a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1768,7 +1772,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="edit.studyline.editmode" class='t-studyline-add ml-2 mt-1'>
|
<div v-if="edit.studyline.editmode" class='t-studyline-add ml-2 mt-1'>
|
||||||
<a href="#" v-b-modal="'modal-add-studyline-'+page.id" @click="false;"
|
<a href="#" v-b-modal="'modal-add-studyline-'+page.id" @click.prevent="false;"
|
||||||
><i class='fa fa-plus'></i>{{ text.studyline_add }}</a>
|
><i class='fa fa-plus'></i>{{ text.studyline_add }}</a>
|
||||||
</div>
|
</div>
|
||||||
<b-modal
|
<b-modal
|
||||||
|
@ -1806,7 +1810,7 @@ export default {
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col cols="3">{{ text.studyline_enrollable}}</b-col>
|
<b-col cols="3">{{ text.studyline_enrollable}}</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-form-select v-model="create.studyline.enrollable">
|
<b-form-select v-model="create.studyline.enrol.enrollable">
|
||||||
<b-form-select-option
|
<b-form-select-option
|
||||||
v-for="(nr,n) in 4"
|
v-for="(nr,n) in 4"
|
||||||
:value="n"
|
:value="n"
|
||||||
|
@ -1814,11 +1818,11 @@ export default {
|
||||||
</b-form-select>
|
</b-form-select>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row v-if='[2,3].includes(create.studyline.enrollable)'>
|
<b-row v-if='[2,3].includes(create.studyline.enrol.enrollable)'>
|
||||||
<b-col cols="3">{{ text.studyline_enrolroles}}</b-col>
|
<b-col cols="3">{{ text.studyline_enrolroles}}</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-form-select
|
<b-form-select
|
||||||
v-model="create.studyline.enrolroles"
|
v-model="create.studyline.enrol.enrolroles"
|
||||||
:options="availableroles"
|
:options="availableroles"
|
||||||
multiple
|
multiple
|
||||||
value-field="id"
|
value-field="id"
|
||||||
|
@ -1865,7 +1869,7 @@ export default {
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col cols="3">{{ text.studyline_enrollable}}</b-col>
|
<b-col cols="3">{{ text.studyline_enrollable}}</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-form-select v-model="edit.studyline.data.enrollable">
|
<b-form-select v-model="edit.studyline.data.enrol.enrollable">
|
||||||
<b-form-select-option
|
<b-form-select-option
|
||||||
v-for="(nr,n) in 4"
|
v-for="(nr,n) in 4"
|
||||||
:value="n"
|
:value="n"
|
||||||
|
@ -1873,11 +1877,11 @@ export default {
|
||||||
</b-form-select>
|
</b-form-select>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row v-if='[2,3].includes(edit.studyline.data.enrollable)'>
|
<b-row v-if='[2,3].includes(edit.studyline.data.enrol.enrollable)'>
|
||||||
<b-col cols="3">{{ text.studyline_enrolroles}}</b-col>
|
<b-col cols="3">{{ text.studyline_enrolroles}}</b-col>
|
||||||
<b-col>
|
<b-col>
|
||||||
<b-form-select
|
<b-form-select
|
||||||
v-model="edit.studyline.data.enrolroles"
|
v-model="edit.studyline.data.enrol.enrolroles"
|
||||||
:options="availableroles"
|
:options="availableroles"
|
||||||
multiple
|
multiple
|
||||||
value-field="id"
|
value-field="id"
|
||||||
|
@ -2019,10 +2023,10 @@ export default {
|
||||||
<div class='controlbox'>
|
<div class='controlbox'>
|
||||||
<template v-if='editable || deletable'>
|
<template v-if='editable || deletable'>
|
||||||
<span class='control editable' v-if='editable'>
|
<span class='control editable' v-if='editable'>
|
||||||
<a href='#' @click='onEdit'><i class='fa fa-pencil'></i></a>
|
<a href='#' @click.prevent='onEdit'><i class='fa fa-pencil'></i></a>
|
||||||
</span>
|
</span>
|
||||||
<span class='control deletable' v-if='deletable'>
|
<span class='control deletable' v-if='deletable'>
|
||||||
<a v-if='deletable' href='#' @click='onDelete'><i class='text-danger fa fa-trash'></i></a>
|
<a v-if='deletable' href='#' @click.prevent='onDelete'><i class='text-danger fa fa-trash'></i></a>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2584,7 +2588,7 @@ export default {
|
||||||
></i>
|
></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="mr-1" v-else>
|
<span class="mr-1" v-else>
|
||||||
<a href='#' @click="validate_course_period()" class="text-warning"
|
<a href='#' @click.prevent="validate_course_period()" class="text-warning"
|
||||||
v-b-tooltip.hover.bottomleft :title="text.timing_off"
|
v-b-tooltip.hover.bottomleft :title="text.timing_off"
|
||||||
><i class="fa fa-calendar-times-o"
|
><i class="fa fa-calendar-times-o"
|
||||||
></i
|
></i
|
||||||
|
@ -3070,7 +3074,7 @@ export default {
|
||||||
:data="value"
|
:data="value"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragend="dragEnd"
|
@dragend="dragEnd"
|
||||||
@click="deleteMode = (value.connections.out.length)?(!deleteMode):false"
|
@click.prevent="deleteMode = (value.connections.out.length)?(!deleteMode):false"
|
||||||
>
|
>
|
||||||
<svg width='5px' height='10px'><rect ry="1px" rx="1px" y="0px" x="0px" height="10px" width="5px"/></svg>
|
<svg width='5px' height='10px'><rect ry="1px" rx="1px" y="0px" x="0px" height="10px" width="5px"/></svg>
|
||||||
<template v-slot:drag-image="{data}"> <i :id="'t-item-cdrag-'+value.id" class="fa"></i>
|
<template v-slot:drag-image="{data}"> <i :id="'t-item-cdrag-'+value.id" class="fa"></i>
|
||||||
|
@ -3079,7 +3083,7 @@ export default {
|
||||||
<div class="deletebox" v-if="deleteMode && value.connections.out.length > 0"
|
<div class="deletebox" v-if="deleteMode && value.connections.out.length > 0"
|
||||||
>
|
>
|
||||||
<a v-for="conn in value.connections.out"
|
<a v-for="conn in value.connections.out"
|
||||||
@click="deleteLine(conn)"
|
@click.prevent="deleteLine(conn)"
|
||||||
@mouseenter="highlight(conn)"
|
@mouseenter="highlight(conn)"
|
||||||
@mouseleave="normalize(conn)"
|
@mouseleave="normalize(conn)"
|
||||||
class="t-connection-delete text-danger"
|
class="t-connection-delete text-danger"
|
||||||
|
@ -3108,11 +3112,11 @@ export default {
|
||||||
</b-form-group>
|
</b-form-group>
|
||||||
|
|
||||||
<template #modal-footer="{ ok, cancel, hide }" >
|
<template #modal-footer="{ ok, cancel, hide }" >
|
||||||
<a href='#' @click='deleteItem()' class="text-danger"
|
<a href='#' @click.prevent='deleteItem()' class="text-danger"
|
||||||
><i class="fa fa-trash"></i>
|
><i class="fa fa-trash"></i>
|
||||||
{{ text.delete }}
|
{{ text.delete }}
|
||||||
</a>
|
</a>
|
||||||
<b-button size="sm" variant="primary" @click="ok()">
|
<b-button size="sm" variant="primary" @click.prevent="ok()">
|
||||||
{{ text.ok }}
|
{{ text.ok }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -3146,7 +3150,7 @@ export default {
|
||||||
<b-col md="11">
|
<b-col md="11">
|
||||||
<b-card-body class="align-items-center">
|
<b-card-body class="align-items-center">
|
||||||
<i class="fa fa-exclamation"></i> {{text.error}}
|
<i class="fa fa-exclamation"></i> {{text.error}}
|
||||||
<a href='#' @click='$emit("deleterq")' class="text-danger"
|
<a href='#' @click.prevent='$emit("deleterq")' class="text-danger"
|
||||||
><i class="fa fa-trash"></i></a>
|
><i class="fa fa-trash"></i></a>
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
</b-col>
|
</b-col>
|
||||||
|
@ -3372,11 +3376,11 @@ export default {
|
||||||
position="below"
|
position="below"
|
||||||
></s-course-extrafields>
|
></s-course-extrafields>
|
||||||
<template #modal-footer="{ ok, cancel, hide }" >
|
<template #modal-footer="{ ok, cancel, hide }" >
|
||||||
<a href='#' @click='$emit("deleterq")' class="text-danger"
|
<a href='#' @click.prevent='$emit("deleterq")' class="text-danger"
|
||||||
><i class="fa fa-trash"></i>
|
><i class="fa fa-trash"></i>
|
||||||
{{ text.delete }}
|
{{ text.delete }}
|
||||||
</a>
|
</a>
|
||||||
<b-button size="sm" variant="primary" @click="ok()">
|
<b-button size="sm" variant="primary" @click.prevent="ok()">
|
||||||
{{ text.ok }}
|
{{ text.ok }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -3837,11 +3841,11 @@ export default {
|
||||||
</b-col></b-row>
|
</b-col></b-row>
|
||||||
</b-container>
|
</b-container>
|
||||||
<template #modal-footer="{ ok, cancel, hide }" >
|
<template #modal-footer="{ ok, cancel, hide }" >
|
||||||
<a href='#' @click='$emit("deleterq")' class="text-danger"
|
<a href='#' @click.prevent='$emit("deleterq")' class="text-danger"
|
||||||
><i class="fa fa-trash"></i>
|
><i class="fa fa-trash"></i>
|
||||||
{{ text.delete }}
|
{{ text.delete }}
|
||||||
</a>
|
</a>
|
||||||
<b-button size="sm" variant="primary" @click="ok()">
|
<b-button size="sm" variant="primary" @click.prevent="ok()">
|
||||||
{{ text.ok }}
|
{{ text.ok }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -693,7 +693,7 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
lastaccess() {
|
lastaccess() {
|
||||||
if (this.student.lastaccess) {
|
if (this.student.lastaccess) {
|
||||||
return format_datetime(this.student.lastaccess*1000); // Takes date in milliseconds
|
return format_datetime(this.student.lastaccess); // Takes date in milliseconds
|
||||||
} else {
|
} else {
|
||||||
return this.text.never;
|
return this.text.never;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
*/
|
*/
|
||||||
export function format_date(d,short){
|
export function format_date(d,short){
|
||||||
if(!(d instanceof Date)){
|
if(!(d instanceof Date)){
|
||||||
|
if (typeof d == 'number') {
|
||||||
|
d *= 1000; // Convert from seconds to milliseconds.
|
||||||
|
}
|
||||||
d = new Date(d);
|
d = new Date(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +31,9 @@ export function format_date(d,short){
|
||||||
*/
|
*/
|
||||||
export function format_datetime(d,short){
|
export function format_datetime(d,short){
|
||||||
if(!(d instanceof Date)){
|
if(!(d instanceof Date)){
|
||||||
|
if (typeof d == 'number') {
|
||||||
|
d *= 1000; // Convert from seconds to milliseconds.
|
||||||
|
}
|
||||||
d = new Date(d);
|
d = new Date(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,11 @@ const svgarcpath = (([cx,cy],[rx,ry], [t1, Δ], φ ) => {
|
||||||
const [eX, eY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1+Δ), ry * sin(t1+Δ)] ), [cx,cy] ) );
|
const [eX, eY] = ( f_vec_add ( f_matrix_times ( rotMatrix, [rx * cos(t1+Δ), ry * sin(t1+Δ)] ), [cx,cy] ) );
|
||||||
const fA = ( ( Δ > π ) ? 1 : 0 );
|
const fA = ( ( Δ > π ) ? 1 : 0 );
|
||||||
const fS = ( ( Δ > 0 ) ? 1 : 0 );
|
const fS = ( ( Δ > 0 ) ? 1 : 0 );
|
||||||
|
if ( isNaN(eY) || isNaN(eX) ) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
return "M " + sX + " " + sY + " A " + [ rx , ry , φ / (2*π) *360, fA, fS, eX, eY ].join(" ");
|
return "M " + sX + " " + sY + " A " + [ rx , ry , φ / (2*π) *360, fA, fS, eX, eY ].join(" ");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -592,4 +592,43 @@ class studentstudyplanservice extends \external_api {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
* *
|
||||||
|
* line_enrol_self *
|
||||||
|
* *
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function line_enrol_self_parameters() : \external_function_parameters {
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"id" => new \external_value(PARAM_INT, 'id of specific studyline to enrol into'),
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return value description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function line_enrol_self_returns() : \external_description {
|
||||||
|
return studyline::enrol_info_structure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all or one studyplan the current user is teaching in
|
||||||
|
* @param int $studyplanid ID of studyplan to retrieve
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function line_enrol_self($id) {
|
||||||
|
global $USER;
|
||||||
|
$userid = $USER->id;
|
||||||
|
|
||||||
|
$o = studyline::find_by_id($id);
|
||||||
|
if ($o->can_enrol($userid)) {
|
||||||
|
$o->enrol($userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $o->enrol_info_model($userid);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,6 +190,41 @@ class studyline {
|
||||||
return ($this->r->enrollable == self::ENROLLABLE_ROLE || $this->r->enrollable == self::ENROLLABLE_SELF_ROLE);
|
return ($this->r->enrollable == self::ENROLLABLE_ROLE || $this->r->enrollable == self::ENROLLABLE_SELF_ROLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the current user can enrol a specific user in this line
|
||||||
|
* @param int|null $user ID or user object for user or null
|
||||||
|
*/
|
||||||
|
public function can_enrol($userid=null) : bool {
|
||||||
|
global $USER;
|
||||||
|
|
||||||
|
$plan = $this->studyplan();
|
||||||
|
if (!empty($userid)){
|
||||||
|
if ( $plan->has_linked_user(intval($userid))) {
|
||||||
|
if ( $this->self_enrollable() && $userid == $USER->id ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( $this->role_enrollable()) {
|
||||||
|
$context = $plan->context();
|
||||||
|
foreach ( $this->enrol_roleids() as $rid) {
|
||||||
|
if (\user_has_role_assignment($USER->id,$rid,$context->id)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( $this->role_enrollable()) {
|
||||||
|
$context = $plan->context();
|
||||||
|
foreach ( $this->enrol_roleids() as $rid) {
|
||||||
|
if (\user_has_role_assignment($USER->id,$rid,$context->id)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this line is enrollable at all
|
* Whether this line is enrollable at all
|
||||||
|
@ -262,8 +297,7 @@ class studyline {
|
||||||
"shortname" => new \external_value(PARAM_TEXT, 'idnumber of studyline'),
|
"shortname" => new \external_value(PARAM_TEXT, 'idnumber of studyline'),
|
||||||
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
||||||
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
||||||
"enrollable" => new \external_value(PARAM_INT, 'type of enrollable'),
|
"enrol" => self::enrol_info_structure(),
|
||||||
"enrolroles" => new \external_multiple_structure(new \external_value(PARAM_INT, 'id of role')),
|
|
||||||
"slots" => new \external_multiple_structure(
|
"slots" => new \external_multiple_structure(
|
||||||
new \external_single_structure([
|
new \external_single_structure([
|
||||||
self::SLOTSET_COURSES => new \external_multiple_structure(
|
self::SLOTSET_COURSES => new \external_multiple_structure(
|
||||||
|
@ -275,6 +309,25 @@ class studyline {
|
||||||
],"Study line editor structure",$value);
|
],"Study line editor structure",$value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Webservice structure for enrolment info
|
||||||
|
* @param int $value Webservice requirement constant
|
||||||
|
*/
|
||||||
|
public static function enrol_info_structure($value = VALUE_REQUIRED) {
|
||||||
|
return new \external_single_structure([
|
||||||
|
"enrollable" => new \external_value(PARAM_INT, 'enrol mode (raw)'),
|
||||||
|
"enrolroles" => new \external_multiple_structure(new \external_value(PARAM_INT, 'id of role')),
|
||||||
|
"allowedroles" => new \external_multiple_structure(new \external_single_structure([
|
||||||
|
"id" => new \external_value(PARAM_INT, 'id of role'),
|
||||||
|
"name" => new \external_value(PARAM_TEXT, 'name of role'),
|
||||||
|
])),
|
||||||
|
"can_enrol" => new \external_value(PARAM_BOOL, 'enrollable by current user',VALUE_OPTIONAL),
|
||||||
|
"enrolled" => new \external_value(PARAM_BOOL, 'student is enrolled',VALUE_OPTIONAL),
|
||||||
|
"enrolled_time" => new \external_value(PARAM_INT, 'moment of enrollment',VALUE_OPTIONAL),
|
||||||
|
"enrolled_by" => new \external_value(PARAM_TEXT, 'Name of enrolling user',VALUE_OPTIONAL),
|
||||||
|
],"Enrollment info",$value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Webservice structure for simple info
|
* Webservice structure for simple info
|
||||||
* @param int $value Webservice requirement constant
|
* @param int $value Webservice requirement constant
|
||||||
|
@ -286,12 +339,7 @@ class studyline {
|
||||||
"shortname" => new \external_value(PARAM_TEXT, 'idnumber of studyline'),
|
"shortname" => new \external_value(PARAM_TEXT, 'idnumber of studyline'),
|
||||||
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
||||||
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
||||||
"enrollable_self" => new \external_value(PARAM_BOOL, 'enrollable by student'),
|
"enrol" => self::enrol_info_structure(),
|
||||||
"enrollable_role" => new \external_value(PARAM_BOOL, 'enrollable by student'),
|
|
||||||
"enrolroles" => new \external_multiple_structure(new \external_single_structure([
|
|
||||||
"id" => new \external_value(PARAM_INT, 'id of role'),
|
|
||||||
"name" => new \external_value(PARAM_TEXT, 'name of role'),
|
|
||||||
])),
|
|
||||||
],"Study line simple structure",$value);
|
],"Study line simple structure",$value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,9 +354,7 @@ class studyline {
|
||||||
'shortname' => $this->r->shortname,
|
'shortname' => $this->r->shortname,
|
||||||
'color' => $this->r->color,
|
'color' => $this->r->color,
|
||||||
'sequence' => $this->r->sequence,
|
'sequence' => $this->r->sequence,
|
||||||
'enrollable_self' => $this->self_enrollable(),
|
'enrol' => $this->enrol_info_model(),
|
||||||
'enrollable_role' => $this->role_enrollable(),
|
|
||||||
'enrolroles' => $this->enrol_roles_model(),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,8 +381,7 @@ class studyline {
|
||||||
'shortname' => $this->r->shortname,
|
'shortname' => $this->r->shortname,
|
||||||
'color' => $this->r->color,
|
'color' => $this->r->color,
|
||||||
'sequence' => $this->r->sequence,
|
'sequence' => $this->r->sequence,
|
||||||
'enrollable' => $this->r->enrollable,
|
'enrol' => $this->enrol_info_model(),
|
||||||
'enrolroles' => $this->enrol_roleids(),
|
|
||||||
'slots' => [],
|
'slots' => [],
|
||||||
];
|
];
|
||||||
if ($mode == "export") {
|
if ($mode == "export") {
|
||||||
|
@ -345,7 +390,6 @@ class studyline {
|
||||||
unset($model["sequence"]);
|
unset($model["sequence"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this a little nicer.
|
|
||||||
// Get the number of slots.
|
// Get the number of slots.
|
||||||
// As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
|
// As a safety data integrity measure, if there are any items in a higher slot than currently allowed, .
|
||||||
// Make sure there are enought slots to account for them.
|
// Make sure there are enought slots to account for them.
|
||||||
|
@ -501,12 +545,7 @@ class studyline {
|
||||||
"shortname" => new \external_value(PARAM_TEXT, 'idnumber of studyline'),
|
"shortname" => new \external_value(PARAM_TEXT, 'idnumber of studyline'),
|
||||||
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
"color" => new \external_value(PARAM_TEXT, 'description of studyline'),
|
||||||
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
"sequence" => new \external_value(PARAM_INT, 'order of studyline'),
|
||||||
"enrollable_self" => new \external_value(PARAM_BOOL, 'enrollable by student'),
|
"enrol" => self::enrol_info_structure(),
|
||||||
"enrollable_role" => new \external_value(PARAM_BOOL, 'enrollable by student'),
|
|
||||||
"enrol_roles" => new \external_multiple_structure(new \external_single_structure([
|
|
||||||
"id" => new \external_value(PARAM_INT, 'id of studyline'),
|
|
||||||
"name" => new \external_value(PARAM_TEXT, 'shortname of studyline'),
|
|
||||||
])),
|
|
||||||
"slots" => new \external_multiple_structure(
|
"slots" => new \external_multiple_structure(
|
||||||
new \external_single_structure([
|
new \external_single_structure([
|
||||||
self::SLOTSET_COURSES => new \external_multiple_structure(
|
self::SLOTSET_COURSES => new \external_multiple_structure(
|
||||||
|
@ -518,13 +557,128 @@ class studyline {
|
||||||
], 'Studyline with user info', $value);
|
], 'Studyline with user info', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Webservice model for user enrolment info
|
||||||
|
* @param int $userid ID of user to check specific info for
|
||||||
|
* @return array Webservice data model
|
||||||
|
*/
|
||||||
|
public function enrol_info_model($userid=null) {
|
||||||
|
global $DB,$USER;
|
||||||
|
|
||||||
|
$model = [
|
||||||
|
'enrolroles' => $this->enrol_roleids(),
|
||||||
|
'allowedroles' => $this->enrol_roles_model(),
|
||||||
|
'enrollable' => $this->r->enrollable,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!empty($userid)) {
|
||||||
|
$r = $DB->get_record('local_treestudyplan_lineuser',[
|
||||||
|
'line_id' => $this->id(),
|
||||||
|
'user_id' => $userid,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (empty($r)) {
|
||||||
|
$enrolled = false;
|
||||||
|
$enrolled_time = 0;
|
||||||
|
$enrolled_by = "";
|
||||||
|
} else {
|
||||||
|
$enrolled = boolval($r->enrolled);
|
||||||
|
$enrolled_time = $r->timeenrolled;
|
||||||
|
$by = $DB->get_record('user',["id" => $r->enrolledby]);
|
||||||
|
if (empty($by)) {
|
||||||
|
$enrolled_by = \get_string("unknownuser","core");
|
||||||
|
} else {
|
||||||
|
$enrolled_by = "{$by->firstname} {$by->lastname}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$usermodel = [
|
||||||
|
'can_enrol' => $this->can_enrol($userid),
|
||||||
|
"enrolled" => $enrolled,
|
||||||
|
"enrolled_time" => $enrolled_time,
|
||||||
|
"enrolled_by" => $enrolled_by,
|
||||||
|
];
|
||||||
|
$model = array_merge($model,$usermodel);
|
||||||
|
} else {
|
||||||
|
$model["can_enrol"] = $this->can_enrol();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enrol student from this line (if line enrollable)
|
||||||
|
* NOTE: This function does not check if the current user should be allowed to do this,
|
||||||
|
* the checks need to be done in the calling webservice / function
|
||||||
|
* @param int $userid of user to enrol
|
||||||
|
*/
|
||||||
|
public function enrol($userid) {
|
||||||
|
global $DB,$USER;
|
||||||
|
|
||||||
|
if ($this->r->enrollable > self::ENROLLABLE_NONE) {
|
||||||
|
$r = $DB->get_record("local_treestudyplan_lineuser",
|
||||||
|
["line_id" => $this->id(),
|
||||||
|
"user_id" => $userid]);
|
||||||
|
if ($r) {
|
||||||
|
// Registration already exists, check if enrol is false and update accordingly.
|
||||||
|
if (! boolval($r->enrolled)) {
|
||||||
|
$r->enrolled = 1;
|
||||||
|
$r->timeenrolled = time();
|
||||||
|
$r->enrolledby = $USER->id;
|
||||||
|
$DB->update_record("local_treestudyplan_lineuser",$r);
|
||||||
|
}
|
||||||
|
// Otherwise, ignore the request.
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Insert new record.
|
||||||
|
$r = new \stdClass;
|
||||||
|
$r->enrolled = 1;
|
||||||
|
$r->line_id = $this->id();
|
||||||
|
$r->user_id = $userid;
|
||||||
|
$r->timeenrolled = time();
|
||||||
|
$r->enrolledby = $USER->id;
|
||||||
|
$DB->insert_record("local_treestudyplan_lineuser",$r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unenrol student from this line (if line enrollable)
|
||||||
|
* NOTE: This function does not check if the current user should be allowed to do this,
|
||||||
|
* the checks need to be done in the calling webservice / function
|
||||||
|
* @param int $userid of user to unenrol
|
||||||
|
*/
|
||||||
|
public function unenrol($userid) {
|
||||||
|
global $DB,$USER;
|
||||||
|
|
||||||
|
if ($this->r->enrollable > self::ENROLLABLE_NONE) {
|
||||||
|
// Check if an enrollment line exist.
|
||||||
|
$r = $DB->get_record("local_treestudyplan_lineuser",
|
||||||
|
["line_id" => $this->id(),
|
||||||
|
"user_id" => $userid]);
|
||||||
|
if ($r) {
|
||||||
|
// Registration already exists, check if enrolled is true and update accordingly.
|
||||||
|
if (boolval($r->enrolled)) {
|
||||||
|
$r->enrolled = 0;
|
||||||
|
$r->timeenrolled = time(); // Regi
|
||||||
|
$r->enrolledby = $USER->id;
|
||||||
|
$DB->update_record("local_treestudyplan_lineuser",$r);
|
||||||
|
}
|
||||||
|
// Otherwise, ignore the request.
|
||||||
|
|
||||||
|
}
|
||||||
|
// Otherwise, no action is needed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Webservice model for user info
|
* Webservice model for user info
|
||||||
* @param int $userid ID of user to check specific info for
|
* @param int $userid ID of user to check specific info for
|
||||||
* @return array Webservice data model
|
* @return array Webservice data model
|
||||||
*/
|
*/
|
||||||
public function user_model($userid) {
|
public function user_model($userid) {
|
||||||
// TODO: Integrate this function into generate_model() for ease of maintenance.
|
|
||||||
|
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
|
@ -534,9 +688,7 @@ class studyline {
|
||||||
'shortname' => $this->r->shortname,
|
'shortname' => $this->r->shortname,
|
||||||
'color' => $this->r->color,
|
'color' => $this->r->color,
|
||||||
'sequence' => $this->r->sequence,
|
'sequence' => $this->r->sequence,
|
||||||
'enrollable_self' => $this->self_enrollable(),
|
'enrol' => $this->enrol_info_model($userid),
|
||||||
'enrollable_role' => $this->role_enrollable(),
|
|
||||||
'enrol_roles' => $this->enrol_roles_model(),
|
|
||||||
'slots' => [],
|
'slots' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1944,5 +1944,147 @@ class studyplanservice extends \external_api {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
* *
|
||||||
|
* line_enrol_students *
|
||||||
|
* *
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function line_enrol_students_parameters() : \external_function_parameters {
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"id" => new \external_value(PARAM_INT, 'id of specific studyline to enrol into'),
|
||||||
|
"users" => new \external_multiple_structure(new \external_value(PARAM_INT),'list of user ids'),
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return value description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function line_enrol_students_returns() : \external_description {
|
||||||
|
return success::structure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all or one studyplan the current user is teaching in
|
||||||
|
* @param int $studyplanid ID of studyplan to retrieve
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function line_enrol_students($id,$users) {
|
||||||
|
global $USER;
|
||||||
|
$userid = $USER->id;
|
||||||
|
|
||||||
|
$o = studyline::find_by_id($id);
|
||||||
|
|
||||||
|
/* NOTE: Perhaps the additional check for the view permission is not needed
|
||||||
|
since there is already a check on roles going on....
|
||||||
|
*/
|
||||||
|
$context = $o->context();
|
||||||
|
webservicehelper::require_capabilities(self::CAP_VIEW, $context);
|
||||||
|
|
||||||
|
foreach ($users as $userid) {
|
||||||
|
if ($o->can_enrol($userid)) {
|
||||||
|
$o->enrol($userid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success::success()->model();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
* *
|
||||||
|
* line_unenrol_students *
|
||||||
|
* *
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function line_unenrol_students_parameters() : \external_function_parameters {
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"id" => new \external_value(PARAM_INT, 'id of specific studyline to enrol into'),
|
||||||
|
"users" => new \external_multiple_structure(new \external_value(PARAM_INT),'list of user ids'),
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return value description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function line_unenrol_students_returns() : \external_description {
|
||||||
|
return success::structure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all or one studyplan the current user is teaching in
|
||||||
|
* @param int $studyplanid ID of studyplan to retrieve
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function line_unenrol_students($id,$users) {
|
||||||
|
global $USER;
|
||||||
|
$userid = $USER->id;
|
||||||
|
|
||||||
|
$o = studyline::find_by_id($id);
|
||||||
|
|
||||||
|
/* NOTE: Perhaps the additional check for the view permission is not needed
|
||||||
|
since there is already a check on roles going on....
|
||||||
|
*/
|
||||||
|
$context = $o->context();
|
||||||
|
webservicehelper::require_capabilities('local/treestudyplan:lineunenrol', $context);
|
||||||
|
|
||||||
|
foreach ($users as $userid) {
|
||||||
|
$o->unenrol($userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success::success()->model();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
* *
|
||||||
|
* line_enrol_students *
|
||||||
|
* *
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function list_line_enrolled_students_parameters() : \external_function_parameters {
|
||||||
|
return new \external_function_parameters( [
|
||||||
|
"id" => new \external_value(PARAM_INT, 'id of specific studyline to list for'),
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return value description for webservice function get_teaching_page
|
||||||
|
*/
|
||||||
|
public static function list_line_enrolled_students_returns() : \external_description {
|
||||||
|
return new \external_single_structure([
|
||||||
|
"userinfo" => new \external_multiple_structure(studyline::enrol_info_structure()),
|
||||||
|
"can_unenrol" => new \external_value(PARAM_BOOL,"True if the requesting user can unenrol students"),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all or one studyplan the current user is teaching in
|
||||||
|
* @param int $studyplanid ID of studyplan to retrieve
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function list_line_enrolled_students($id) {
|
||||||
|
$o = studyline::find_by_id($id);
|
||||||
|
$context = $o->context();
|
||||||
|
webservicehelper::require_capabilities(self::CAP_VIEW, $context);
|
||||||
|
|
||||||
|
$list = [];
|
||||||
|
$p = $o->studyplan();
|
||||||
|
foreach( $p->find_linked_userids() as $userid) {
|
||||||
|
$list[] = $o->enrol_info_model($userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"userinfo" => $list,
|
||||||
|
"can_unenrol" => \has_capability('local/treestudyplan:lineunenrol', $context),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -891,8 +891,10 @@ body.path-local-treestudyplan .editmode-switch-form > * {
|
||||||
.features-treestudyplan .t-item-course .card-body,
|
.features-treestudyplan .t-item-course .card-body,
|
||||||
.features-treestudyplan .r-item-competency .card-body {
|
.features-treestudyplan .r-item-competency .card-body {
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
padding-left: 7px;
|
padding-left: 5px;
|
||||||
padding-right: 7px;
|
padding-right: 5px;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
.path-local-treestudyplan .r-item-invalid .card-body,
|
.path-local-treestudyplan .r-item-invalid .card-body,
|
||||||
.path-local-treestudyplan .t-item-invalid .card-body,
|
.path-local-treestudyplan .t-item-invalid .card-body,
|
||||||
|
@ -1030,8 +1032,8 @@ body.path-local-treestudyplan .editmode-switch-form > * {
|
||||||
font-size: 21px;
|
font-size: 21px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 2px;
|
top: -1px;
|
||||||
margin-top: 2px;
|
position: relative;
|
||||||
}
|
}
|
||||||
.path-local-treestudyplan .r-progress-circle-popup,
|
.path-local-treestudyplan .r-progress-circle-popup,
|
||||||
.features-treestudyplan .r-progress-circle-popup {
|
.features-treestudyplan .r-progress-circle-popup {
|
||||||
|
|
|
@ -68,4 +68,13 @@ $capabilities = [
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'local/treestudyplan:lineunenrol' => [
|
||||||
|
'riskbitmask' => RISK_PERSONAL ,
|
||||||
|
'captype' => 'write',
|
||||||
|
'contextlevel' => CONTEXT_SYSTEM,
|
||||||
|
'archetypes' => array(
|
||||||
|
'manager' => CAP_ALLOW
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -734,4 +734,40 @@ $functions = [
|
||||||
'capabilities' => 'local/treestudyplan:editstudyplan',
|
'capabilities' => 'local/treestudyplan:editstudyplan',
|
||||||
'loginrequired' => true,
|
'loginrequired' => true,
|
||||||
],
|
],
|
||||||
|
'local_treestudyplan_line_enrol_self' => [ // Web service function name.
|
||||||
|
'classname' => '\local_treestudyplan\studentstudyplanservice', // Class containing the external function.
|
||||||
|
'methodname' => 'line_enrol_self', // External function name.
|
||||||
|
'description' => 'Enroll yourself in a study line',
|
||||||
|
'type' => 'write', // Database rights of the web service function (read, write).
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => '',
|
||||||
|
'loginrequired' => true,
|
||||||
|
],
|
||||||
|
'local_treestudyplan_line_enrol_students' => [ // Web service function name.
|
||||||
|
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
|
||||||
|
'methodname' => 'line_enrol_students', // External function name.
|
||||||
|
'description' => 'Enroll a student in a study line',
|
||||||
|
'type' => 'write', // Database rights of the web service function (read, write).
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => '',
|
||||||
|
'loginrequired' => true,
|
||||||
|
],
|
||||||
|
'local_treestudyplan_line_unenrol_students' => [ // Web service function name.
|
||||||
|
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
|
||||||
|
'methodname' => 'line_unenrol_students', // External function name.
|
||||||
|
'description' => 'Enrol a student in a study line',
|
||||||
|
'type' => 'write', // Database rights of the web service function (read, write).
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => 'local/treestudyplan:lineunenrol',
|
||||||
|
'loginrequired' => true,
|
||||||
|
],
|
||||||
|
'local_treestudyplan_list_line_enrolled_students' => [ // Web service function name.
|
||||||
|
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
|
||||||
|
'methodname' => 'list_line_enrolled_students', // External function name.
|
||||||
|
'description' => 'Show students enrolled in an enrollable study line',
|
||||||
|
'type' => 'write', // Database rights of the web service function (read, write).
|
||||||
|
'ajax' => true,
|
||||||
|
'capabilities' => '',
|
||||||
|
'loginrequired' => true,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
|
@ -175,6 +175,8 @@ $string["studyline_name_ph"] = '';
|
||||||
$string["studyline_shortname"] = 'Short name';
|
$string["studyline_shortname"] = 'Short name';
|
||||||
$string["studyline_shortname_ph"] = '';
|
$string["studyline_shortname_ph"] = '';
|
||||||
$string["studyline_color"] = 'Background color';
|
$string["studyline_color"] = 'Background color';
|
||||||
|
$string["studyline_enrollable"] = 'Registration';
|
||||||
|
$string["studyline_enrolroles"] = 'Allowed roles';
|
||||||
|
|
||||||
$string["studyitem_confirm_remove"] = 'Are you sure you want to remove module {$a}?';
|
$string["studyitem_confirm_remove"] = 'Are you sure you want to remove module {$a}?';
|
||||||
$string["editmode_modules_hidden"] = 'Modules hidden in edit mode';
|
$string["editmode_modules_hidden"] = 'Modules hidden in edit mode';
|
||||||
|
@ -469,3 +471,14 @@ $string["line_enrollable:0"] = 'No registration needed';
|
||||||
$string["line_enrollable:1"] = 'Registration by students themselves.';
|
$string["line_enrollable:1"] = 'Registration by students themselves.';
|
||||||
$string["line_enrollable:2"] = 'Registration by user with role';
|
$string["line_enrollable:2"] = 'Registration by user with role';
|
||||||
$string["line_enrollable:3"] = 'Registration by students themeselves or user with role';
|
$string["line_enrollable:3"] = 'Registration by students themeselves or user with role';
|
||||||
|
$string["line_enrol"] = 'Register';
|
||||||
|
$string["line_enrolled"] = 'Registered';
|
||||||
|
$string["line_notenrolled"] = 'Not registered';
|
||||||
|
$string["line_enrol_question"] = 'Do you want to register yourself for {$a}?';
|
||||||
|
$string["line_enrollments"] = 'Registrations';
|
||||||
|
$string["line_enrollment"] = 'Registration';
|
||||||
|
$string["line_cannot_enrol"] = 'You cannot register yourself for this line';
|
||||||
|
$string["line_can_enrol"] = 'You can register for this line';
|
||||||
|
$string["line_is_enrolled"] = 'You are registered for this line';
|
||||||
|
$string["line_enrolled_in"] = 'Registered in {$a}';
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,8 @@ $string["studyline_name_ph"] = '';
|
||||||
$string["studyline_shortname"] = 'Korte naam';
|
$string["studyline_shortname"] = 'Korte naam';
|
||||||
$string["studyline_shortname_ph"] = '';
|
$string["studyline_shortname_ph"] = '';
|
||||||
$string["studyline_color"] = 'Achtergrondkleur';
|
$string["studyline_color"] = 'Achtergrondkleur';
|
||||||
|
$string["studyline_enrollable"] = 'Inschrijven';
|
||||||
|
$string["studyline_enrolroles"] = 'Rollen mogen inschrijven';
|
||||||
|
|
||||||
$string["studyitem_confirm_remove"] = 'Weet je zeker dat je module {$a} wilt verwijderen?';
|
$string["studyitem_confirm_remove"] = 'Weet je zeker dat je module {$a} wilt verwijderen?';
|
||||||
$string["editmode_modules_hidden"] = 'Modules verborgen tijdens bewerken';
|
$string["editmode_modules_hidden"] = 'Modules verborgen tijdens bewerken';
|
||||||
|
@ -469,3 +471,13 @@ $string["line_enrollable:0"] = 'Geen inschrijving nodig';
|
||||||
$string["line_enrollable:1"] = 'Inschrijving door student zelf';
|
$string["line_enrollable:1"] = 'Inschrijving door student zelf';
|
||||||
$string["line_enrollable:2"] = 'Inschrijving door gebruiker met rol';
|
$string["line_enrollable:2"] = 'Inschrijving door gebruiker met rol';
|
||||||
$string["line_enrollable:3"] = 'Inschrijving door student zelf of gebruiker met rol';
|
$string["line_enrollable:3"] = 'Inschrijving door student zelf of gebruiker met rol';
|
||||||
|
$string["line_enrol"] = 'Inschrijven';
|
||||||
|
$string["line_enrolled"] = 'Ingeschreven';
|
||||||
|
$string["line_notenrolled"] = 'Niet ingeschreven';
|
||||||
|
$string["line_enrol_quetsion"] = 'Wil je jezelf inschrijven voor {$a}?';
|
||||||
|
$string["line_enrollments"] = 'Inschrijvingen';
|
||||||
|
$string["line_enrollment"] = 'Inschrijving';
|
||||||
|
$string["line_cannot_enrol"] = 'Je kunt je niet zelf inschrijven voor deze leerlijn';
|
||||||
|
$string["line_can_enrol"] = 'Je kunt jezelf inschrijven voor deze leerlijn';
|
||||||
|
$string["line_is_enrolled"] = 'Je bent ingeschreven voor deze leerlijn';
|
||||||
|
$string["line_enrolled_in"] = 'Ingeschreven in {$a}';
|
|
@ -756,8 +756,11 @@
|
||||||
.t-item-course .card-body,
|
.t-item-course .card-body,
|
||||||
.r-item-competency .card-body {
|
.r-item-competency .card-body {
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
padding-left: 7px;
|
padding-left: 5px;
|
||||||
padding-right: 7px;
|
padding-right: 5px;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.r-item-invalid .card-body,
|
.r-item-invalid .card-body,
|
||||||
|
@ -878,8 +881,8 @@
|
||||||
font-size: 21px /*16pt*/;
|
font-size: 21px /*16pt*/;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 2px;
|
top: -1px;
|
||||||
margin-top: 2px;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.r-progress-circle-popup{
|
.r-progress-circle-popup{
|
||||||
|
|
10
styles.css
10
styles.css
|
@ -891,8 +891,10 @@ body.path-local-treestudyplan .editmode-switch-form > * {
|
||||||
.features-treestudyplan .t-item-course .card-body,
|
.features-treestudyplan .t-item-course .card-body,
|
||||||
.features-treestudyplan .r-item-competency .card-body {
|
.features-treestudyplan .r-item-competency .card-body {
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
padding-left: 7px;
|
padding-left: 5px;
|
||||||
padding-right: 7px;
|
padding-right: 5px;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
.path-local-treestudyplan .r-item-invalid .card-body,
|
.path-local-treestudyplan .r-item-invalid .card-body,
|
||||||
.path-local-treestudyplan .t-item-invalid .card-body,
|
.path-local-treestudyplan .t-item-invalid .card-body,
|
||||||
|
@ -1030,8 +1032,8 @@ body.path-local-treestudyplan .editmode-switch-form > * {
|
||||||
font-size: 21px;
|
font-size: 21px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 2px;
|
top: -1px;
|
||||||
margin-top: 2px;
|
position: relative;
|
||||||
}
|
}
|
||||||
.path-local-treestudyplan .r-progress-circle-popup,
|
.path-local-treestudyplan .r-progress-circle-popup,
|
||||||
.features-treestudyplan .r-progress-circle-popup {
|
.features-treestudyplan .r-progress-circle-popup {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
defined('MOODLE_INTERNAL') || die();
|
defined('MOODLE_INTERNAL') || die();
|
||||||
|
|
||||||
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
|
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
|
||||||
$plugin->version = 2024022505; // YYYYMMDDHH (year, month, day, iteration).
|
$plugin->version = 2024030200; // YYYYMMDDHH (year, month, day, iteration).
|
||||||
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
|
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
|
||||||
|
|
||||||
$plugin->release = "1.1.5";
|
$plugin->release = "1.1.5";
|
||||||
|
|
Loading…
Reference in a new issue