From 5e23fbb61f9484b7155ea103fa6b95488b9b3456 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 26 Nov 2015 12:59:36 +0100 Subject: [PATCH 01/14] Add editor editor to code evolution page --- .../exercises/external_users/statistics.html.slim | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 489a7e21..aa49f96b 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -1 +1,11 @@ -h1 = "#{@exercise} for external user #{@external_user}" \ No newline at end of file +h1 = "#{@exercise} (external user #{@external_user})" + +#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id + div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(@exercise.files).to_js_tree + div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') + - @exercise.files.each do |file| + = render('editor_frame', exercise: @exercise, file: file) + +#slider + +#timeline From 21e28972dce62da3c0be00822590f8c233d4c0c8 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 26 Nov 2015 14:30:41 +0100 Subject: [PATCH 02/14] Add a slider based on submissions --- .../exercises/external_users/statistics.html.slim | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index aa49f96b..2399a195 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -1,11 +1,22 @@ h1 = "#{@exercise} (external user #{@external_user})" +- submissions = Submission.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id).to_a +- current_index = submissions.length - 1 +- current_submission = submissions[current_index] +- files = current_submission.files.to_a #editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id - div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(@exercise.files).to_js_tree + div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(files).to_js_tree div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - @exercise.files.each do |file| + - files.each do |file| = render('editor_frame', exercise: @exercise, file: file) #slider + input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=current_index + datalist#datapoints + - index=0 + - submissions.each do |submission| + option data-submission=submission + =index + - index += 1 #timeline From bd9118328ff9f8c44f397d33db70e9674e61a221 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 26 Nov 2015 15:28:02 +0100 Subject: [PATCH 03/14] Hide interface if no submissions are available and encode submissions for later use in javascript --- .../external_users/statistics.html.slim | 40 ++++++++++--------- config/locales/de.yml | 3 ++ config/locales/en.yml | 3 ++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 2399a195..d45f9334 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -1,22 +1,26 @@ h1 = "#{@exercise} (external user #{@external_user})" -- submissions = Submission.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id).to_a -- current_index = submissions.length - 1 -- current_submission = submissions[current_index] -- files = current_submission.files.to_a +- submissions = Submission.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id) +- current_submission = submissions.last +- if current_submission + - files = current_submission.files.to_a -#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id - div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(files).to_js_tree - div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - files.each do |file| - = render('editor_frame', exercise: @exercise, file: file) + .hidden data-submissions=ActiveSupport::JSON.encode(submissions) -#slider - input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=current_index - datalist#datapoints - - index=0 - - submissions.each do |submission| - option data-submission=submission - =index - - index += 1 + #editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id + div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(files).to_js_tree + div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') + - files.each do |file| + = render('editor_frame', exercise: @exercise, file: file) -#timeline + #slider + input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=0 + datalist#datapoints + - index=0 + - submissions.each do |submission| + option data-submission=submission + =index + - index += 1 + + #timeline +- else + p = t('.no_data_available') diff --git a/config/locales/de.yml b/config/locales/de.yml index bbd0e5de..56519a72 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -253,6 +253,9 @@ de: external_user: Externe Nutzer submit: failure: Beim Übermitteln Ihrer Punktzahl ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut. + external_users: + statistics: + no_data_available: Keine Daten verfügbar. files: roles: main_file: Hauptdatei diff --git a/config/locales/en.yml b/config/locales/en.yml index fc08792a..c7b0aa64 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -253,6 +253,9 @@ en: external_users: External Users submit: failure: An error occured while transmitting your score. Please try again later. + external_users: + statistics: + no_data_available: No data available. files: roles: main_file: Main File From baf33419cf3c6153979ec5cfe7c3670f3421fc3d Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 26 Nov 2015 16:25:59 +0100 Subject: [PATCH 04/14] Update editor content on submission selection --- .../javascripts/submission_statistics.js | 32 +++++++++++++++++++ .../external_users/statistics.html.slim | 6 +++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/submission_statistics.js diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js new file mode 100644 index 00000000..f8d37026 --- /dev/null +++ b/app/assets/javascripts/submission_statistics.js @@ -0,0 +1,32 @@ +$(function() { + + if ($.isController('exercises') && $('#timeline').isPresent()) { + + var editors = $('.editor'); + var slider = $('#slider>input'); + var submissions = $('#data').data('submissions'); + var files = $('#data').data('files'); + + editors.each(function(index, editor) { + currentEditor = ace.edit(editor); + currentEditor.$blockScrolling = Infinity; + currentEditor.setReadOnly(true); + }); + + slider.on('change', function(event) { + var currentSubmission = slider.val(); + var currentFiles = JSON.parse(files[currentSubmission]); + + editors.each(function(index, editor) { + currentEditor = ace.edit(editor); + fileContent = ""; + if (currentFiles[index]) { + fileContent = currentFiles[index].content + } + currentEditor.getSession().setValue(fileContent); + }); + }); + + } + +}); diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index d45f9334..a4117ae2 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -4,7 +4,11 @@ h1 = "#{@exercise} (external user #{@external_user})" - if current_submission - files = current_submission.files.to_a - .hidden data-submissions=ActiveSupport::JSON.encode(submissions) + - all_files = [] + - submissions.each do |submission| + - all_files.push(ActiveSupport::JSON.encode(submission.files)) + + .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=all_files #editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(files).to_js_tree From 72b5fa3b8c97e2ab7df4e779009da5632ad14a4f Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 26 Nov 2015 17:04:37 +0100 Subject: [PATCH 05/14] Cleanup code --- .../javascripts/submission_statistics.js | 2 +- .../external_users/statistics.html.slim | 40 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index f8d37026..843812fb 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -15,7 +15,7 @@ $(function() { slider.on('change', function(event) { var currentSubmission = slider.val(); - var currentFiles = JSON.parse(files[currentSubmission]); + var currentFiles = files[currentSubmission]; editors.each(function(index, editor) { currentEditor = ace.edit(editor); diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index a4117ae2..fc1966f7 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -2,29 +2,29 @@ h1 = "#{@exercise} (external user #{@external_user})" - submissions = Submission.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id) - current_submission = submissions.last - if current_submission - - files = current_submission.files.to_a + - initial_files = current_submission.files.to_a - - all_files = [] - - submissions.each do |submission| - - all_files.push(ActiveSupport::JSON.encode(submission.files)) + - all_files = [] + - submissions.each do |submission| + - all_files.push(submission.files) - .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=all_files + .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) - #editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id - div class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') id='files' data-entries=FileTree.new(files).to_js_tree - div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - files.each do |file| - = render('editor_frame', exercise: @exercise, file: file) + #editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id + #files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-entries=FileTree.new(initial_files).to_js_tree + div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') + - initial_files.each do |file| + = render('editor_frame', exercise: @exercise, file: file) - #slider - input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=0 - datalist#datapoints - - index=0 - - submissions.each do |submission| - option data-submission=submission - =index - - index += 1 + #slider + input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=0 + datalist#datapoints + - index=0 + - submissions.each do |submission| + option data-submission=submission + =index + - index += 1 - #timeline + #timeline - else - p = t('.no_data_available') + p = t('.no_data_available') From 6c13b8714f96d693c213651ec09ec7aa9d2ffbe8 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 2 Dec 2015 13:59:31 +0100 Subject: [PATCH 06/14] Remove unnecessary data attributes --- app/views/exercises/external_users/statistics.html.slim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index fc1966f7..b2e404fd 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -1,6 +1,6 @@ h1 = "#{@exercise} (external user #{@external_user})" - submissions = Submission.where("user_id = ? AND exercise_id = ?", @external_user.id, @exercise.id) -- current_submission = submissions.last +- current_submission = submissions.first - if current_submission - initial_files = current_submission.files.to_a @@ -10,7 +10,7 @@ h1 = "#{@exercise} (external user #{@external_user})" .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) - #editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-user-id=@external_user.id + #editor.row #files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-entries=FileTree.new(initial_files).to_js_tree div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - initial_files.each do |file| From c0b4c17de6d3baeb54381efc2deb50733245bc38 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 2 Dec 2015 15:39:13 +0100 Subject: [PATCH 07/14] Use custom lightweight editor and file-tree --- .../javascripts/submission_statistics.js | 52 ++++++++++++++++++- .../external_users/statistics.html.slim | 2 +- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index 843812fb..4ca7d634 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -1,16 +1,62 @@ $(function() { + var ACE_FILES_PATH = '/assets/ace/'; + var THEME = 'ace/theme/textmate'; + + var active_file = undefined; + + var showFirstFile = function() { + var frame = $('.frame[data-role="main_file"]').isPresent() ? $('.frame[data-role="main_file"]') : $('.frame').first(); + var file_id = frame.find('.editor').data('file-id'); + $('#files').jstree().select_node(file_id); + showFrame(frame); + }; + + var showFrame = function(frame) { + $('.frame').hide(); + frame.show(); + }; + + var initializeFileTree = function() { + $('#files').jstree($('#files').data('entries')); + $('#files').on('click', 'li.jstree-leaf', function() { + active_file = { + filename: $(this).text(), + id: parseInt($(this).attr('id')) + }; + var frame = $('[data-file-id="' + active_file.id + '"]').parent(); + showFrame(frame); + }); + }; + if ($.isController('exercises') && $('#timeline').isPresent()) { + _.each(['modePath', 'themePath', 'workerPath'], function(attribute) { + ace.config.set(attribute, ACE_FILES_PATH); + }); + var editors = $('.editor'); var slider = $('#slider>input'); var submissions = $('#data').data('submissions'); var files = $('#data').data('files'); - editors.each(function(index, editor) { - currentEditor = ace.edit(editor); + editors.each(function(index, element) { + currentEditor = ace.edit(element); + + var file_id = $(element).data('file-id'); + var content = $('.editor-content[data-file-id=' + file_id + ']'); + + currentEditor.setShowPrintMargin(false); + currentEditor.setTheme(THEME); currentEditor.$blockScrolling = Infinity; currentEditor.setReadOnly(true); + + var session = currentEditor.getSession(); + session.setMode($(element).data('mode')); + session.setTabSize($(element).data('indent-size')); + session.setUseSoftTabs(true); + session.setUseWrapMode(true); + session.setValue(content.text()); }); slider.on('change', function(event) { @@ -27,6 +73,8 @@ $(function() { }); }); + initializeFileTree(); + showFirstFile(); } }); diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index b2e404fd..0aa19140 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -10,7 +10,7 @@ h1 = "#{@exercise} (external user #{@external_user})" .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) - #editor.row + #stats-editor.row #files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-entries=FileTree.new(initial_files).to_js_tree div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - initial_files.each do |file| From 5c5769bab227dd8f1cc8f1dd58471263038ee735 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Wed, 2 Dec 2015 17:01:31 +0100 Subject: [PATCH 08/14] Change file tree when changing submission --- .../javascripts/submission_statistics.js | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index 4ca7d634..4c03a8d2 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -3,13 +3,16 @@ $(function() { var ACE_FILES_PATH = '/assets/ace/'; var THEME = 'ace/theme/textmate'; + var currentSubmission = 0; var active_file = undefined; + var fileTrees = [] var showFirstFile = function() { var frame = $('.frame[data-role="main_file"]').isPresent() ? $('.frame[data-role="main_file"]') : $('.frame').first(); var file_id = frame.find('.editor').data('file-id'); - $('#files').jstree().select_node(file_id); + $(fileTrees[currentSubmission]).jstree().select_node(file_id); showFrame(frame); + showFileTree(currentSubmission); }; var showFrame = function(frame) { @@ -18,17 +21,25 @@ $(function() { }; var initializeFileTree = function() { - $('#files').jstree($('#files').data('entries')); - $('#files').on('click', 'li.jstree-leaf', function() { - active_file = { - filename: $(this).text(), - id: parseInt($(this).attr('id')) - }; - var frame = $('[data-file-id="' + active_file.id + '"]').parent(); - showFrame(frame); + $('.files').each(function(index, element) { + fileTree = $(element).jstree($(element).data('entries')); + fileTree.on('click', 'li.jstree-leaf', function() { + active_file = { + filename: $(this).text(), + id: parseInt($(this).attr('id')) + }; + var frame = $('[data-file-id="' + active_file.id + '"]').parent(); + showFrame(frame); + }); + fileTrees.push(fileTree); }); }; + var showFileTree = function(index) { + $('.files').hide(); + $(fileTrees[index].context).show(); + } + if ($.isController('exercises') && $('#timeline').isPresent()) { _.each(['modePath', 'themePath', 'workerPath'], function(attribute) { @@ -60,7 +71,8 @@ $(function() { }); slider.on('change', function(event) { - var currentSubmission = slider.val(); + currentSubmission = slider.val(); + showFileTree(currentSubmission); var currentFiles = files[currentSubmission]; editors.each(function(index, editor) { From efe3895894516afedf3849f6f0570ee9b75282cd Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 3 Dec 2015 13:52:18 +0100 Subject: [PATCH 09/14] Enable switching between files of a submission --- .../javascripts/submission_statistics.js | 25 +++++++------------ .../external_users/statistics.html.slim | 15 +++++++---- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index 4c03a8d2..8618a516 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -8,14 +8,13 @@ $(function() { var fileTrees = [] var showFirstFile = function() { - var frame = $('.frame[data-role="main_file"]').isPresent() ? $('.frame[data-role="main_file"]') : $('.frame').first(); - var file_id = frame.find('.editor').data('file-id'); - $(fileTrees[currentSubmission]).jstree().select_node(file_id); - showFrame(frame); + $(fileTrees[currentSubmission]).jstree().select_node(active_file.file_id); + showActiveFrame(); showFileTree(currentSubmission); }; - var showFrame = function(frame) { + var showActiveFrame = function() { + var frame = $('.data[data-file-id="' + active_file.id + '"]').parent().find('.frame'); $('.frame').hide(); frame.show(); }; @@ -28,8 +27,7 @@ $(function() { filename: $(this).text(), id: parseInt($(this).attr('id')) }; - var frame = $('[data-file-id="' + active_file.id + '"]').parent(); - showFrame(frame); + showActiveFrame() }); fileTrees.push(fileTree); }); @@ -74,17 +72,12 @@ $(function() { currentSubmission = slider.val(); showFileTree(currentSubmission); var currentFiles = files[currentSubmission]; - - editors.each(function(index, editor) { - currentEditor = ace.edit(editor); - fileContent = ""; - if (currentFiles[index]) { - fileContent = currentFiles[index].content - } - currentEditor.getSession().setValue(fileContent); - }); + console.log(currentFiles); + active_file = currentFiles[0]; + showFirstFile(); }); + active_file = files[0][0] initializeFileTree(); showFirstFile(); } diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 0aa19140..583adc83 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -10,11 +10,16 @@ h1 = "#{@exercise} (external user #{@external_user})" .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) - #stats-editor.row - #files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-entries=FileTree.new(initial_files).to_js_tree - div id='frames' class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - initial_files.each do |file| - = render('editor_frame', exercise: @exercise, file: file) + - index = 0 + - all_files.each do |files| + #stats-editor.row + .files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-index=index data-entries=FileTree.new(files).to_js_tree + .frames class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') + - files.each do |file| + .frame-container + = render('editor_frame', exercise: @exercise, file: file) + .hidden.data data-file-id=file.id + - index += 1 #slider input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=0 From b7b0bf826ef08f4e5df07b5b150b17eaf1019164 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 3 Dec 2015 14:52:33 +0100 Subject: [PATCH 10/14] Use only one editor to reduce complexity --- .../javascripts/submission_statistics.js | 61 ++++++++----------- .../external_users/statistics.html.slim | 15 ++--- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index 8618a516..5428061d 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -6,28 +6,31 @@ $(function() { var currentSubmission = 0; var active_file = undefined; var fileTrees = [] + var editor = undefined; + + var showActiveFile = function() { + var session = editor.getSession(); + //session.setMode(active_file.file_type.editor_mode); + //session.setTabSize(active_file.file_type.indent_size); + session.setValue(active_file.content); + session.setUseSoftTabs(true); + session.setUseWrapMode(true); - var showFirstFile = function() { - $(fileTrees[currentSubmission]).jstree().select_node(active_file.file_id); - showActiveFrame(); showFileTree(currentSubmission); - }; - - var showActiveFrame = function() { - var frame = $('.data[data-file-id="' + active_file.id + '"]').parent().find('.frame'); - $('.frame').hide(); - frame.show(); + $(fileTrees[currentSubmission]).jstree().select_node(active_file.file_id); }; var initializeFileTree = function() { $('.files').each(function(index, element) { fileTree = $(element).jstree($(element).data('entries')); fileTree.on('click', 'li.jstree-leaf', function() { - active_file = { - filename: $(this).text(), - id: parseInt($(this).attr('id')) - }; - showActiveFrame() + var id = parseInt($(this).attr('id')) + _.each(files[currentSubmission], function(file) { + if (file.file_id === id) { + active_file = file; + } + }); + showActiveFile(); }); fileTrees.push(fileTree); }); @@ -44,42 +47,26 @@ $(function() { ace.config.set(attribute, ACE_FILES_PATH); }); - var editors = $('.editor'); var slider = $('#slider>input'); var submissions = $('#data').data('submissions'); var files = $('#data').data('files'); - editors.each(function(index, element) { - currentEditor = ace.edit(element); - - var file_id = $(element).data('file-id'); - var content = $('.editor-content[data-file-id=' + file_id + ']'); - - currentEditor.setShowPrintMargin(false); - currentEditor.setTheme(THEME); - currentEditor.$blockScrolling = Infinity; - currentEditor.setReadOnly(true); - - var session = currentEditor.getSession(); - session.setMode($(element).data('mode')); - session.setTabSize($(element).data('indent-size')); - session.setUseSoftTabs(true); - session.setUseWrapMode(true); - session.setValue(content.text()); - }); + editor = ace.edit('current-file'); + editor.setShowPrintMargin(false); + editor.setTheme(THEME); + editor.$blockScrolling = Infinity; + editor.setReadOnly(true); slider.on('change', function(event) { currentSubmission = slider.val(); - showFileTree(currentSubmission); var currentFiles = files[currentSubmission]; - console.log(currentFiles); active_file = currentFiles[0]; - showFirstFile(); + showActiveFile(); }); active_file = files[0][0] initializeFileTree(); - showFirstFile(); + showActiveFile(); } }); diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 583adc83..58a50c43 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -10,16 +10,13 @@ h1 = "#{@exercise} (external user #{@external_user})" .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) - - index = 0 - - all_files.each do |files| - #stats-editor.row + #stats-editor.row + - index = 0 + - all_files.each do |files| .files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-index=index data-entries=FileTree.new(files).to_js_tree - .frames class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - - files.each do |file| - .frame-container - = render('editor_frame', exercise: @exercise, file: file) - .hidden.data data-file-id=file.id - - index += 1 + - index += 1 + div class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') + #current-file.editor style="height: 400px" #slider input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=0 From 79e7f7b7e870bf7104f76a0e72a0a455ebd1ef9e Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 10 Dec 2015 12:49:36 +0100 Subject: [PATCH 11/14] Apply some styling and add timeline --- app/assets/javascripts/submission_statistics.js | 2 +- app/assets/stylesheets/statistics.css.scss | 9 +++++++++ .../external_users/statistics.html.slim | 17 +++++++++++++++-- config/locales/de.yml | 3 +++ config/locales/en.yml | 3 +++ 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 app/assets/stylesheets/statistics.css.scss diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index 5428061d..ec0d827a 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -47,7 +47,7 @@ $(function() { ace.config.set(attribute, ACE_FILES_PATH); }); - var slider = $('#slider>input'); + var slider = $('#submissions-slider>input'); var submissions = $('#data').data('submissions'); var files = $('#data').data('files'); diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss new file mode 100644 index 00000000..a8d1d81d --- /dev/null +++ b/app/assets/stylesheets/statistics.css.scss @@ -0,0 +1,9 @@ +#submissions-slider { + margin-top: 25px; + margin-bottom: 25px; +} + +#current-file.editor { + height: 400px; +} + diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 58a50c43..97c069d4 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -16,9 +16,9 @@ h1 = "#{@exercise} (external user #{@external_user})" .files class=(@exercise.hide_file_tree ? 'hidden col-sm-3' : 'col-sm-3') data-index=index data-entries=FileTree.new(files).to_js_tree - index += 1 div class=(@exercise.hide_file_tree ? 'col-sm-12' : 'col-sm-9') - #current-file.editor style="height: 400px" + #current-file.editor - #slider + #submissions-slider input type='range' orient='horizontal' list='datapoints' min=0 max=submissions.length-1 value=0 datalist#datapoints - index=0 @@ -28,5 +28,18 @@ h1 = "#{@exercise} (external user #{@external_user})" - index += 1 #timeline + .table-responsive + table.table + thead + tr + - ['.time', '.cause', '.score'].each do |title| + th.header = t(title) + tbody + - submissions.each do |submission| + tr data-id=submission.id + td = submission.created_at.strftime("%F %T") + td = submission.cause + td = submission.score + - else p = t('.no_data_available') diff --git a/config/locales/de.yml b/config/locales/de.yml index 56519a72..525b65ae 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -256,6 +256,9 @@ de: external_users: statistics: no_data_available: Keine Daten verfügbar. + time: Zeit + cause: Grund + score: Punktzahl files: roles: main_file: Hauptdatei diff --git a/config/locales/en.yml b/config/locales/en.yml index c7b0aa64..47539bf1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -256,6 +256,9 @@ en: external_users: statistics: no_data_available: No data available. + time: Time + cause: Cause + score: Score files: roles: main_file: Main File From 842907f1fa1f7f2b36c862fd09f0f6f7ab257b1e Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 10 Dec 2015 13:48:31 +0100 Subject: [PATCH 12/14] Make use of file types for highlighting and tabs --- app/assets/javascripts/submission_statistics.js | 12 ++++++++++-- .../exercises/external_users/statistics.html.slim | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index ec0d827a..c5cfaab8 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -7,11 +7,13 @@ $(function() { var active_file = undefined; var fileTrees = [] var editor = undefined; + var fileTypeById = {} var showActiveFile = function() { var session = editor.getSession(); - //session.setMode(active_file.file_type.editor_mode); - //session.setTabSize(active_file.file_type.indent_size); + var fileType = fileTypeById[active_file.file_type_id] + session.setMode(fileType.editor_mode); + session.setTabSize(fileType.indent_size); session.setValue(active_file.content); session.setUseSoftTabs(true); session.setUseWrapMode(true); @@ -50,6 +52,7 @@ $(function() { var slider = $('#submissions-slider>input'); var submissions = $('#data').data('submissions'); var files = $('#data').data('files'); + var filetypes = $('#data').data('file-types'); editor = ace.edit('current-file'); editor.setShowPrintMargin(false); @@ -57,6 +60,11 @@ $(function() { editor.$blockScrolling = Infinity; editor.setReadOnly(true); + _.each(filetypes, function (filetype) { + filetype = JSON.parse(filetype); + fileTypeById[filetype.id] = filetype; + }); + slider.on('change', function(event) { currentSubmission = slider.val(); var currentFiles = files[currentSubmission]; diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 97c069d4..3141572a 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -5,10 +5,13 @@ h1 = "#{@exercise} (external user #{@external_user})" - initial_files = current_submission.files.to_a - all_files = [] + - file_types = Set.new() - submissions.each do |submission| + - submission.files.each do |file| + - file_types.add(ActiveSupport::JSON.encode(file.file_type)) - all_files.push(submission.files) - .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) + .hidden#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) data-file-types=ActiveSupport::JSON.encode(file_types) #stats-editor.row - index = 0 From 53330fbdc5e6c8956bce71b0146dba6bddd77e07 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 10 Dec 2015 14:03:23 +0100 Subject: [PATCH 13/14] Make timeline entries clickable --- app/assets/javascripts/submission_statistics.js | 8 ++++++++ app/assets/stylesheets/statistics.css.scss | 3 +++ app/views/exercises/external_users/statistics.html.slim | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index c5cfaab8..9f74ed7a 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -65,6 +65,14 @@ $(function() { fileTypeById[filetype.id] = filetype; }); + $('tr[data-id]>.clickable').each(function(index, element) { + element = $(element); + element.click(function() { + slider.val(index); + slider.change() + }); + }); + slider.on('change', function(event) { currentSubmission = slider.val(); var currentFiles = files[currentSubmission]; diff --git a/app/assets/stylesheets/statistics.css.scss b/app/assets/stylesheets/statistics.css.scss index a8d1d81d..d148f782 100644 --- a/app/assets/stylesheets/statistics.css.scss +++ b/app/assets/stylesheets/statistics.css.scss @@ -7,3 +7,6 @@ height: 400px; } +.clickable { + cursor: pointer; +} diff --git a/app/views/exercises/external_users/statistics.html.slim b/app/views/exercises/external_users/statistics.html.slim index 3141572a..ca5142cc 100644 --- a/app/views/exercises/external_users/statistics.html.slim +++ b/app/views/exercises/external_users/statistics.html.slim @@ -40,7 +40,7 @@ h1 = "#{@exercise} (external user #{@external_user})" tbody - submissions.each do |submission| tr data-id=submission.id - td = submission.created_at.strftime("%F %T") + td.clickable = submission.created_at.strftime("%F %T") td = submission.cause td = submission.score From 0f61a46764f11ebad60a4239a2746b2c18635137 Mon Sep 17 00:00:00 2001 From: Maximilian Grundke Date: Thu, 10 Dec 2015 15:54:51 +0100 Subject: [PATCH 14/14] Select the same file if possible --- app/assets/javascripts/submission_statistics.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/submission_statistics.js b/app/assets/javascripts/submission_statistics.js index 9f74ed7a..75fe42cd 100644 --- a/app/assets/javascripts/submission_statistics.js +++ b/app/assets/javascripts/submission_statistics.js @@ -19,7 +19,9 @@ $(function() { session.setUseWrapMode(true); showFileTree(currentSubmission); - $(fileTrees[currentSubmission]).jstree().select_node(active_file.file_id); + filetree = $(fileTrees[currentSubmission]) + filetree.jstree("deselect_all"); + filetree.jstree().select_node(active_file.file_id); }; var initializeFileTree = function() { @@ -76,7 +78,13 @@ $(function() { slider.on('change', function(event) { currentSubmission = slider.val(); var currentFiles = files[currentSubmission]; - active_file = currentFiles[0]; + var fileIndex = 0; + _.each(currentFiles, function(file, index) { + if (file.name === active_file.name) { + fileIndex = index; + } + }) + active_file = currentFiles[fileIndex]; showActiveFile(); });