Added results view page

This commit is contained in:
pmk 2018-09-24 11:05:10 +02:00
parent fa285134cb
commit 773d1acdbe
14 changed files with 417 additions and 288 deletions

View File

@ -6,8 +6,7 @@
define([], function () {
return (function (name) {
let handle = name;
return (function (handle) {
let output_enabled = false;
return {

View File

@ -5,15 +5,15 @@
// You can call it anything you like
define([], function () {
let debug_enabled = false;
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);
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);
console.error("Exception from webservice: ", ex.message, "\n",
ex.debuginfo, "\n---Stack trace---\n", ex.backtrace, "\n", ex);
}
},

View File

@ -1,3 +1,4 @@
/*eslint max-len: ["error", { "code": 150 }]*/
/**!
* @preserve Shadow animation 1.11
* http://www.bitstorm.org/jquery/shadow-animation/
@ -8,228 +9,230 @@
define(['jquery'], function (jQuery) {
return jQuery(function($, undefined) {
/**
* 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 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;
}
return result;
}
$.extend(true, $, {
support: {
'rgba': isRGBACapable()
}
});
$.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;
}
});
// 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;
};
}
};
}
// 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];
// 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(', ');
}
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;
// 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();
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;
}
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;
}
});
});

View File

@ -1,3 +1,9 @@
/*eslint no-unused-vars: "off" */
/*eslint max-len: "off" */
/*eslint no-bitwise: "off" */
/*eslint no-cond-assign: "off" */
/*eslint no-new-func: "off" */
/*eslint no-caller: "off" */
/**
* jscolor - JavaScript Color Picker
*
@ -180,7 +186,7 @@ define([], function () {
document.detachEvent('onreadystatechange', arguments.callee);
fireOnce();
}
})
});
// Fallback
window.attachEvent('onload', fireOnce);
@ -624,8 +630,8 @@ define([], function () {
case 'pad':
// if the slider is at the bottom, move it up
switch (jsc.getSliderComponent(thisObj)) {
case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break;
case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break;
case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); } break;
case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); } break;
}
jsc.setPad(thisObj, e, 0, 0);
break;
@ -655,7 +661,7 @@ define([], function () {
jsc.dispatchFineChange(thisObj);
break;
}
}
};
},
@ -809,7 +815,7 @@ define([], function () {
hGrad.type = 'gradient';
hGrad.method = 'linear';
hGrad.angle = '90';
hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0'
hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0';
var hRect = document.createElement(jsc._vmlNS + ':rect');
hRect.style.position = 'absolute';
@ -1818,7 +1824,9 @@ define([], function () {
if (this.value) {
// Try to set the color from the .value option and if unsuccessful,
// export the current color
this.fromString(this.value) || this.exportColor();
if (!this.fromString(this.value)) {
this.exportColor();
}
} else {
this.importColor();
}

View File

@ -1,4 +1,5 @@
/*eslint no-var: "error"*/
/*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
@ -25,7 +26,7 @@ define(['jquery', 'block_gradelevel/jquery.animate-shadow', 'core/str', 'core/aj
}
// make sure all uint type numbers are not able to go below 0
$(document).on('input', "input[type=number].uint", function (evt) {
$(document).on('input', "input[type=number].uint", function (e) {
let $this = $(this);
if ($this.val() < 0) {
$this.val(0);
@ -33,7 +34,7 @@ define(['jquery', 'block_gradelevel/jquery.animate-shadow', 'core/str', 'core/aj
});
// On click handler for add level link
$("a[data-action=addlevel]").on('click', function (evt) {
$("a[data-action=addlevel]").on('click', function (e) {
self.add_levelrow(-255, '', '7F7F7F');
});
@ -80,7 +81,7 @@ define(['jquery', 'block_gradelevel/jquery.animate-shadow', 'core/str', 'core/aj
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);
@ -110,7 +111,7 @@ define(['jquery', 'block_gradelevel/jquery.animate-shadow', 'core/str', 'core/aj
id: Number($this.attr('data-rowid')),
points: -255, // means: delete row
badgecolor: "", // totally irrelevent when requesting a delete
}
};
level_data.push(row);
});
@ -137,7 +138,6 @@ define(['jquery', 'block_gradelevel/jquery.animate-shadow', 'core/str', 'core/aj
}
let $inputs = $tbody.find("input[data-name='points']");
let orig_border = $inputs.css('border-left-color');
$inputs
.animate({ boxShadow: '0px 0px 5px 3px #3FDFCF'}, 400)
.delay(200)

View File

@ -76,7 +76,7 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
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);
@ -155,7 +155,7 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
if (props.image) {
let iconImg = new Image();
iconImg.onload = function () {
let imPos = {
let imPos = {
x: 0, // to be determined later
y: 0, // to be determined later
w: config.size * config.icon.scale,
@ -174,7 +174,7 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
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;
}
@ -200,6 +200,7 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
},
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) => {
@ -215,12 +216,12 @@ define(['jquery', 'core/str', 'core/ajax','block_gradelevel/debugger' ], functio
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 */
},
};

View File

@ -1,10 +1,13 @@
/*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) {
'block_gradelevel/debugger', 'core/modal_factory', 'core/modal_events'],
function ($, str, ajax, mdlcfg, renderbadge, handlers, Debugger, ModalFactory, ModalEvents)
{
let debug = Debugger("skilleditor");
debug.enable();
@ -23,7 +26,7 @@ define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/rend
});
debug.info("Attaching function to addskill link");
$skillset_div.find("a[data-action='addskill']").on('click', function (ev) {
$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 },
@ -40,7 +43,6 @@ define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/rend
renderbadge.setup_badge(this);
});
});
});
@ -50,7 +52,7 @@ define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/rend
let skill_id = $li.data('id');
// Attach edit name pencil
$li.find("a[data-action='editname']").on('click', function (evt) {
$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();
@ -93,16 +95,16 @@ define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/rend
});
// Attach edit icon pencil
$li.find("a[data-action='editicon']").on('click', function (ev) {
$li.find("a[data-action='editicon']").on('click', function (e) {
let $uploader = $("<input type='file' style='display: none;' accept='" + uploadFilter + "'/>");
$uploader.on('change', function (ev) {
ev.stopPropagation();
ev.preventDefault();
let file = ev.originalEvent.target.files[0];
$uploader.on('change', function (e) {
e.stopPropagation();
e.preventDefault();
let file = e.originalEvent.target.files[0];
let fr = new FileReader();
$(fr).on('load', function (ev) {
let dataURI = ev.target.result;
$(fr).on('load', function (e) {
let dataURI = e.target.result;
let promises = ajax.call([{
methodname: 'block_gradelevel_update_skill',
@ -134,7 +136,8 @@ define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/rend
});
// Attach edit levels link
$li.find("a[data-action='editlevels']").attr('href', mdlcfg.wwwroot + "/blocks/gradelevel/cfg_skilllevels.php?skill_id=" + skill_id);
$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 () {
@ -171,26 +174,6 @@ define(['jquery', 'core/str', 'core/ajax', 'core/config', 'block_gradelevel/rend
});
},
success_refill_table: function success_refill_table(response) {
//console.info("Response from webservice: ", response);
let $tbody = $skill_table.find('tbody');
$tbody.empty();
for (let idx in response) {
let lvl = response[idx];
//console.info("Level:", lvl);
self.add_levelrow(lvl.id, lvl.points, lvl.badgecolor);
}
},
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;
});

View File

@ -71,7 +71,7 @@ class block_gradelevel extends block_base {
if(has_capability('block/gradelevel:viewresults', $coursecontext))
{
$this->content->footer .= "\n<div class='teachermode'><a href='#'>".get_string('teacher_view_results','block_gradelevel')."</a></div>";
$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;

View File

@ -6,14 +6,14 @@ require_once($CFG->dirroot.'/grade/querylib.php');
class block_gradelevel_levelset {
const UNDEFINED_BADGE_COLOR="#3F3F3F";
const NULL_BADGE_COLOR = "#000000";
const NULL_BADGE_COLOR = "#320000";
const DEFAULT_ICON = "/blocks/gradelevel/pix/undefinedskill.svg";
const GLOBAL_DEFAULTS = array(
0 => "#000000",
0 => "#320000",
250 => "#2ad4ff", // + 250
750 => "#cd7f32", // + 500
1750 => "#a6a6a6", // + 1000
1750 => "#92A1A6", // + 1000
2750 => "#f6ae00", // + 2000
);
@ -244,13 +244,11 @@ class block_gradelevel_levelset {
{
if(!$DB->update_record('block_gradelevel_levelset',$this->data)){
print_error('updateerror', 'block_gradelevel');
error_log('UPDATE-ERROR\n', 3, '/tmp/moodledevlog.log');
}
}
else
{
print_error('datarowchanged_error', 'block_gradelevel');
error_log('DATAROW-INVALID\n', 3, '/tmp/moodledevlog.log');
}
}

View File

@ -8,7 +8,7 @@ require_once($CFG->dirroot.'/grade/querylib.php');
class block_gradelevel_skillmgmtservice extends external_api
{
const DEBUG = true; // enable debug logging
const DEBUG = false; // enable debug logging
const DEMOBADGE_SIZE = 150; // size of demo badge
private static function log($message)
@ -458,7 +458,7 @@ class block_gradelevel_skillmgmtservice extends external_api
if(!$single){
$s .= "<a data-action='editlevels' href='#'>";
if(count($skill->list_courses()) ){
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>";
}
}

View File

@ -69,20 +69,14 @@ class block_gradelevel_edit_form extends block_edit_form {
$currentskill = block_gradelevel_levelset::find_by_course($COURSE->id);
if(isset($currentskill))
{
$this->debug("deetaching...");
$currentskill->detach_course($COURSE->id);
}
$skill = block_gradelevel_levelset::find_by_id($data->attached_skill);
if(isset($skill)){
$this->debug("attaching...");
$skill->attach_course($COURSE->id);
}
}
}
private function debug($msg)
{
error_log($msg, 3, '/tmp/moodledevlog.log');
}
}

View File

@ -5,7 +5,7 @@ $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'] = 'Next level: ';
$string['levelup_at'] = 'Progress: ';
$string['levelup_done'] = 'Complete';
$string['unattached_course'] = 'Please attach this course to a skill in the block settings';
@ -20,6 +20,9 @@ $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";

View File

@ -94,6 +94,44 @@ 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;

102
view-results.php Normal file
View File

@ -0,0 +1,102 @@
<?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");
}
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 = $skill->get_levelset_grade($usr->id);
$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>";
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></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 = $skill->get_levelset_grade($usr->id);
$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>";
print "<div class='pointinfo'>".get_string('levelup_at','block_gradelevel')." <span class='currentpoints'>{$level_info->points_in_level}</span>/<span class='leveluppoints'>{$level_info->levelup_total}</span></div>";
print "</li>";
}
print "</ul>";
print "</div>";
print $OUTPUT->footer();