diff --git a/app/assets/javascripts/annotations_helpers.js b/app/assets/javascripts/annotations_helpers.js new file mode 100644 index 000000000..c782543e9 --- /dev/null +++ b/app/assets/javascripts/annotations_helpers.js @@ -0,0 +1,142 @@ +/* following paths/functions for annotations */ +var sharedCommentsPath = basePath + "/shared_comments"; + +var createPath = basePath + ".json"; +var updatePath = function (ann) { + return [basePath, "/", ann.id, ".json"].join(""); +}; +var deletePath = updatePath; + +function getSharedCommentsForProblem(problem_id) { + return localCache['shared_comments'][problem_id]?.map( + (annotation) => { + return {label: annotation.comment ?? annotation, value: annotation} + } + ) +} + +var selectAnnotation = box => (e, ui) => { + const {value} = ui.item; + + const score = value.value ?? 0; + box.find('#comment-score').val(score); + + const $textarea = box.find("#comment-textarea"); + M.textareaAutoResize($textarea); + + return false; +} + +function focusAnnotation( event, ui ) { + $(this).val(ui.item.label); + return false; +} + +// retrieve shared comments +// also retrieves annotation id to allow easy deletion in the future +function retrieveSharedComments(cb) { + $.getJSON(sharedCommentsPath, function (data) { + localCache['shared_comments'] = {}; + data.forEach(e => { + if (!e.problem_id) + return; + localCache['shared_comments'][e.problem_id] ||= []; + localCache['shared_comments'][e.problem_id].push(e); + }); + cb?.(); + }); +} + +function purgeCurrentPageCache() { + localCache[currentHeaderPos] = { + codeBox: `
${$('#code-box').html()}
`, + pdf: false, + symbolTree: `
${$('#symbol-tree-box').html()}
`, + versionLinks: `${$('#version-links').html()}`, + versionDropdown: `${$('#version-dropdown').html()}`, + url: window.location.href, + }; +} + +function plusFix(n) { + n = parseFloat(n) + if (isNaN(n)) n = 0; + + if (n > 0) { + return "+" + n.toFixed(2); + } + + return n.toFixed(2); +} + +function getProblemNameWithId(problem_id) { + var problem_id = parseInt(problem_id, 10); + var problem = _.findWhere(problems, { "id": problem_id }); + if (problem == undefined) return "Deleted Problem(s)"; + return problem.name; +} + + +// create an HTML element real nice and easy like +function elt(t, a) { + var el = document.createElement(t); + if (a) { + for (var attr in a) + if (a.hasOwnProperty(attr)) + el.setAttribute(attr, a[attr]); + } + for (var i = 2; i < arguments.length; ++i) { + var arg = arguments[i]; + if (typeof arg === "string") + arg = document.createTextNode(arg); + el.appendChild(arg); + } + return el; +} + + +// this creates a JSON representation of what the actual Rails Annotation model looks like +function createAnnotation() { + var annObj = { + submitted_by: cudEmailStr, + }; + if (fileNameStr != null) { + annObj.filename = fileNameStr + } + + if (currentHeaderPos || currentHeaderPos === 0) { + annObj.position = currentHeaderPos + } + + return annObj; +} + +function getAnnotationObject(annotationId) { + for (var i = 0; i < annotations.length; i++) { + if (annotations[i].id == annotationId) { + return annotations[i]; + } + } +} + + +var updateAnnotationBox = function (annObj) { + + var problemStr = annObj.problem_id ? getProblemNameWithId(annObj.problem_id) : "General"; + var valueStr = annObj.value ? annObj.value.toString() : "None"; + var commentStr = annObj.comment; + + if (annotationMode === "PDF") { + $('#ann-box-' + annObj.id).find('.score-box').html("
Problem: " + problemStr + "
Score: " + valueStr + "
"); + $("#ann-box-" + annObj.id).find('.body').html(commentStr); + } + else { + $('#ann-box-' + annObj.id).find('.score-box').html("" + problemStr + "" + valueStr + ""); + } + $('#ann-box-' + annObj.id).find('.edit').show(); + $('#ann-box-' + annObj.id).find('.body').show(); + $('#ann-box-' + annObj.id).find('.score-box').show(); + $('#ann-box-' + annObj.id).find('.minimize').show(); + $('#ann-box-' + annObj.id).draggable('enable'); + $('#ann-box-' + annObj.id).resizable('enable'); +} diff --git a/app/assets/javascripts/annotations_popup.js b/app/assets/javascripts/annotations_popup.js new file mode 100644 index 000000000..a3723e41f --- /dev/null +++ b/app/assets/javascripts/annotations_popup.js @@ -0,0 +1,158 @@ +const updateEditTweakButtons = () => { + tweaks.forEach(({tweak, submission}) => { + get_tweak_total(submission.id).then(data => { + tweak?.setState({ amount: data }) + }) + }) +} +const get_tweak_total = (submission_id) => { + return new Promise((resolve, reject) => { + $.ajax({ + url: `submissions/${submission_id}/tweak_total`, + method: 'GET', + dataType: 'json', + success: (data) => { + resolve(data); + }, + error: (error) => { + console.error("There was an error fetching the scores:", error); + reject(error); + } + }); + }); +} +function newAnnotationFormCode() { + var box = $(".base-annotation-line").clone(); + box.removeClass("base-annotation-line"); + + box.addClass("new-annotation"); + + // Creates a dictionary of problem and grader_id + var problemGraderId = {}; + + _.each(scores, function (score) { + problemGraderId[score.problem_id] = score.grader_id; + }); + + _.each(problems, function (problem, i) { + if (problemGraderId[problem.id] !== 0) { // Because grader == 0 is autograder + box.find("select")?.append( + $("