Commit a66f2e51 authored by mathieso's avatar mathieso

Fight the rubricy bugs!

parent 34d43cd9
......@@ -12640,8 +12640,11 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
*/
rubricItemComplete() {
let $collapseButton = $(this.$refs.collapseButton);
// console.log("$collapseButton", $collapseButton);
window.collapseButton = $collapseButton;
//Only collapse if not already collapsed.
if ($collapseButton.find('span.glyphicon').hasClass('glyphicon-triangle-top')) {
if ($collapseButton.find('span.glyphicon').hasClass('glyphicon-triangle-bottom')) {
// console.log("click collapse");
$collapseButton.click();
}
},
......@@ -12656,7 +12659,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
* User wants to forget choices.
*/
clearChoice(event) {
console.log("clear event", event);
// console.log("clear event", event);
// Show the RI choices.
const target = $(event.target);
var $panel = target.closest('.panel');
......@@ -12687,7 +12690,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
if (chosen.length === 0) {
result = '(Nothing chosen)';
} else {
result = chosen.join('<br>');
result = chosen.join("");
}
return '<small>' + result + '</small>';
// let chosen = [];
......@@ -12808,6 +12811,7 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
* Grader clicked an option. Add or remove it from the submission's choices.
*/
optionClicked() {
// console.log("optionClicked");
//Get the existing choices for this submission.
let submissionRubricItemChoices = this.getExistingChoicesThisSubmission();
//Have any choices for this rubric item been chosen?
......@@ -12817,14 +12821,17 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
}
//Get grader's existing choices for this rubric item.
let choicesThisRubricItem = submissionRubricItemChoices[this.rubricItemId];
// console.log("choicesThisRubricItem", choicesThisRubricItem);
//Get the index of this option in the choices array, -1 if not there.
let optionIndexInChoices = choicesThisRubricItem.indexOf(this.responseOptionId);
// console.log("optionIndexInChoices", optionIndexInChoices);
if (optionIndexInChoices === -1) {
//Not found - add it.
choicesThisRubricItem.push(this.responseOptionId);
//Does this autocollapse the rubric item?
let option = window.responseOptions[this.responseOptionId];
if (option.completes) {
// console.log("emit rubricItemComplete");
this.$emit('rubricItemComplete');
}
} else {
......@@ -13205,50 +13212,41 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
message += overallEvalMessage; // + '<br><br>';
//Chosen rubric responses.
// Sort them by order of RIs they're in, in the exercise.
const rubricItemChoicesUnsorted = window.submissions[this.submissionId].rubricItemChoices;
console.log("rubricItemChoicesUnsorted", rubricItemChoicesUnsorted);
// Get the options for that RI.
// const rubricItemOptions = window.rubricItems[rubricItemId].responseOptionIds;
let graderChoices = window.submissions[this.submissionId].rubricItemChoices;
console.log("graderChoices", graderChoices);
const exerciseId = window.submissions[this.submissionId].exerciseId;
console.log("exerciseId", exerciseId);
const exerciseRubricItemIds = window.exercises[exerciseId].rubricItemIds;
console.log("exerciseRubricItemIds", exerciseRubricItemIds);
// The target array.
const graderChoices = [];
message += '<ul>';
// Run through the RIs in the order they appear for the exercise.
for (let exerciseRubricItemIdIndex = 0; exerciseRubricItemIdIndex < exerciseRubricItemIds.length; exerciseRubricItemIdIndex++) {
// if (exerciseRubricItemIds[exerciseRubricItemIdIndex]) {
// Get a rubric item id that is in the exercise.
const rubricItemId = exerciseRubricItemIds[exerciseRubricItemIdIndex];
console.log("start outer loop rubricItemId", rubricItemId);
// Find this one in the unsorted array.
for (const rubricItemId in rubricItemChoicesUnsorted) {
console.log("inner loop rubricItemId", rubricItemId);
if (rubricItemChoicesUnsorted[rubricItemId]) {
console.log("inner loop found rubricItemChoicesUnsorted[rubricItemId]", rubricItemChoicesUnsorted[rubricItemId]);
graderChoices.push(rubricItemChoicesUnsorted[rubricItemId]);
break;
let graderResponseOptionsChoicesForRI = graderChoices[rubricItemId];
console.log("graderResponseOptionsChoicesForRI", graderResponseOptionsChoicesForRI);
// Grader might not have chosen anything for the rubric item.
if (graderResponseOptionsChoicesForRI) {
for (let roArrayIndex = 0; roArrayIndex < graderResponseOptionsChoicesForRI.length; roArrayIndex++) {
const responseOptionId = graderResponseOptionsChoicesForRI[roArrayIndex];
console.log("responseOptionId", responseOptionId);
let responseText = window.responseOptions[responseOptionId].response;
if (isCanSeeNames) {
responseText = this.replaceStudentNameTokens(responseText, student);
} else {
responseText = this.killStudentNameTokens(responseText);
}
console.log("responseText", responseText);
message += `<li>${responseText}</li>`;
// Add response options to the output.
}
}
// }
}
console.log("graderChoices", graderChoices);
return;
// Get the options for that RI.
// const rubricItemOptions = window.rubricItems[rubricItemId].responseOptionIds;
message += '<ul>';
let that = this;
graderChoices.forEach(function (choicesForRubricItem) {
choicesForRubricItem.forEach(function (responseOptionId) {
let responseText = window.responseOptions[responseOptionId].response;
if (isCanSeeNames) {
responseText = that.replaceStudentNameTokens(responseText, student);
} else {
responseText = that.killStudentNameTokens(responseText);
}
message += `<li>${responseText}</li>`;
});
});
//Run through new options.
//The options will be out of order. Not with their rubric item brethren.
let that = this;
this.$refs.rubricItem.forEach(ri => {
ri.newOptions.forEach(newOption => {
if (newOption.chosen) {
......@@ -29834,7 +29832,7 @@ module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c
return _vm.clearChoice($event)
}
}
}, [_vm._v("Clear")]), _vm._v(" "), _c('div', {
}, [_vm._v("")]), _vm._v(" "), _c('div', {
staticClass: "pull-right"
}, [_c('button', {
ref: "collapseButton",
......
This diff is collapsed.
......@@ -11,7 +11,7 @@
v-show="isAnyOptionSelected"
@click.stop="clearChoice"
title="Clear your choice"
>Clear</span>
>&#x2718;</span>
<div class="pull-right">
<!--Button to collapse/expand rubric item option deets.
Used Bootstrap animations rather than Vue transitions, because I like the effect.
......@@ -235,8 +235,11 @@
*/
rubricItemComplete() {
let $collapseButton = $(this.$refs.collapseButton);
// console.log("$collapseButton", $collapseButton);
window.collapseButton = $collapseButton;
//Only collapse if not already collapsed.
if ( $collapseButton.find('span.glyphicon').hasClass('glyphicon-triangle-top') ) {
if ( $collapseButton.find('span.glyphicon').hasClass('glyphicon-triangle-bottom') ) {
// console.log("click collapse");
$collapseButton.click();
}
},
......@@ -251,7 +254,7 @@
* User wants to forget choices.
*/
clearChoice(event) {
console.log("clear event", event);
// console.log("clear event", event);
// Show the RI choices.
const target = $(event.target);
var $panel = target.closest('.panel');
......@@ -283,7 +286,7 @@
result = '(Nothing chosen)';
}
else {
result = chosen.join('<br>');
result = chosen.join("");
}
return '<small>' + result + '</small>';
// let chosen = [];
......
......@@ -76,6 +76,7 @@
* Grader clicked an option. Add or remove it from the submission's choices.
*/
optionClicked() {
// console.log("optionClicked");
//Get the existing choices for this submission.
let submissionRubricItemChoices = this.getExistingChoicesThisSubmission();
//Have any choices for this rubric item been chosen?
......@@ -85,14 +86,17 @@
}
//Get grader's existing choices for this rubric item.
let choicesThisRubricItem = submissionRubricItemChoices[this.rubricItemId];
// console.log("choicesThisRubricItem", choicesThisRubricItem);
//Get the index of this option in the choices array, -1 if not there.
let optionIndexInChoices = choicesThisRubricItem.indexOf(this.responseOptionId);
// console.log("optionIndexInChoices", optionIndexInChoices);
if ( optionIndexInChoices === -1 ) {
//Not found - add it.
choicesThisRubricItem.push(this.responseOptionId);
//Does this autocollapse the rubric item?
let option = window.responseOptions[this.responseOptionId];
if (option.completes) {
// console.log("emit rubricItemComplete");
this.$emit('rubricItemComplete');
}
}
......
......@@ -345,7 +345,7 @@
// },
//User clicked the Create message button.
createMessage() {
console.log('createMessage');
console.log('createMessage');
let message = '';
const student = window.students[
window.submissions[this.submissionId].studentId
......@@ -375,54 +375,50 @@
message += overallEvalMessage; // + '<br><br>';
//Chosen rubric responses.
// Sort them by order of RIs they're in, in the exercise.
const rubricItemChoicesUnsorted = window.submissions[this.submissionId].rubricItemChoices;
console.log("rubricItemChoicesUnsorted", rubricItemChoicesUnsorted);
// Get the options for that RI.
// const rubricItemOptions = window.rubricItems[rubricItemId].responseOptionIds;
let graderChoices = window.submissions[this.submissionId].rubricItemChoices;
console.log("graderChoices", graderChoices);
const exerciseId = window.submissions[this.submissionId].exerciseId;
console.log("exerciseId", exerciseId);
const exerciseRubricItemIds = window.exercises[exerciseId].rubricItemIds;
console.log("exerciseRubricItemIds", exerciseRubricItemIds);
// The target array.
const graderChoices = [];
for (let exerciseRubricItemIdIndex = 0;
exerciseRubricItemIdIndex < exerciseRubricItemIds.length;
exerciseRubricItemIdIndex ++) {
// if (exerciseRubricItemIds[exerciseRubricItemIdIndex]) {
// Get a rubric item id that is in the exercise.
const rubricItemId = exerciseRubricItemIds[exerciseRubricItemIdIndex];
message += '<ul>';
// Run through the RIs in the order they appear for the exercise.
for (
let exerciseRubricItemIdIndex = 0;
exerciseRubricItemIdIndex < exerciseRubricItemIds.length;
exerciseRubricItemIdIndex ++
) {
const rubricItemId = exerciseRubricItemIds[exerciseRubricItemIdIndex];
console.log("start outer loop rubricItemId", rubricItemId);
// Find this one in the unsorted array.
for (const rubricItemId in rubricItemChoicesUnsorted) {
console.log("inner loop rubricItemId", rubricItemId);
if (rubricItemChoicesUnsorted[rubricItemId]) {
console.log("inner loop found rubricItemChoicesUnsorted[rubricItemId]",
rubricItemChoicesUnsorted[rubricItemId]);
graderChoices.push(rubricItemChoicesUnsorted[rubricItemId]);
break;
let graderResponseOptionsChoicesForRI = graderChoices[rubricItemId];
console.log("graderResponseOptionsChoicesForRI", graderResponseOptionsChoicesForRI);
// Grader might not have chosen anything for the rubric item.
if (graderResponseOptionsChoicesForRI) {
for (
let roArrayIndex = 0;
roArrayIndex < graderResponseOptionsChoicesForRI.length;
roArrayIndex++
) {
const responseOptionId = graderResponseOptionsChoicesForRI[roArrayIndex];
console.log("responseOptionId", responseOptionId);
let responseText = window.responseOptions[responseOptionId].response;
if (isCanSeeNames) {
responseText = this.replaceStudentNameTokens(responseText, student);
}
else {
responseText = this.killStudentNameTokens(responseText);
}
console.log("responseText", responseText);
message += `<li>${responseText}</li>`;
// Add response options to the output.
}
// }
}
}
console.log("graderChoices", graderChoices);
return;
// Get the options for that RI.
// const rubricItemOptions = window.rubricItems[rubricItemId].responseOptionIds;
message += '<ul>';
let that = this;
graderChoices.forEach( function(choicesForRubricItem) {
choicesForRubricItem.forEach( function(responseOptionId){
let responseText = window.responseOptions[responseOptionId].response;
if (isCanSeeNames) {
responseText = that.replaceStudentNameTokens(responseText, student);
}
else {
responseText = that.killStudentNameTokens(responseText);
}
message += `<li>${responseText}</li>`;
});
});
//Run through new options.
//The options will be out of order. Not with their rubric item brethren.
let that = this;
this.$refs.rubricItem.forEach( ri => {
ri.newOptions.forEach( newOption => {
if ( newOption.chosen ) {
......
......@@ -3,8 +3,7 @@ $(document).ready(function () {
//When js-collapse-panel-body elements are nested, propagation causes problems.
e.stopPropagation();
e.preventDefault();
console.log("collapse clicked");
// console.log("collapse clicked");
var $this = $(this);
var $panel = $this.closest('.panel');
var panelBody = $panel.find('.panel-body');
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -883,17 +883,6 @@ eval("var fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules
/***/ }),
/***/ "./node_modules/core-js/internals/inherit-if-required.js":
/*!***************************************************************!*\
!*** ./node_modules/core-js/internals/inherit-if-required.js ***!
\***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
eval("var isObject = __webpack_require__(/*! ../internals/is-object */ \"./node_modules/core-js/internals/is-object.js\");\nvar setPrototypeOf = __webpack_require__(/*! ../internals/object-set-prototype-of */ \"./node_modules/core-js/internals/object-set-prototype-of.js\");\n\n// makes subclassing work correct for wrapped built-ins\nmodule.exports = function ($this, dummy, Wrapper) {\n var NewTarget, NewTargetPrototype;\n if (\n // it can work only with native `setPrototypeOf`\n setPrototypeOf &&\n // we haven't completely correct pre-ES6 way for getting `new.target`, so use this\n typeof (NewTarget = dummy.constructor) == 'function' &&\n NewTarget !== Wrapper &&\n isObject(NewTargetPrototype = NewTarget.prototype) &&\n NewTargetPrototype !== Wrapper.prototype\n ) setPrototypeOf($this, NewTargetPrototype);\n return $this;\n};\n\n\n//# sourceURL=webpack:///./node_modules/core-js/internals/inherit-if-required.js?");
/***/ }),
/***/ "./node_modules/core-js/internals/inspect-source.js":
/*!**********************************************************!*\
!*** ./node_modules/core-js/internals/inspect-source.js ***!
......@@ -1689,18 +1678,6 @@ eval("var DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./
/***/ }),
/***/ "./node_modules/core-js/modules/es.number.constructor.js":
/*!***************************************************************!*\
!*** ./node_modules/core-js/modules/es.number.constructor.js ***!
\***************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval("\nvar DESCRIPTORS = __webpack_require__(/*! ../internals/descriptors */ \"./node_modules/core-js/internals/descriptors.js\");\nvar global = __webpack_require__(/*! ../internals/global */ \"./node_modules/core-js/internals/global.js\");\nvar isForced = __webpack_require__(/*! ../internals/is-forced */ \"./node_modules/core-js/internals/is-forced.js\");\nvar redefine = __webpack_require__(/*! ../internals/redefine */ \"./node_modules/core-js/internals/redefine.js\");\nvar has = __webpack_require__(/*! ../internals/has */ \"./node_modules/core-js/internals/has.js\");\nvar classof = __webpack_require__(/*! ../internals/classof-raw */ \"./node_modules/core-js/internals/classof-raw.js\");\nvar inheritIfRequired = __webpack_require__(/*! ../internals/inherit-if-required */ \"./node_modules/core-js/internals/inherit-if-required.js\");\nvar toPrimitive = __webpack_require__(/*! ../internals/to-primitive */ \"./node_modules/core-js/internals/to-primitive.js\");\nvar fails = __webpack_require__(/*! ../internals/fails */ \"./node_modules/core-js/internals/fails.js\");\nvar create = __webpack_require__(/*! ../internals/object-create */ \"./node_modules/core-js/internals/object-create.js\");\nvar getOwnPropertyNames = __webpack_require__(/*! ../internals/object-get-own-property-names */ \"./node_modules/core-js/internals/object-get-own-property-names.js\").f;\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ../internals/object-get-own-property-descriptor */ \"./node_modules/core-js/internals/object-get-own-property-descriptor.js\").f;\nvar defineProperty = __webpack_require__(/*! ../internals/object-define-property */ \"./node_modules/core-js/internals/object-define-property.js\").f;\nvar trim = __webpack_require__(/*! ../internals/string-trim */ \"./node_modules/core-js/internals/string-trim.js\").trim;\n\nvar NUMBER = 'Number';\nvar NativeNumber = global[NUMBER];\nvar NumberPrototype = NativeNumber.prototype;\n\n// Opera ~12 has broken Object#toString\nvar BROKEN_CLASSOF = classof(create(NumberPrototype)) == NUMBER;\n\n// `ToNumber` abstract operation\n// https://tc39.github.io/ecma262/#sec-tonumber\nvar toNumber = function (argument) {\n var it = toPrimitive(argument, false);\n var first, third, radix, maxCode, digits, length, index, code;\n if (typeof it == 'string' && it.length > 2) {\n it = trim(it);\n first = it.charCodeAt(0);\n if (first === 43 || first === 45) {\n third = it.charCodeAt(2);\n if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix\n } else if (first === 48) {\n switch (it.charCodeAt(1)) {\n case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i\n case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i\n default: return +it;\n }\n digits = it.slice(2);\n length = digits.length;\n for (index = 0; index < length; index++) {\n code = digits.charCodeAt(index);\n // parseInt parses a string to a first unavailable symbol\n // but ToNumber should return NaN if a string contains unavailable symbols\n if (code < 48 || code > maxCode) return NaN;\n } return parseInt(digits, radix);\n }\n } return +it;\n};\n\n// `Number` constructor\n// https://tc39.github.io/ecma262/#sec-number-constructor\nif (isForced(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {\n var NumberWrapper = function Number(value) {\n var it = arguments.length < 1 ? 0 : value;\n var dummy = this;\n return dummy instanceof NumberWrapper\n // check on 1..constructor(foo) case\n && (BROKEN_CLASSOF ? fails(function () { NumberPrototype.valueOf.call(dummy); }) : classof(dummy) != NUMBER)\n ? inheritIfRequired(new NativeNumber(toNumber(it)), dummy, NumberWrapper) : toNumber(it);\n };\n for (var keys = DESCRIPTORS ? getOwnPropertyNames(NativeNumber) : (\n // ES3:\n 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n // ES2015 (in case, if modules with ES2015 Number statics required before):\n 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n ).split(','), j = 0, key; keys.length > j; j++) {\n if (has(NativeNumber, key = keys[j]) && !has(NumberWrapper, key)) {\n defineProperty(NumberWrapper, key, getOwnPropertyDescriptor(NativeNumber, key));\n }\n }\n NumberWrapper.prototype = NumberPrototype;\n NumberPrototype.constructor = NumberWrapper;\n redefine(global, NUMBER, NumberWrapper);\n}\n\n\n//# sourceURL=webpack:///./node_modules/core-js/modules/es.number.constructor.js?");
/***/ }),
/***/ "./node_modules/core-js/modules/es.object.assign.js":
/*!**********************************************************!*\
!*** ./node_modules/core-js/modules/es.object.assign.js ***!
<template>
<div>
<h2>Exercise</h2>
<div id="app">
<exercise :exerciseId="exerciseId"></exercise>
</div>
......
......@@ -10,7 +10,10 @@
title="Create a new rubric item"
@click.stop="createRubricItem">Create</button>
</p>
<div id="rubric-item-list" v-if="rubricItemsThisExercise.length">
<p v-if="rubricItemsThisExercise.length == 0">
No rubric items for this exercise. Yet.
</p>
<div id="rubric-item-list">
<rubric-item-summary
v-for="rubricItem in rubricItemsThisExercise"
:rubricItem="rubricItem"
......@@ -19,9 +22,6 @@
v-on:edit-rubric-item="editRubricItem"
></rubric-item-summary>
</div>
<p v-else>
No rubric items for this exercise. Yet.
</p>
<p>
<button class="button button--primary" type="button"
title="Choose an existing rubric item for this exercise"
......@@ -78,20 +78,20 @@
},
exerciseId() {
const id = this.$store.getters.getCurrentExerciseId();
// console.log("exercise computed exerciseId", id);
console.log("exercise computed exerciseId", id);
return id;
},
rubricItemsThisExercise() {
// console.log("start rubricItemsThisExercise");
// console.log("this.$store", this.$store);
console.log("start rubricItemsThisExercise");
console.log("this.$store", this.$store);
const currentExerciseId = this.$store.getters.getCurrentExerciseId();
// Displaying afore data has loaded, don't want to continue.
if (currentExerciseId === null) {
return [];
}
// console.log("rubricItemsThisExercise currentExerciseId", currentExerciseId);
console.log("rubricItemsThisExercise currentExerciseId", currentExerciseId);
let rubricItems = this.$store.getters.getExerciseRubricItems(currentExerciseId);
// console.log("rubricItemsThisExercise rubricItems", rubricItems);
console.log("rubricItemsThisExercise rubricItems", rubricItems);
return rubricItems;
},
rubricItemIdsThisExercise() {
......@@ -123,19 +123,24 @@
this.$modal.show("item-selector-modal");
},
createRubricItem() {
console.log("createRubricItem");
// Get clone of new item template.
let newRubicItem = this.$store.getters.getNewRubricItemTemplate();
console.log("newRubicItem", newRubicItem);
// Set a unique id for the new item.
newRubicItem.rubricItemId = "new" + this.numNewRubricItemsCreated;
this.numNewRubricItemsCreated ++;
// Ask store to make it.
this.$store.dispatch("addRubricItemAction", newRubicItem);
// Add it to the current exercise.
console.log("this.exerciseId", this.exerciseId);
let params = {
exerciseId: this.exerciseId,
rubricItemId: newRubicItem.rubricItemId
};
console.log("params", params);
this.$store.dispatch("addRubricItemIdToExerciseAction", params);
this.$forceUpdate();
},
editRubricItem(rubricItemId) {
// console.log("exercise call editRubricItem");
......
......@@ -127,11 +127,11 @@
}
}
},
props: {
responseOption: Object,
rubricItemId: Number,
exerciseId: Number
},
props: [
"responseOption",
"rubricItemId",
"exerciseId"
],
computed: {
},
methods: {
......
......@@ -23,10 +23,10 @@ import CKEditor from '@ckeditor/ckeditor5-vue';
const exerciseId = Drupal.behaviors.rubricItemGui.getExerciseIdFromUrl();
if (exerciseId === null) {
// TODO make real
alert("No node number:" + window.location.href);
alert("No node number or add:" + window.location.href);
return;
}
// Store in window for Vuex to use.
// Store in window for Vuex to use. Could be 0, for new exercise.
window.exerciseId = exerciseId;
// Adapted from https://vegibit.com/vue-sibling-component-communication/
window.eventBus = new Vue();
......@@ -43,7 +43,7 @@ import CKEditor from '@ckeditor/ckeditor5-vue';
// Get the data to send.
let allTheThings = window.vueInstance.$store.getters.getAllTheThings();
jQuery("input[name='rubric_item_chooser_return']").val(JSON.stringify(allTheThings));
// console.log("allTheThings", allTheThings);
console.log("allTheThings", allTheThings);
// e.preventDefault();
});
window.vueInstance = vueInstance;
......@@ -51,21 +51,25 @@ import CKEditor from '@ckeditor/ckeditor5-vue';
});
},
/**
* Extract the exercise id from the URL.
* Extract the exercise id from the URL, or 0 for a new record.
* @return {null} | {number}
*/
getExerciseIdFromUrl() {
let urlComponents = window.location.href.split("/");
let nodeNumber = null;
let result = null;
for (let i = 0; i < urlComponents.length - 2; i++) {
if (urlComponents[i] === "node") {
if (urlComponents[i + 2].slice(0, 4) === "edit") {
nodeNumber = urlComponents[i + 1];
result = urlComponents[i + 1];
break;
}
if (urlComponents[i + 1].slice(0, 4) === "add") {
result = 0;
break;
}
}
}
return nodeNumber;
return result;
}
}
})(jQuery, Drupal);
......
......@@ -23,6 +23,7 @@ export default new Vuex.Store({
appliesToExerciseIds: []
},
exercises: [],
// 0 for new exercise.
exerciseId: null,
// exerciseRubricItemIds: [],
rubricItemCategories: [],
......@@ -161,6 +162,12 @@ export default new Vuex.Store({
// console.log("removeRubricItemFromExercise params", params);
// console.log("state.exercises", state.exercises);
let targetExerciseId = params.exerciseId;
if (!targetExerciseId || isNaN(targetExerciseId)) {
// TODO make real
alert(`removeRubricItemFromExercise unknown exer id: ${targetExerciseId}`);
return;
}
let targetRubricItemId = params.rubricItemId;
// Find the exercise.
let targetExercise = state.exercises.find(
......@@ -243,10 +250,11 @@ export default new Vuex.Store({
responseOption.appliesToExerciseIds.push(exerciseId);
},
addNewRubricItem(state, rubricItem) {
// console.log("veux addNewRubricItem ", rubricItem);
console.log("veux addNewRubricItem ", rubricItem);
state.rubricItems.push(rubricItem);
},
addRubricItemIdToExercise(state, params) {
console.log("addRubricItemIdToExercise params ", params);
let targetExerciseId = params.exerciseId;
let rubricItemId = params.rubricItemId;
// Find the exercise.
......@@ -261,6 +269,7 @@ export default new Vuex.Store({
return;
}
targetExercise.rubricItemIds.push(rubricItemId);
console.log("targetExercise", targetExercise);
},
addResponseOptionIdToRubricItem(state, params) {
let rubricItemIdToFind = params.rubricItemId;
......@@ -402,13 +411,24 @@ export default new Vuex.Store({
}
},
loadData(state, params) {
// console.log("loadData params", params);
state.exerciseId = window.exerciseId;
console.log("loadData params", params);
console.log("window.exerciseId", window.exerciseId);
// 0 for new.
state.exerciseId = parseInt(window.exerciseId);
state.exercises = params.exercises;
if (state.exerciseId === 0) {
// New exercise, make a place for it.
state.exercises.push({
exerciseId: 0,
name: "New exercise",
rubricItemIds: []
});
}
state.rubricItemCategories = params.rubricItemCategories;
state.rubricItems = params.rubricItems;
state.responseOptions = params.responseOptions;
state.dataLoaded = true;
console.log("loadData state.exercises", state.exercises);
// state.exerciseRubricItemIds = params.exerciseRubricItemIds;
}
},
......@@ -428,7 +448,7 @@ export default new Vuex.Store({
})
.then(function (response) {
// handle success
// console.log("axios response", response);
console.log("axios response", response);
context.commit('loadData', response.data);
})
.catch(function (error) {
......
......@@ -64,6 +64,11 @@ F/b allows building for dist. Why not exercise RI editor?
Save and edit fior exercises
Skip submissons for exercises/students that don't exist anymore. Or student blocked.
Authors use skilling input filter.
......
......@@ -234,7 +234,8 @@ function skilling_alter_exercise_edit_form(&$form, FormStateInterface $form_stat
// Add rubric item GUI.
// $form['#attached']['library'][] = 'skilling/rubric-item-chooser';
$form['rubric_item_chooser'] = [
'#markup' => '<div id="app"></div>',
'#markup' => '<div id="app"></div>',
'#weight' => 100,
'#attached' => [
'library' => [
'skilling/rubric-item-chooser',
......
......@@ -101,22 +101,25 @@ class RubricItemGuiController extends ControllerBase {
$result = [];
// What is the exercise?
$exerciseId = $request->query->get('exerciseId');
if (!$exerciseId || !is_numeric($exerciseId)) {
if (!is_numeric($exerciseId) ) {
throw new AccessDeniedException('Access denied');
}
$exerciseId = (int)$exerciseId;
$result['exerciseId'] = $exerciseId;
// Load it.
/** @var \Drupal\node\NodeInterface $exercise */
$exercise = $this->entityTypeManager->getStorage('node')
->load($exerciseId);
if (!$exercise) {
throw new AccessDeniedException('Access denied');
}
// Is the node an exercise?
if ($exercise->bundle() !== SkillingConstants::EXERCISE_CONTENT_TYPE) {
throw new AccessDeniedException('Access denied');
// $exerciseIdOrAdd = (int)$exerciseIdOrAdd;
// $result['exerciseIdOrAdd'] = $exerciseIdOrAdd;
if ($exerciseId != 0) {
// Load it.
/** @var \Drupal\node\NodeInterface $exercise */
$exercise = $this->entityTypeManager->getStorage('node')
->load($exerciseId);
if (!$exercise) {
throw new AccessDeniedException('Access denied');
}
// Is the node an exercise?
if ($exercise->bundle() !== SkillingConstants::EXERCISE_CONTENT_TYPE) {
throw new AccessDeniedException('Access denied');
}
}
//
// Get all the exercise names.
$exercisesJson = [];
$allExerciseIds = $this->entityTypeManager->getStorage('node')
......@@ -127,14 +130,29 @@ class RubricItemGuiController extends ControllerBase {
->loadMultiple($allExerciseIds);
/** @var \Drupal\node\NodeInterface $oneExercise */
foreach ($allExercises as $oneExercise) {
if (!$oneExercise) {
// In case does not exist.
continue;
}
$exerciseJson = [
'exerciseId' => (int)$oneExercise->id(),
'name' => $oneExercise->getTitle(),
];
$exerciseRIIdsJson = [];
$exerciseRIIds = $oneExercise->get(SkillingConstants::FIELD_RUBRIC_ITEMS)->getValue();
// Extract the RI nids from the reference field.
$exerciseRIIds = [];
$exerciseRIIdRecords = $oneExercise->get(SkillingConstants::FIELD_RUBRIC_ITEMS)->getValue();
foreach($exerciseRIIdRecords as $exerciseRIIdRecord) {
$exerciseRIIds[] = $exerciseRIIdRecord['target_id'];
}
foreach ($exerciseRIIds as $exerciseRIId) {
$exerciseRIIdsJson[] = (int)$exerciseRIId['target_id'];
// Is rubric item real?
$rubricItem = $this->entityTypeManager->getStorage('node')
->load($exerciseRIId);
if (!$rubricItem) {
continue;
}