Update Bootstrap to v4.1, fix chosen.js and pagedown on multiple sites
This commit is contained in:
@ -8,7 +8,6 @@ window.CodeOcean = {
|
||||
}
|
||||
};
|
||||
|
||||
$(function() {
|
||||
var ANIMATION_DURATION = 500;
|
||||
|
||||
$.isController = function(name) {
|
||||
@ -24,4 +23,3 @@ $(function() {
|
||||
scrollTop: $(selector).offset().top - $(this).offset().top + $(this).scrollTop()
|
||||
}, ANIMATION_DURATION);
|
||||
};
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ $(document).on('turbolinks:load', function() {
|
||||
var menu = $(this).parent().find("ul");
|
||||
var menupos = menu.offset();
|
||||
|
||||
var newPos;
|
||||
var newPos = 0.0;
|
||||
if ((menupos.left + menu.width()) + 30 > $(window).width()) {
|
||||
newPos = -menu.width();
|
||||
} else {
|
||||
|
@ -33,6 +33,7 @@ var CodeOceanEditor = {
|
||||
<% @config ||= CodeOcean::Config.new(:code_ocean).read(erb: false) %>
|
||||
sendEvents: <%= @config['codeocean_events'] ? @config['codeocean_events']['enabled'] : false %>,
|
||||
eventURL: "<%= @config['codeocean_events'] ? events_path : '' %>",
|
||||
fileTypeURL: "<%= file_types_path %>",
|
||||
|
||||
|
||||
configureEditors: function () {
|
||||
@ -43,7 +44,7 @@ configureEditors: function () {
|
||||
|
||||
confirmDestroy: function (event) {
|
||||
event.preventDefault();
|
||||
if (confirm($(this).data('message-confirm'))) {
|
||||
if (confirm($(event.target).data('message-confirm'))) {
|
||||
this.destroyFile();
|
||||
}
|
||||
},
|
||||
@ -63,7 +64,7 @@ configureEditors: function () {
|
||||
if ($('#output-' + index).isPresent()) {
|
||||
return $('#output-' + index);
|
||||
} else {
|
||||
var element = $('<pre>').attr('id', 'output-' + index);
|
||||
var element = $('<pre class="mt-2">').attr('id', 'output-' + index);
|
||||
$('#output').append(element);
|
||||
return element;
|
||||
}
|
||||
@ -79,13 +80,13 @@ configureEditors: function () {
|
||||
}
|
||||
},
|
||||
|
||||
getPanelClass: function (result) {
|
||||
getCardClass: function (result) {
|
||||
if (result.stderr && !result.score) {
|
||||
return 'panel-danger';
|
||||
return 'card bg-danger text-white';
|
||||
} else if (result.score < 1) {
|
||||
return 'panel-warning';
|
||||
return 'card bg-warning';
|
||||
} else {
|
||||
return 'panel-success';
|
||||
return 'card bg-success text-white';
|
||||
}
|
||||
},
|
||||
|
||||
@ -107,11 +108,22 @@ configureEditors: function () {
|
||||
progress_bar.css('width', percentage + '%');
|
||||
},
|
||||
|
||||
// The event ready.jstree is fired too early and thus doesn't work.
|
||||
selectFileInJsTree: function(filetree, file_id) {
|
||||
if (!filetree.hasClass('jstree-loading')) {
|
||||
filetree.jstree("deselect_all");
|
||||
filetree.jstree().select_node(file_id);
|
||||
} else {
|
||||
setTimeout(this.selectFileInJsTree.bind(null, filetree, file_id), 250);
|
||||
}
|
||||
},
|
||||
|
||||
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');
|
||||
this.setActiveFile(frame.data('filename'), file_id);
|
||||
$('#files').jstree().select_node(file_id);
|
||||
var filetree = $('#files');
|
||||
this.selectFileInJsTree(filetree, file_id);
|
||||
this.showFrame(frame);
|
||||
this.toggleButtonStates();
|
||||
},
|
||||
@ -124,11 +136,11 @@ configureEditors: function () {
|
||||
|
||||
getProgressBarClass: function (percentage) {
|
||||
if (percentage < this.ADEQUATE_PERCENTAGE) {
|
||||
return 'progress-bar progress-bar-striped progress-bar-danger';
|
||||
return 'progress-bar progress-bar-striped bg-danger';
|
||||
} else if (percentage < this.SUCCESSFULL_PERCENTAGE) {
|
||||
return 'progress-bar progress-bar-striped progress-bar-warning';
|
||||
return 'progress-bar progress-bar-striped bg-warning';
|
||||
} else {
|
||||
return 'progress-bar progress-bar-striped progress-bar-success';
|
||||
return 'progress-bar progress-bar-striped bg-success';
|
||||
}
|
||||
},
|
||||
|
||||
@ -158,7 +170,7 @@ configureEditors: function () {
|
||||
category: 'editor_paste',
|
||||
data: pasteObject.text,
|
||||
exercise_id: $('#editor').data('exercise-id'),
|
||||
file_id: $(this).data('file-id')
|
||||
file_id: $(event.target).data('file-id')
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -266,6 +278,21 @@ configureEditors: function () {
|
||||
this.initializeRequestForComments()
|
||||
},
|
||||
|
||||
updateEditorModeToFileTypeID: function (editor, fileTypeID) {
|
||||
var newMode = 'ace/mode/text'
|
||||
|
||||
$.ajax(this.fileTypeURL + '/' + fileTypeID, {
|
||||
dataType: 'json'
|
||||
}).done(function (data) {
|
||||
if (data['editor_mode'] !== null) {
|
||||
newMode = data['editor_mode'];
|
||||
}
|
||||
}).fail(_.noop)
|
||||
.always(function () {
|
||||
ace.edit(editor).session.setMode(newMode);
|
||||
});
|
||||
},
|
||||
|
||||
initializeFileTree: function () {
|
||||
$('#files').jstree($('#files').data('entries'));
|
||||
$('#files').on('click', 'li.jstree-leaf', function (event) {
|
||||
@ -296,8 +323,8 @@ configureEditors: function () {
|
||||
|
||||
handleSideBarToggle: function() {
|
||||
$('#sidebar').toggleClass('sidebar-col').toggleClass('sidebar-col-collapsed');
|
||||
$('#sidebar-collapsed').toggleClass('hidden');
|
||||
$('#sidebar-uncollapsed').toggleClass('hidden');
|
||||
$('#sidebar-collapsed').toggleClass('d-none');
|
||||
$('#sidebar-uncollapsed').toggleClass('d-none');
|
||||
},
|
||||
|
||||
initializeRegexes: function () {
|
||||
@ -369,17 +396,17 @@ configureEditors: function () {
|
||||
return Modernizr.websockets;
|
||||
},
|
||||
|
||||
populatePanel: function (panel, result, index) {
|
||||
panel.removeClass('panel-default').addClass(this.getPanelClass(result));
|
||||
panel.find('.panel-title .filename').text(result.filename);
|
||||
panel.find('.panel-title .number').text(index + 1);
|
||||
panel.find('.row .col-sm-9').eq(0).find('.number').eq(0).text(result.passed);
|
||||
panel.find('.row .col-sm-9').eq(0).find('.number').eq(1).text(result.count);
|
||||
panel.find('.row .col-sm-9').eq(1).find('.number').eq(0).text(parseFloat((result.score * result.weight).toFixed(2)));
|
||||
panel.find('.row .col-sm-9').eq(1).find('.number').eq(1).text(result.weight);
|
||||
panel.find('.row .col-sm-9').eq(2).html(result.message);
|
||||
if (result.error_messages) panel.find('.row .col-sm-9').eq(3).text(result.error_messages.join(' '));
|
||||
//panel.find('.row .col-sm-9').eq(4).find('a').attr('href', '#output-' + index);
|
||||
populateCard: function (card, result, index) {
|
||||
card.addClass(this.getCardClass(result));
|
||||
card.find('.card-title .filename').text(result.filename);
|
||||
card.find('.card-title .number').text(index + 1);
|
||||
card.find('.row .col-sm-9').eq(0).find('.number').eq(0).text(result.passed);
|
||||
card.find('.row .col-sm-9').eq(0).find('.number').eq(1).text(result.count);
|
||||
card.find('.row .col-sm-9').eq(1).find('.number').eq(0).text(parseFloat((result.score * result.weight).toFixed(2)));
|
||||
card.find('.row .col-sm-9').eq(1).find('.number').eq(1).text(result.weight);
|
||||
card.find('.row .col-sm-9').eq(2).html(result.message);
|
||||
if (result.error_messages) card.find('.row .col-sm-9').eq(3).text(result.error_messages.join(' '));
|
||||
//card.find('.row .col-sm-9').eq(4).find('a').attr('href', '#output-' + index);
|
||||
},
|
||||
|
||||
publishCodeOceanEvent: function (payload) {
|
||||
@ -556,14 +583,14 @@ configureEditors: function () {
|
||||
},
|
||||
|
||||
showOutputBar: function() {
|
||||
$('#output_sidebar_collapsed').addClass('hidden');
|
||||
$('#output_sidebar_uncollapsed').removeClass('hidden');
|
||||
$('#output_sidebar_collapsed').addClass('d-none');
|
||||
$('#output_sidebar_uncollapsed').removeClass('d-none');
|
||||
$('#output_sidebar').removeClass('output-col-collapsed').addClass('output-col');
|
||||
},
|
||||
|
||||
hideOutputBar: function() {
|
||||
$('#output_sidebar_collapsed').removeClass('hidden');
|
||||
$('#output_sidebar_uncollapsed').addClass('hidden');
|
||||
$('#output_sidebar_collapsed').removeClass('d-none');
|
||||
$('#output_sidebar_uncollapsed').addClass('d-none');
|
||||
$('#output_sidebar').removeClass('output-col').addClass('output-col-collapsed');
|
||||
},
|
||||
|
||||
@ -572,12 +599,12 @@ configureEditors: function () {
|
||||
},
|
||||
|
||||
initializeDescriptionToggle: function() {
|
||||
$('#exercise-headline').on('click', this.toggleDescriptionPanel.bind(this));
|
||||
$('a#toggle').on('click', this.toggleDescriptionPanel.bind(this));
|
||||
$('#exercise-headline').on('click', this.toggleDescriptionCard.bind(this));
|
||||
$('a#toggle').on('click', this.toggleDescriptionCard.bind(this));
|
||||
},
|
||||
|
||||
toggleDescriptionPanel: function() {
|
||||
$('#description-panel').toggleClass('description-panel-collapsed').toggleClass('description-panel');
|
||||
toggleDescriptionCard: function() {
|
||||
$('#description-card').toggleClass('description-card-collapsed').toggleClass('description-card');
|
||||
$('#description-symbol').toggleClass('fa-chevron-down').toggleClass('fa-chevron-right');
|
||||
var toggle = $('a#toggle');
|
||||
toggle.text(toggle.text() == toggle.data('hide') ? toggle.data('show') : toggle.data('hide'));
|
||||
|
@ -9,7 +9,7 @@ CodeOceanEditorEvaluation = {
|
||||
this.clearScoringOutput();
|
||||
this.createSubmission('#assess', null, function (response) {
|
||||
this.showSpinner($('#assess'));
|
||||
$('#score_div').removeClass('hidden');
|
||||
$('#score_div').removeClass('d-none');
|
||||
var url = response.score_url;
|
||||
this.initializeSocketForScoring(url);
|
||||
}.bind(this));
|
||||
@ -26,9 +26,9 @@ CodeOceanEditorEvaluation = {
|
||||
|
||||
printScoringResult: function (result, index) {
|
||||
$('#results').show();
|
||||
var panel = $('#dummies').children().first().clone();
|
||||
this.populatePanel(panel, result, index);
|
||||
$('#results ul').first().append(panel);
|
||||
var card = $('#dummies').children().first().clone();
|
||||
this.populateCard(card, result, index);
|
||||
$('#results ul').first().append(card);
|
||||
},
|
||||
|
||||
printScoringResults: function (response) {
|
||||
@ -60,7 +60,7 @@ CodeOceanEditorEvaluation = {
|
||||
renderHint: function (object) {
|
||||
var hint = object.data || object.hint;
|
||||
if (hint) {
|
||||
$('#hint .panel-body').text(hint);
|
||||
$('#hint .card-body').text(hint);
|
||||
$('#hint').fadeIn();
|
||||
}
|
||||
},
|
||||
|
@ -1,12 +1,12 @@
|
||||
CodeOceanEditorFlowr = {
|
||||
isFlowrEnabled: true,
|
||||
flowrResultHtml: '<div class="panel panel-default"><div id="{{headingId}}" role="tab" class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#flowrHint" href="#{{collapseId}}" aria-expanded="true" aria-controls="{{collapseId}}"></a></h4></div><div id="{{collapseId}}" role="tabpanel" aria-labelledby="{{headingId}}" class="panel-collapse collapse"><div class="panel-body"></div></div></div>',
|
||||
flowrResultHtml: '<div class="panel panel-default"><div id="{{headingId}}" role="tab" class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#flowrHint" href="#{{collapseId}}" aria-expanded="true" aria-controls="{{collapseId}}"></a></h4></div><div id="{{collapseId}}" role="tabpanel" aria-labelledby="{{headingId}}" class="panel-collapse collapse"><div class="card-body"></div></div></div>',
|
||||
|
||||
handleStderrOutputForFlowr: function () {
|
||||
if (!this.isFlowrEnabled) return;
|
||||
|
||||
var flowrUrl = $('#flowrHint').data('url');
|
||||
var flowrHintBody = $('#flowrHint .panel-body');
|
||||
var flowrHintBody = $('#flowrHint .card-body');
|
||||
var queryParameters = {
|
||||
query: this.flowrOutputBuffer
|
||||
};
|
||||
@ -19,8 +19,8 @@ CodeOceanEditorFlowr = {
|
||||
var resultTile = $(collapsibleTileHtml);
|
||||
|
||||
resultTile.find('h4 > a').text(question.title + ' | Found via ' + question.source);
|
||||
resultTile.find('.panel-body').html(question.body);
|
||||
resultTile.find('.panel-body').append('<a href="' + question.url + '" class="btn btn-primary btn-block">Open this question</a>');
|
||||
resultTile.find('.card-body').html(question.body);
|
||||
resultTile.find('.card-body').append('<a href="' + question.url + '" class="btn btn-primary btn-block">Open this question</a>');
|
||||
|
||||
flowrHintBody.append(resultTile);
|
||||
});
|
||||
|
@ -2,19 +2,19 @@ CodeOceanEditorPrompt = {
|
||||
prompt: '#prompt',
|
||||
|
||||
showPrompt: function(msg) {
|
||||
var label = $('#prompt .input-group-addon');
|
||||
var label = $('#prompt .input-group-text');
|
||||
var prompt = $(this.prompt);
|
||||
label.text(msg.data || label.data('prompt'));
|
||||
if (prompt.isPresent() && prompt.hasClass('hidden')) {
|
||||
prompt.removeClass('hidden');
|
||||
if (prompt.isPresent() && prompt.hasClass('d-none')) {
|
||||
prompt.removeClass('d-none');
|
||||
}
|
||||
$('#prompt input').focus();
|
||||
},
|
||||
|
||||
hidePrompt: function() {
|
||||
var prompt = $(this.prompt);
|
||||
if (prompt.isPresent() && !prompt.hasClass('hidden')) {
|
||||
prompt.addClass('hidden');
|
||||
if (prompt.isPresent() && !prompt.hasClass('d-none')) {
|
||||
prompt.addClass('d-none');
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -155,7 +155,7 @@ CodeOceanEditorSubmissions = {
|
||||
$('#stop').data('url', submission.stop_url);
|
||||
this.running = true;
|
||||
this.showSpinner($('#run'));
|
||||
$('#score_div').addClass('hidden');
|
||||
$('#score_div').addClass('d-none');
|
||||
this.toggleButtonStates();
|
||||
var url = submission.run_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
|
||||
this.initializeSocketForRunning(url);
|
||||
@ -175,7 +175,7 @@ CodeOceanEditorSubmissions = {
|
||||
if ($('#test').is(':visible')) {
|
||||
this.createSubmission('#test', null, function(response) {
|
||||
this.showSpinner($('#test'));
|
||||
$('#score_div').addClass('hidden');
|
||||
$('#score_div').addClass('d-none');
|
||||
var url = response.test_url.replace(this.FILENAME_URL_PLACEHOLDER, this.active_file.filename.replace(/#$/,'')); // remove # if it is the last character, this is not part of the filename and just an anchor
|
||||
this.initializeSocketForTesting(url);
|
||||
}.bind(this));
|
||||
|
@ -38,10 +38,10 @@ CodeOceanEditorTurtle = {
|
||||
|
||||
showCanvas: function () {
|
||||
if ($('#turtlediv').isPresent()
|
||||
&& this.turtlecanvas.hasClass('hidden')) {
|
||||
&& this.turtlecanvas.hasClass('d-none')) {
|
||||
// initialize two-column layout
|
||||
$('#output-col1').addClass('col-lg-7 col-md-7 two-column');
|
||||
this.turtlecanvas.removeClass('hidden');
|
||||
this.turtlecanvas.removeClass('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,9 @@ $(document).on('turbolinks:load', function() {
|
||||
$('#files').append(html);
|
||||
$('#files li:last select[name*="file_type_id"]').val(getSelectedExecutionEnvironment().file_type_id);
|
||||
$('#files li:last select').chosen(window.CodeOcean.CHOSEN_OPTIONS);
|
||||
$('#files li:last select').remove();
|
||||
$('#files li:last>div:last').removeClass('in').addClass('show')
|
||||
$('body, html').scrollTo('#add-file');
|
||||
// if we collapse the file forms by default, we need to click on the new element in order to open it.
|
||||
// however, this crashes for more files (if we add several ones by clicking the add button more often), since the elements are probably not correctly added to the files list.
|
||||
//$('#files li:last>div:first>a>div').click();
|
||||
|
||||
// initialize the ace editor for the new textarea.
|
||||
// pass the correct index and the last ace editor under the node files. this is the last one, since we just added it.
|
||||
@ -93,7 +92,7 @@ $(document).on('turbolinks:load', function() {
|
||||
|
||||
var deleteFile = function(event) {
|
||||
event.preventDefault();
|
||||
var fileUrl = $(this).data('file-url');
|
||||
var fileUrl = $(event.target).data('file-url');
|
||||
|
||||
if (confirm('<%= I18n.t('shared.confirm_destroy') %>')) {
|
||||
var jqxhr = $.ajax({
|
||||
@ -139,9 +138,9 @@ $(document).on('turbolinks:load', function() {
|
||||
var enableBatchUpdate = function() {
|
||||
$('thead .batch a').on('click', function(event) {
|
||||
event.preventDefault();
|
||||
if (!$(this).data('toggled')) {
|
||||
$(this).data('toggled', true);
|
||||
$(this).text($(this).data('text'));
|
||||
if (!$(event.target).data('toggled')) {
|
||||
$(event.target).data('toggled', true);
|
||||
$(event.target).text($(event.target).data('text'));
|
||||
buildCheckboxes();
|
||||
} else {
|
||||
performBatchUpdate();
|
||||
@ -199,7 +198,7 @@ $(document).on('turbolinks:load', function() {
|
||||
var observeFileRoleChanges = function() {
|
||||
$(document).on('change', 'select[name$="[role]"]', function() {
|
||||
var is_test_file = $(this).val() === 'teacher_defined_test';
|
||||
var parent = $(this).parents('.panel');
|
||||
var parent = $(this).parents('.card');
|
||||
var fields = parent.find('.test-related-fields');
|
||||
if (is_test_file) {
|
||||
fields.slideDown();
|
||||
@ -262,17 +261,13 @@ $(document).on('turbolinks:load', function() {
|
||||
jqxhr.fail(ajaxError);
|
||||
}
|
||||
|
||||
if ($.isController('exercises')) {
|
||||
if ($.isController('exercises') || $.isController('submissions')) {
|
||||
// ignore tags table since it is in the dom before other tables
|
||||
if ($('table:not(#tags-table)').isPresent()) {
|
||||
enableBatchUpdate();
|
||||
} else if ($('.edit_exercise, .new_exercise').isPresent()) {
|
||||
execution_environments = $('form').data('execution-environments');
|
||||
file_types = $('form').data('file-types');
|
||||
// new MarkdownEditor('#exercise_instructions');
|
||||
// new MarkdownEditor('#exercise_description')
|
||||
// todo: add an ace editor for each file
|
||||
new PagedownEditor('#exercise_description');
|
||||
|
||||
enableInlineFileCreation();
|
||||
inferFileAttributes();
|
||||
|
@ -14,11 +14,11 @@ $(document).on('turbolinks:load', function() {
|
||||
var alternative_input = parent.find('.alternative-input');
|
||||
|
||||
if (alternative_input.attr('disabled')) {
|
||||
$(this).text($(this).data('text-toggled'));
|
||||
$(this).text($(event.target).data('text-toggled'));
|
||||
original_input.attr('disabled', true).hide();
|
||||
alternative_input.attr('disabled', false).show();
|
||||
} else {
|
||||
$(this).text($(this).data('text-initial'));
|
||||
$(this).text($(event.target).data('text-initial'));
|
||||
alternative_input.attr('disabled', true).hide();
|
||||
original_input.attr('disabled', false).show();
|
||||
}
|
||||
@ -26,5 +26,27 @@ $(document).on('turbolinks:load', function() {
|
||||
});
|
||||
|
||||
window.CodeOcean.CHOSEN_OPTIONS = CHOSEN_OPTIONS;
|
||||
$('select:visible').chosen(CHOSEN_OPTIONS);
|
||||
chosen_inputs = $('select').filter(function(){
|
||||
return !$(this).parents('ul').is('#dummies');
|
||||
});
|
||||
|
||||
// enable chosen hook when editing an exercise to update ace code highlighting
|
||||
if ($.isController('exercises') && $('.edit_exercise, .new_exercise').isPresent()) {
|
||||
chosen_inputs.filter(function(){
|
||||
return $(this).attr('id').includes('file_type_id');
|
||||
}).on('change chosen:ready', function(event, parameter) {
|
||||
// Set ACE editor mode (for code highlighting) on change of file type and after initialization
|
||||
editorInstance = $(event.target).closest('.card-body').find('.editor')[0];
|
||||
selectedFileType = event.target.value;
|
||||
CodeOceanEditor.updateEditorModeToFileTypeID(editorInstance, selectedFileType);
|
||||
})
|
||||
}
|
||||
|
||||
chosen_inputs.chosen(CHOSEN_OPTIONS);
|
||||
});
|
||||
|
||||
// Remove some elements before going back to an older site. Otherwise, they might not work.
|
||||
$(document).on('turbolinks:before-cache', function() {
|
||||
$('.chosen-container').remove();
|
||||
$('#wmd-button-row-description').remove();
|
||||
});
|
||||
|
@ -9,7 +9,7 @@
|
||||
});
|
||||
editor.setShowPrintMargin(false);
|
||||
var session = editor.getSession();
|
||||
session.setMode('markdown');
|
||||
session.setMode('ace/mode/markdown');
|
||||
session.setUseWrapMode(true);
|
||||
session.setValue($(selector).val());
|
||||
};
|
||||
|
@ -1,10 +0,0 @@
|
||||
(function() {
|
||||
var ACE_FILES_PATH = '/assets/ace/';
|
||||
|
||||
window.PagedownEditor = function(selector) {
|
||||
var converter = Markdown.getSanitizingConverter();
|
||||
var editor = new Markdown.Editor( converter );
|
||||
|
||||
editor.run();
|
||||
};
|
||||
})();
|
2131
app/assets/javascripts/pagedown/markdown.editor.js.erb
Normal file
2131
app/assets/javascripts/pagedown/markdown.editor.js.erb
Normal file
File diff suppressed because it is too large
Load Diff
43
app/assets/javascripts/pagedown/pagedown.js.erb
Normal file
43
app/assets/javascripts/pagedown/pagedown.js.erb
Normal file
@ -0,0 +1,43 @@
|
||||
//= require markdown.converter
|
||||
// markdown.editor is slightly adjusted to work with Bootstrap 4.
|
||||
// Taken from https://github.com/hughevans/pagedown-bootstrap-rails, V2.1.4
|
||||
//= require markdown.editor
|
||||
//= require markdown.sanitizer
|
||||
//= require markdown.extra
|
||||
|
||||
renderPagedown = function() {
|
||||
$(".wmd-output").each(function (i) {
|
||||
const converter = new Markdown.Converter();
|
||||
const content = $(this).html();
|
||||
return $(this).html(converter.makeHtml(content));
|
||||
})
|
||||
};
|
||||
|
||||
createPagedownEditor = function( selector, context ) {
|
||||
if (context == null) { context = 'body'; }
|
||||
return $(selector, context).each(function(i, input) {
|
||||
if ($(input).data('is_rendered')) {
|
||||
return;
|
||||
}
|
||||
const attr = $(input).attr('id').split('wmd-input')[1];
|
||||
const converter = new Markdown.Converter();
|
||||
Markdown.Extra.init(converter);
|
||||
const help = {
|
||||
handler() {
|
||||
window.open('http://daringfireball.net/projects/markdown/syntax');
|
||||
return false;
|
||||
},
|
||||
title: "<%= I18n.t('components.markdown_editor.help', default: 'Markdown Editing Help') %>"
|
||||
};
|
||||
|
||||
const editor = new Markdown.Editor(converter, attr, help);
|
||||
editor.run();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
return $(input).data('is_rendered', true);
|
||||
});
|
||||
};
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
renderPagedown();
|
||||
return createPagedownEditor('.wmd-input');
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
$(document).ready(function(){
|
||||
$(document).on('turbolinks:load', function(){
|
||||
(function vendorTableSorter(){
|
||||
/*
|
||||
SortTable
|
||||
|
@ -49,7 +49,7 @@ $(document).on('turbolinks:load', function() {
|
||||
|
||||
var refreshData = function (callback) {
|
||||
var params = new URLSearchParams(window.location.search.slice(1));
|
||||
var jqxhr = $.ajax(prefix + '-activity-history.json', {
|
||||
var jqxhr = $.ajax('/statistics/graphs/' + prefix + '-activity-history.json', {
|
||||
dataType: 'json',
|
||||
data: {from: params.get('from'), to: params.get('to'), interval: params.get('interval')},
|
||||
method: 'GET'
|
||||
|
@ -101,7 +101,7 @@ $(document).on('turbolinks:load', function() {
|
||||
});
|
||||
}
|
||||
|
||||
manageGraph('user-activity', 'graphs/user-activity', 10);
|
||||
manageGraph('rfc-activity', 'graphs/rfc-activity', 30);
|
||||
manageGraph('user-activity', '/statistics/graphs/user-activity', 10);
|
||||
manageGraph('rfc-activity', '/statistics/graphs/rfc-activity', 30);
|
||||
}
|
||||
});
|
||||
|
@ -5,30 +5,40 @@ $(document).on('turbolinks:load', function() {
|
||||
|
||||
var currentSubmission = 0;
|
||||
var active_file = undefined;
|
||||
var fileTrees = []
|
||||
var fileTrees = [];
|
||||
var editor = undefined;
|
||||
var fileTypeById = {}
|
||||
var fileTypeById = {};
|
||||
|
||||
var showActiveFile = function() {
|
||||
var session = editor.getSession();
|
||||
var fileType = fileTypeById[active_file.file_type_id]
|
||||
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);
|
||||
|
||||
showFileTree(currentSubmission);
|
||||
filetree = $(fileTrees[currentSubmission])
|
||||
// The event ready.jstree is fired too early and thus doesn't work.
|
||||
var selectFileInJsTree = function() {
|
||||
if (!filetree.hasClass('jstree-loading')) {
|
||||
filetree.jstree("deselect_all");
|
||||
filetree.jstree().select_node(active_file.file_id);
|
||||
} else {
|
||||
setTimeout(selectFileInJsTree, 250);
|
||||
}
|
||||
};
|
||||
|
||||
filetree = $(fileTrees[currentSubmission]);
|
||||
selectFileInJsTree();
|
||||
// Finally change jstree element to prevent flickering
|
||||
showFileTree(currentSubmission);
|
||||
};
|
||||
|
||||
var initializeFileTree = function() {
|
||||
$('.files').each(function(index, element) {
|
||||
fileTree = $(element).jstree($(element).data('entries'));
|
||||
fileTree.on('click', 'li.jstree-leaf', function() {
|
||||
var id = parseInt($(this).attr('id'))
|
||||
var id = parseInt($(this).attr('id'));
|
||||
_.each(files[currentSubmission], function(file) {
|
||||
if (file.file_id === id) {
|
||||
active_file = file;
|
||||
@ -42,8 +52,8 @@ $(document).on('turbolinks:load', function() {
|
||||
|
||||
var showFileTree = function(index) {
|
||||
$('.files').hide();
|
||||
$(fileTrees[index].context).show();
|
||||
}
|
||||
$(fileTrees[index]).show();
|
||||
};
|
||||
|
||||
if ($.isController('exercises') && $('#timeline').isPresent()) {
|
||||
|
||||
@ -85,7 +95,7 @@ $(document).on('turbolinks:load', function() {
|
||||
if (file.name === active_file.name) {
|
||||
fileIndex = index;
|
||||
}
|
||||
})
|
||||
});
|
||||
active_file = currentFiles[fileIndex];
|
||||
showActiveFile();
|
||||
});
|
||||
@ -94,10 +104,10 @@ $(document).on('turbolinks:load', function() {
|
||||
clearInterval(playInterval);
|
||||
playInterval = undefined;
|
||||
playButton.find('span.fa').removeClass('fa-pause').addClass('fa-play')
|
||||
}
|
||||
};
|
||||
|
||||
playButton.on('click', function(event) {
|
||||
if (playInterval == undefined) {
|
||||
if (playInterval === undefined) {
|
||||
playInterval = setInterval(function() {
|
||||
if ($.isController('exercises') && $('#timeline').isPresent() && slider.val() < submissions.length - 1) {
|
||||
slider.val(parseInt(slider.val()) + 1);
|
||||
@ -112,7 +122,7 @@ $(document).on('turbolinks:load', function() {
|
||||
}
|
||||
});
|
||||
|
||||
active_file = files[0][0]
|
||||
active_file = files[0][0];
|
||||
initializeFileTree();
|
||||
showActiveFile();
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ span.caret {
|
||||
.progress-bar {
|
||||
line-height: initial;
|
||||
min-width: 2em;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +36,7 @@ span.caret {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.badge {
|
||||
.badge-pill {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,14 @@
|
||||
}
|
||||
|
||||
.dropdown-submenu > .dropdown-menu {
|
||||
top: 0;
|
||||
top: -0.2em;
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.dropdown-submenu.open > ul.dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropdown-submenu > a:after {
|
||||
display: block;
|
||||
content: " ";
|
||||
@ -25,11 +29,11 @@
|
||||
border-left-color: #ffffff;
|
||||
}
|
||||
|
||||
.dropdown-submenu.pull-left {
|
||||
.dropdown-submenu.float-left {
|
||||
float: none;
|
||||
}
|
||||
|
||||
.dropdown-submenu.pull-left > .dropdown-menu {
|
||||
.dropdown-submenu.float-left > .dropdown-menu {
|
||||
left: -100%;
|
||||
margin-left: 10px;
|
||||
-webkit-border-radius: 6px 0 6px 6px;
|
||||
|
@ -144,7 +144,8 @@ button i.fa-spin {
|
||||
min-height: 1px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
box-sizing: border-box
|
||||
box-sizing: border-box;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.output-col-collapsed {
|
||||
@ -155,7 +156,8 @@ button i.fa-spin {
|
||||
min-height: 1px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
box-sizing: border-box
|
||||
box-sizing: border-box;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.enforce-top-margin {
|
||||
@ -166,14 +168,14 @@ button i.fa-spin {
|
||||
margin-right: 10px !important;
|
||||
}
|
||||
|
||||
.description-panel-collapsed {
|
||||
.description-card-collapsed {
|
||||
-webkit-transition: width 2s;
|
||||
transition: width 2s;
|
||||
height: 0px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.description-panel {
|
||||
.description-card {
|
||||
height: auto;
|
||||
-webkit-transition: height 2s;
|
||||
transition: height 2s;
|
||||
|
@ -57,10 +57,6 @@ rect.value-bar {
|
||||
}
|
||||
}
|
||||
|
||||
.table-responsive#exercise-list {
|
||||
max-height: 512px;
|
||||
}
|
||||
|
||||
.exercise-id-tooltip {
|
||||
position: absolute;
|
||||
display: none;
|
||||
|
@ -35,11 +35,19 @@ input[type='file'] {
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
.lead.description-panel-collapsed {
|
||||
.lead.description-card-collapsed {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
[data-toggle="collapse"] .fa:before {
|
||||
content: "\f139";
|
||||
}
|
||||
|
||||
[data-toggle="collapse"].collapsed .fa:before {
|
||||
content: "\f13a";
|
||||
}
|
||||
|
||||
// Graph Settings
|
||||
|
||||
.axis path {
|
||||
|
@ -127,7 +127,7 @@
|
||||
background-color:#f9f9f9
|
||||
}
|
||||
|
||||
.ace_tooltip {
|
||||
:not(.allow_ace_tooltip) > .ace_tooltip {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,8 @@ tr.highlight {
|
||||
grid-gap: 10px;
|
||||
|
||||
> a {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
color: #fff !important;
|
||||
text-decoration: none !important;
|
||||
|
||||
> div {
|
||||
border: 2px solid #0055ba;
|
||||
|
@ -38,7 +38,7 @@ class FileTypesController < ApplicationController
|
||||
end
|
||||
|
||||
def set_editor_modes
|
||||
@editor_modes = Dir.glob('vendor/assets/javascripts/ace/mode-*.js').map do |filename|
|
||||
@editor_modes = Dir.glob('vendor/assets/javascripts/ace/mode-*.js').sort.map do |filename|
|
||||
name = filename.gsub(/\w+\/|mode-|.js$/, '')
|
||||
[name, "ace/mode/#{name}"]
|
||||
end
|
||||
|
42
app/helpers/pagedown_form_builder.rb
Normal file
42
app/helpers/pagedown_form_builder.rb
Normal file
@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class PagedownFormBuilder < ActionView::Helpers::FormBuilder
|
||||
def pagedown(method, args)
|
||||
# Adopt simple form builder to work with form_for
|
||||
@attribute_name = method
|
||||
@input_html_options = args[:input_html]
|
||||
|
||||
@template.capture do
|
||||
@template.concat wmd_button_bar
|
||||
@template.concat wmd_textarea
|
||||
@template.concat wmd_preview if show_wmd_preview?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wmd_button_bar
|
||||
@template.content_tag :div, nil, id: "wmd-button-bar-#{base_id}"
|
||||
end
|
||||
|
||||
def wmd_textarea
|
||||
@template.text_area @object_name, @attribute_name,
|
||||
**@input_html_options,
|
||||
class: 'form-control wmd-input',
|
||||
id: "wmd-input-#{base_id}"
|
||||
end
|
||||
|
||||
def wmd_preview
|
||||
@template.content_tag :div, nil,
|
||||
class: 'wmd-preview',
|
||||
id: "wmd-preview-#{base_id}"
|
||||
end
|
||||
|
||||
def show_wmd_preview?
|
||||
@input_html_options[:preview].present?
|
||||
end
|
||||
|
||||
def base_id
|
||||
options[:pagedown_id_suffix] || @attribute_name
|
||||
end
|
||||
end
|
@ -3,6 +3,6 @@ class ErrorTemplate < ApplicationRecord
|
||||
has_and_belongs_to_many :error_template_attributes
|
||||
|
||||
def to_s
|
||||
"#{id} [#{name}]"
|
||||
name
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,6 @@ class ErrorTemplateAttribute < ApplicationRecord
|
||||
has_and_belongs_to_many :error_template
|
||||
|
||||
def to_s
|
||||
"#{id} [#{key}]"
|
||||
key
|
||||
end
|
||||
end
|
||||
|
@ -3,17 +3,17 @@
|
||||
- if model = Kernel.const_get(controller_path.classify) rescue nil
|
||||
- object = model.find_by(id: params[:id])
|
||||
- if model.try(:nested_resource?)
|
||||
li = model.model_name.human(count: 2)
|
||||
li.breadcrumb-item = model.model_name.human(count: 2)
|
||||
- if object
|
||||
li = object
|
||||
li.breadcrumb-item = object
|
||||
- else
|
||||
li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
|
||||
li.breadcrumb-item = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
|
||||
- if object
|
||||
li = link_to(object, send(:"#{model.model_name.singular}_path", object))
|
||||
li.active
|
||||
li.breadcrumb-item = link_to(object, send(:"#{model.model_name.singular}_path", object))
|
||||
li.breadcrumb-item.active
|
||||
- if I18n.translation_present?("shared.#{params[:action]}")
|
||||
= t("shared.#{params[:action]}")
|
||||
- else
|
||||
= t("#{controller_name}.index.#{params[:action]}")
|
||||
- else
|
||||
li.active = t("breadcrumbs.#{controller_name}.#{params[:action]}")
|
||||
li.breadcrumb-item.active = t("breadcrumbs.#{controller_name}.#{params[:action]}")
|
||||
|
@ -1,6 +1,7 @@
|
||||
#flash-container
|
||||
#flash.container.fixed_error_messages data-message-failure=t('shared.message_failure')
|
||||
- %w[alert danger info notice success warning].each do |severity|
|
||||
div.alert.flash class="alert-#{{'alert' => 'warning', 'notice' => 'success'}.fetch(severity, severity)}"
|
||||
p id="flash-#{severity}" = flash[severity]
|
||||
span.fa.fa-times
|
||||
div.alert.flash class="alert-#{{'alert' => 'warning', 'notice' => 'success'}.fetch(severity, severity)} alert-dismissible fade show"
|
||||
p.mb-0 id="flash-#{severity}" = flash[severity]
|
||||
button type="button" class="close" data-dismiss="alert" aria-label="Close"
|
||||
span.text-white aria-hidden="true" ×
|
||||
|
@ -1,7 +1,7 @@
|
||||
li.dropdown
|
||||
a.dropdown-toggle data-toggle='dropdown' href='#'
|
||||
li.nav-item.dropdown
|
||||
a.nav-link.dropdown-toggle.mx-3 data-toggle='dropdown' href='#'
|
||||
= t("locales.#{I18n.locale}")
|
||||
span.caret
|
||||
ul.dropdown-menu role='menu'
|
||||
ul.dropdown-menu.p-0.mt-1 role='menu'
|
||||
- I18n.available_locales.sort_by { |locale| t("locales.#{locale}") }.each do |locale|
|
||||
li = link_to(t("locales.#{locale}"), url_for(params.permit!.merge(locale: locale)))
|
||||
li = link_to(t("locales.#{locale}"), url_for(params.permit!.merge(locale: locale)), class: 'dropdown-item')
|
||||
|
@ -1,14 +1,14 @@
|
||||
- if current_user.try(:internal_user?)
|
||||
ul.nav.navbar-nav
|
||||
li.dropdown
|
||||
a.dropdown-toggle data-toggle='dropdown' href='#'
|
||||
li.nav-item.dropdown
|
||||
a.nav-link.dropdown-toggle.mx-3 data-toggle='dropdown' href='#'
|
||||
= t('shared.administration')
|
||||
span.caret
|
||||
ul.dropdown-menu role='menu'
|
||||
ul.dropdown-menu.p-0.mt-1 role='menu'
|
||||
- if current_user.admin?
|
||||
li = link_to(t('breadcrumbs.dashboard.show'), admin_dashboard_path, 'data-turbolinks' => "false")
|
||||
li = link_to(t('breadcrumbs.statistics.show'), statistics_path)
|
||||
li.divider
|
||||
li = link_to(t('breadcrumbs.dashboard.show'), admin_dashboard_path, class: 'dropdown-item', 'data-turbolinks' => "false")
|
||||
li = link_to(t('breadcrumbs.statistics.show'), statistics_path, class: 'dropdown-item')
|
||||
li.dropdown-divider role='separator'
|
||||
= render('navigation_submenu', title: t('activerecord.models.exercise.other'),
|
||||
models: [Exercise, ExerciseCollection, ProxyExercise, Tag, Submission], link: exercises_path, cached: true)
|
||||
= render('navigation_submenu', title: t('navigation.sections.users'), models: [InternalUser, ExternalUser],
|
||||
|
@ -1,2 +1,2 @@
|
||||
- if policy(model).index?
|
||||
li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
|
||||
li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"), class: 'dropdown-item')
|
||||
|
@ -1,6 +1,6 @@
|
||||
li.dropdown.dropdown-submenu
|
||||
li.dropdown-submenu
|
||||
- link = link.nil? ? "#" : link
|
||||
a href=link class="dropdown-toggle" data-toggle="dropdown" = title
|
||||
ul class="dropdown-menu"
|
||||
a.dropdown-item.dropdown-toggle href=link data-toggle="dropdown" = title
|
||||
ul.dropdown-menu.p-0
|
||||
- models.each do |model|
|
||||
= render('navigation_collection_link', model: model, cached: true)
|
||||
|
@ -1,19 +1,19 @@
|
||||
- if current_user
|
||||
li.dropdown
|
||||
a.dropdown-toggle data-toggle='dropdown' href='#'
|
||||
li.nav-item.dropdown
|
||||
a.nav-link.dropdown-toggle data-toggle='dropdown' href='#'
|
||||
i.fa.fa-user
|
||||
= current_user
|
||||
span.caret
|
||||
ul.dropdown-menu role='menu'
|
||||
ul.dropdown-menu.p-0.mt-1 role='menu'
|
||||
- if current_user.internal_user?
|
||||
li = link_to(t('consumers.show.link'), current_user.consumer) if current_user.consumer
|
||||
li = link_to(t('internal_users.show.link'), current_user)
|
||||
li = link_to(t('request_for_comments.index.all'), request_for_comments_path)
|
||||
li = link_to(t('request_for_comments.index.get_my_rfc_activity'), my_rfc_activity_path)
|
||||
li = link_to(t('request_for_comments.index.get_my_comment_requests'), my_request_for_comments_path)
|
||||
li = link_to(t('consumers.show.link'), current_user.consumer, class: 'dropdown-item') if current_user.consumer
|
||||
li = link_to(t('internal_users.show.link'), current_user, class: 'dropdown-item')
|
||||
li = link_to(t('request_for_comments.index.all'), request_for_comments_path, class: 'dropdown-item')
|
||||
li = link_to(t('request_for_comments.index.get_my_rfc_activity'), my_rfc_activity_path, class: 'dropdown-item')
|
||||
li = link_to(t('request_for_comments.index.get_my_comment_requests'), my_request_for_comments_path, class: 'dropdown-item')
|
||||
- if current_user.internal_user?
|
||||
li = link_to(t('sessions.destroy.link'), sign_out_path, method: :delete)
|
||||
li = link_to(t('sessions.destroy.link'), sign_out_path, method: :delete, class: 'dropdown-item')
|
||||
- else
|
||||
li = link_to(sign_in_path) do
|
||||
li.nav-item = link_to(sign_in_path, class: 'nav-link') do
|
||||
i.fa.fa-sign-in
|
||||
= t('sessions.new.link')
|
||||
|
@ -9,7 +9,7 @@ h1 = CodeHarborLink.model_name.human(count: 2)
|
||||
tbody
|
||||
- @code_harbor_links.each do |code_harbor_link|
|
||||
tr
|
||||
td = code_harbor_link.oauth2token
|
||||
td = link_to(code_harbor_link.oauth2token, code_harbor_link)
|
||||
td = link_to(t('shared.show'), code_harbor_link)
|
||||
td = link_to(t('shared.edit'), edit_code_harbor_link_path(code_harbor_link))
|
||||
td = link_to(t('shared.destroy'), code_harbor_link, data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
|
@ -12,5 +12,5 @@
|
||||
= f.label(:file_template_id, t('activerecord.attributes.file.file_template_id'))
|
||||
= f.collection_select(:file_template_id, FileTemplate.all.order(:name), :id, :name, {:include_blank => true}, class: 'form-control')
|
||||
= f.hidden_field(:context_id)
|
||||
.hidden#noTemplateLabel data-text=t('file_template.no_template_label')
|
||||
.d-none#noTemplateLabel data-text=t('file_template.no_template_label')
|
||||
.actions = render('shared/submit_button', f: f, object: CodeOcean::File.new)
|
||||
|
@ -9,7 +9,7 @@ h1 = Consumer.model_name.human(count: 2)
|
||||
tbody
|
||||
- @consumers.each do |consumer|
|
||||
tr
|
||||
td = consumer.name
|
||||
td = link_to(consumer.name, consumer)
|
||||
td = link_to(t('shared.show'), consumer)
|
||||
td = link_to(t('shared.edit'), edit_consumer_path(consumer))
|
||||
td = link_to(t('shared.destroy'), consumer, data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
|
@ -9,8 +9,9 @@
|
||||
.form-group
|
||||
= f.label(:regex)
|
||||
= f.text_field(:regex, class: 'form-control', required: true)
|
||||
.help-block == t('error_templates.hints.signature')
|
||||
.form-group
|
||||
= f.check_box(:important)
|
||||
.help-block.form-text == t('error_templates.hints.signature')
|
||||
.form-check.form-group
|
||||
label.form-check-label
|
||||
= f.check_box(:important, class: 'form-check-input')
|
||||
= t('activerecord.attributes.error_template_attribute.important')
|
||||
.actions = render('shared/submit_button', f: f, object: @error_template_attribute)
|
||||
|
@ -17,9 +17,10 @@ h1 = ErrorTemplateAttribute.model_name.human(count: 2)
|
||||
span class="fa fa-star" aria-hidden="true"
|
||||
- else
|
||||
span class="fa fa-star-o" aria-hidden="true"
|
||||
td = error_template_attribute.key
|
||||
td = link_to(error_template_attribute.key, error_template_attribute)
|
||||
td = error_template_attribute.description
|
||||
td = error_template_attribute.regex
|
||||
td
|
||||
code = error_template_attribute.regex
|
||||
td = link_to(t('shared.show'), error_template_attribute)
|
||||
td = link_to(t('shared.edit'), edit_error_template_attribute_path(error_template_attribute))
|
||||
td = link_to(t('shared.destroy'), error_template_attribute, data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
|
@ -2,7 +2,10 @@ h1
|
||||
= @error_template_attribute
|
||||
= render('shared/edit_button', object: @error_template_attribute)
|
||||
|
||||
- [:key, :description, :regex, :important].each do |attribute|
|
||||
- [:key, :description].each do |attribute|
|
||||
= row(label: "error_template_attribute.#{attribute}", value: @error_template_attribute.send(attribute))
|
||||
= row(label: "error_template_attribute.key") do
|
||||
code = @error_template_attribute.key
|
||||
= row(label: "error_template_attribute.important", value: @error_template_attribute.important)
|
||||
|
||||
// todo: used by
|
||||
|
@ -9,12 +9,12 @@
|
||||
.form-group
|
||||
= f.label(:signature)
|
||||
= f.text_field(:signature, class: 'form-control')
|
||||
.help-block == t('error_templates.hints.signature')
|
||||
.help-block.form-text == t('error_templates.hints.signature')
|
||||
.form-group
|
||||
= f.label(:description)
|
||||
= f.text_field(:description, class: 'form-control')
|
||||
.form-group
|
||||
= f.label(:hint)
|
||||
= f.text_field(:hint, class: 'form-control')
|
||||
.help-block == t('error_templates.hints.hint_templates')
|
||||
.help-block.form-text == t('error_templates.hints.hint_templates')
|
||||
.actions = render('shared/submit_button', f: f, object: @error_template)
|
||||
|
@ -11,7 +11,7 @@ h1 = ErrorTemplate.model_name.human(count: 2)
|
||||
tbody
|
||||
- @error_templates.each do |error_template|
|
||||
tr
|
||||
td = error_template.name
|
||||
td = link_to(error_template.name, error_template)
|
||||
td = error_template.description
|
||||
td = link_to(error_template.execution_environment)
|
||||
td = link_to(t('shared.show'), error_template)
|
||||
|
@ -4,10 +4,12 @@ h1
|
||||
|
||||
= row(label: 'error_template.name', value: @error_template.name)
|
||||
= row(label: 'exercise.execution_environment', value: link_to(@error_template.execution_environment))
|
||||
- [:signature, :description, :hint].each do |attribute|
|
||||
= row(label: "error_template.signature") do
|
||||
code = @error_template.signature
|
||||
- [:description, :hint].each do |attribute|
|
||||
= row(label: "error_template.#{attribute}", value: @error_template.send(attribute))
|
||||
|
||||
h3
|
||||
h2.mt-4
|
||||
= t 'error_templates.attributes'
|
||||
|
||||
.table-responsive
|
||||
@ -27,9 +29,10 @@ h3
|
||||
span class="fa fa-star" aria-hidden="true"
|
||||
- else
|
||||
span class="fa fa-star-o" aria-hidden="true"
|
||||
td = attribute.key
|
||||
td = link_to(attribute.key, attribute)
|
||||
td = attribute.description
|
||||
td = attribute.regex
|
||||
td
|
||||
code = attribute.regex
|
||||
td = link_to(t('shared.show'), attribute)
|
||||
td = link_to(t('shared.destroy'), attribute_error_template_url(:error_template_attribute_id => attribute.id), :method => :delete)
|
||||
|
||||
@ -37,4 +40,4 @@ h3
|
||||
= collection_select({}, :error_template_attribute_id,
|
||||
ErrorTemplateAttribute.where.not(id: @error_template.error_template_attributes.select(:id).to_a).order('important DESC', :key),
|
||||
:id, :key, {include_blank: false}, class: '')
|
||||
button.btn.btn-default = t('error_templates.add_attribute')
|
||||
button.btn.btn-outline-primary = t('error_templates.add_attribute')
|
||||
|
@ -12,17 +12,17 @@
|
||||
a.toggle-input data={text_initial: t('shared.new'), text_toggled: t('shared.back')} href='#' = t('shared.new')
|
||||
.original-input = f.select(:docker_image, @docker_images, {}, class: 'form-control')
|
||||
= f.text_field(:docker_image, class: 'alternative-input form-control', disabled: true)
|
||||
.help-block == t('.hints.docker_image')
|
||||
.help-block.form-text == t('.hints.docker_image')
|
||||
.form-group
|
||||
= f.label(:exposed_ports)
|
||||
= f.text_field(:exposed_ports, class: 'form-control', placeholder: '3000, 4000')
|
||||
.help-block == t('.hints.exposed_ports')
|
||||
.help-block.form-text == t('.hints.exposed_ports')
|
||||
.form-group
|
||||
= f.label(:memory_limit)
|
||||
= f.number_field(:memory_limit, class: 'form-control', min: DockerClient::MINIMUM_MEMORY_LIMIT, value: f.object.memory_limit || DockerClient::DEFAULT_MEMORY_LIMIT)
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:network_enabled)
|
||||
.form-check.mb-3
|
||||
label.form-check-label
|
||||
= f.check_box(:network_enabled, class: 'form-check-input')
|
||||
= t('activerecord.attributes.execution_environment.network_enabled')
|
||||
.form-group
|
||||
= f.label(:permitted_execution_time)
|
||||
@ -33,11 +33,11 @@
|
||||
.form-group
|
||||
= f.label(:run_command)
|
||||
= f.text_field(:run_command, class: 'form-control', placeholder: 'command %{filename}', required: true)
|
||||
.help-block == t('.hints.command')
|
||||
.help-block.form-text == t('.hints.command')
|
||||
.form-group
|
||||
= f.label(:test_command)
|
||||
= f.text_field(:test_command, class: 'form-control', placeholder: 'command %{filename}')
|
||||
.help-block == t('.hints.command')
|
||||
.help-block.form-text == t('.hints.command')
|
||||
.form-group
|
||||
= f.label(:testing_framework)
|
||||
= f.select(:testing_framework, @testing_framework_adapters, {include_blank: true}, class: 'form-control')
|
||||
|
@ -15,7 +15,7 @@ h1 = ExecutionEnvironment.model_name.human(count: 2)
|
||||
tbody
|
||||
- @execution_environments.each do |execution_environment|
|
||||
tr
|
||||
td = execution_environment.name
|
||||
td = link_to(execution_environment.name, execution_environment)
|
||||
td = link_to(execution_environment.author, execution_environment.author)
|
||||
td = execution_environment.pool_size
|
||||
td = execution_environment.memory_limit
|
||||
|
@ -5,7 +5,10 @@ h1
|
||||
= row(label: 'execution_environment.name', value: @execution_environment.name)
|
||||
= row(label: 'execution_environment.user', value: link_to(@execution_environment.author, @execution_environment.author))
|
||||
= row(label: 'execution_environment.file_type', value: @execution_environment.file_type.present? ? link_to(@execution_environment.file_type, @execution_environment.file_type) : nil)
|
||||
- [:docker_image, :exposed_ports, :memory_limit, :network_enabled, :permitted_execution_time, :pool_size, :run_command, :test_command].each do |attribute|
|
||||
- [:docker_image, :exposed_ports, :memory_limit, :network_enabled, :permitted_execution_time, :pool_size].each do |attribute|
|
||||
= row(label: "execution_environment.#{attribute}", value: @execution_environment.send(attribute))
|
||||
- [:run_command, :test_command].each do |attribute|
|
||||
= row(label: "execution_environment.#{attribute}") do
|
||||
code = @execution_environment.send(attribute)
|
||||
= row(label: 'execution_environment.testing_framework', value: @testing_framework_adapter.try(:framework_name))
|
||||
= row(label: 'execution_environment.help', value: render_markdown(@execution_environment.help))
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
form#exercise-selection
|
||||
.form-group
|
||||
span.label = t('activerecord.attributes.exercise_collections.exercises')
|
||||
span.badge = t('activerecord.attributes.exercise_collections.exercises')
|
||||
.mb-2
|
||||
= collection_select({}, :exercise_ids, exercises, :id, :title, {}, {id: 'add-exercise-list', class: 'form-control', multiple: true})
|
||||
|
||||
button.btn.btn-primary#add-exercises = t('exercise_collections.form.add_exercises')
|
||||
|
@ -3,9 +3,10 @@
|
||||
.form-group
|
||||
= f.label(t('activerecord.attributes.exercise_collections.name'))
|
||||
= f.text_field(:name, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= f.label(t('activerecord.attributes.exercise_collections.use_anomaly_detection'))
|
||||
= f.check_box(:use_anomaly_detection, {class: 'form-control'})
|
||||
.form-check.form-group
|
||||
label.form-check-label
|
||||
= f.check_box(:use_anomaly_detection, class: 'form-check-input')
|
||||
= t('activerecord.attributes.exercise_collections.use_anomaly_detection')
|
||||
.form-group
|
||||
= f.label(t('activerecord.attributes.exercise_collections.user'))
|
||||
= f.collection_select(:user_id, InternalUser.order(:name), :id, :name, {}, {class: 'form-control'})
|
||||
@ -26,10 +27,10 @@
|
||||
td = link_to(t('shared.show'), item.exercise, 'data-turbolinks' => "false")
|
||||
td
|
||||
a.remove-exercise href='#' = t('shared.destroy')
|
||||
.hidden
|
||||
.d-none
|
||||
= f.collection_select(:exercise_ids, Exercise.all, :id, :title, {}, {id: 'exercise-select', class: 'form-control', multiple: true})
|
||||
.exercise-actions
|
||||
button.btn.btn-primary type='button' data-toggle='modal' data-target='#add-exercise-modal' = t('exercise_collections.form.add_exercises')
|
||||
button.btn.btn-outline-primary type='button' data-toggle='modal' data-target='#add-exercise-modal' = t('exercise_collections.form.add_exercises')
|
||||
button.btn.btn-secondary#sort-button type='button' = t('exercise_collections.form.sort_by_title')
|
||||
|
||||
.actions = render('shared/submit_button', f: f, object: @exercise_collection)
|
||||
|
@ -7,7 +7,7 @@ h1
|
||||
= row(label: 'exercise_collections.use_anomaly_detection', value: @exercise_collection.use_anomaly_detection)
|
||||
= row(label: 'exercise_collections.updated_at', value: @exercise_collection.updated_at)
|
||||
|
||||
h4 = t('activerecord.attributes.exercise_collections.exercises')
|
||||
h4.mt-4 = t('activerecord.attributes.exercise_collections.exercises')
|
||||
.table-responsive#exercise-list
|
||||
table.table
|
||||
thead
|
||||
@ -24,5 +24,5 @@ h4 = t('activerecord.attributes.exercise_collections.exercises')
|
||||
td = exercise_collection_item.position
|
||||
td = link_to(exercise.title, exercise)
|
||||
td = link_to_if(exercise.execution_environment && policy(exercise.execution_environment).show?, exercise.execution_environment, exercise.execution_environment)
|
||||
td = exercise.user.name
|
||||
td = link_to_if(exercise.user && policy(exercise.user).show?, exercise.user.name, exercise.user)
|
||||
td = link_to(t('shared.statistics'), statistics_exercise_path(exercise), 'data-turbolinks' => "false")
|
||||
|
@ -6,7 +6,7 @@ h1 = @exercise_collection
|
||||
= row(label: 'exercises.statistics.average_worktime', value: @exercise_collection.average_working_time.round(3).to_s + 's')
|
||||
|
||||
#graph
|
||||
#data.hidden(data-working-times=ActiveSupport::JSON.encode(@exercise_collection.collection_statistics) data-average-working-time=@exercise_collection.average_working_time)
|
||||
#data.d-none(data-working-times=ActiveSupport::JSON.encode(@exercise_collection.collection_statistics) data-average-working-time=@exercise_collection.average_working_time)
|
||||
#legend
|
||||
- {time: t('exercises.statistics.average_worktime'),
|
||||
min: 'min. anomaly threshold',
|
||||
|
@ -3,5 +3,5 @@
|
||||
|
|
||||
a.toggle-input data={text_initial: t('shared.upload_file'), text_toggled: t('shared.back')} href='#' = t('shared.upload_file')
|
||||
= form.text_area(attribute, class: 'code-field form-control', rows: 16, style: "display:none;")
|
||||
= form.file_field(attribute, class: 'alternative-input form-control', disabled: true)
|
||||
= form.file_field(attribute, class: 'alternative-input form-control-file', disabled: true)
|
||||
= render partial: 'editor_edit', locals: { exercise: @exercise }
|
||||
|
@ -6,8 +6,7 @@
|
||||
- hide_rfc_button = @hide_rfc_button || false
|
||||
#editor.row data-exercise-id=@exercise.id data-message-depleted=t('exercises.editor.depleted') data-message-timeout=t('exercises.editor.timeout', permitted_execution_time: @exercise.execution_environment.permitted_execution_time) data-errors-url=execution_environment_errors_path(exercise.execution_environment) data-submissions-url=submissions_path data-user-id=@current_user.id data-user-external-id=external_user_external_id data-working-times-url=working_times_exercise_path(@exercise) data-intervention-save-url=intervention_exercise_path(@exercise) data-rfc-interventions=show_rfc_interventions data-break-interventions=show_break_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise)
|
||||
div id="sidebar" class=(@exercise.hide_file_tree ? 'sidebar-col-collapsed' : 'sidebar-col') = render('editor_file_tree', exercise: @exercise, files: @files)
|
||||
div id='output_sidebar' class='output-col-collapsed' = render('exercises/editor_output', external_user_id: external_user_id, consumer_id: consumer_id )
|
||||
div id='frames' class='editor-col'
|
||||
div.editor-col.col.p-0 id='frames'
|
||||
#editor-buttons.btn-group.enforce-bottom-margin
|
||||
= render('editor_button', disabled: true, icon: 'fa fa-ban', id: 'dummy', label: t('exercises.editor.dummy'))
|
||||
= render('editor_button', icon: 'fa fa-desktop', id: 'render', label: t('exercises.editor.render'))
|
||||
@ -24,6 +23,7 @@
|
||||
= t('exercises.editor.lastsaved')
|
||||
span
|
||||
button style="display:none" id="autosave"
|
||||
div id='output_sidebar' class='output-col-collapsed' = render('exercises/editor_output', external_user_id: external_user_id, consumer_id: consumer_id )
|
||||
|
||||
|
||||
= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent')
|
||||
|
@ -1,4 +1,4 @@
|
||||
button.btn class=local_assigns.fetch(:classes, 'btn-primary btn-sm') *local_assigns.fetch(:data, {}) disabled=local_assigns.fetch(:disabled, false) id=id title=local_assigns[:title] type='button'
|
||||
button.btn class=local_assigns.fetch(:classes, 'btn-primary btn-lg') *local_assigns.fetch(:data, {}) disabled=local_assigns.fetch(:disabled, false) id=id title=local_assigns[:title] type='button'
|
||||
i.fa.fa-circle-o-notch.fa-spin
|
||||
i class=icon
|
||||
i class=(label.present? ? icon : "#{icon} m-0")
|
||||
= label
|
||||
|
@ -1,5 +1,5 @@
|
||||
#editor-edit.panel-group.row.original-input data-exercise-id=@exercise.id
|
||||
#editor-edit.original-input data-exercise-id=@exercise.id
|
||||
#frames
|
||||
.edit-frame
|
||||
.editor-content.hidden
|
||||
.editor
|
||||
.editor-content.d-none
|
||||
.editor.allow_ace_tooltip
|
@ -1,18 +1,18 @@
|
||||
div id='sidebar-collapsed' class=(@exercise.hide_file_tree ? '' : 'hidden')
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-plus-square', id: 'sidebar-collapse-collapsed', label:'', title:t('exercises.editor.expand_action_sidebar'))
|
||||
div id='sidebar-collapsed' class=(@exercise.hide_file_tree ? '' : 'd-none')
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-plus-square', id: 'sidebar-collapse-collapsed', label:'', title:t('exercises.editor.expand_action_sidebar'))
|
||||
|
||||
- if @exercise.allow_file_creation and not @exercise.hide_file_tree?
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm enforce-top-margin', data: {:'data-cause' => 'file', :'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-plus', id: 'create-file-collapsed', label:'', title: t('exercises.editor.create_file'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn enforce-top-margin', data: {:'data-cause' => 'file', :'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-plus', id: 'create-file-collapsed', label:'', title: t('exercises.editor.create_file'))
|
||||
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm enforce-top-margin', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-download', id: 'download-collapsed', label:'', title: t('exercises.editor.download'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm enforce-top-margin', data: {:'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(@exercise), :'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-history', id: 'start-over-collapsed', label:'', title: t('exercises.editor.start_over'))
|
||||
- if !@course_token.blank?
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm enforce-top-margin', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-search', id: 'sidebar-search-collapsed', label: '', title: t('search.search_in_forum'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn enforce-top-margin', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-download', id: 'download-collapsed', label:'', title: t('exercises.editor.download'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn enforce-top-margin', data: {:'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(@exercise), :'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-history', id: 'start-over-collapsed', label:'', title: t('exercises.editor.start_over'))
|
||||
//- if !@course_token.blank?
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn enforce-top-margin', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-search', id: 'sidebar-search-collapsed', label: '', title: t('search.search_in_forum'))
|
||||
|
||||
div id='sidebar-uncollapsed' class=(@exercise.hide_file_tree ? 'hidden' : '')
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', icon: 'fa fa-minus-square', id: 'sidebar-collapse', label: t('exercises.editor.collapse_action_sidebar'))
|
||||
div id='sidebar-uncollapsed' class=(@exercise.hide_file_tree ? 'd-none' : '')
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn', icon: 'fa fa-minus-square', id: 'sidebar-collapse', label: t('exercises.editor.collapse_action_sidebar'))
|
||||
|
||||
div class=(@exercise.hide_file_tree ? 'hidden' : '')
|
||||
div class=(@exercise.hide_file_tree ? 'd-none' : '')
|
||||
hr
|
||||
|
||||
#files data-entries=FileTree.new(files).to_js_tree
|
||||
@ -20,11 +20,11 @@ div id='sidebar-uncollapsed' class=(@exercise.hide_file_tree ? 'hidden' : '')
|
||||
hr
|
||||
|
||||
- if @exercise.allow_file_creation and not @exercise.hide_file_tree?
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', data: {:'data-cause' => 'file'}, icon: 'fa fa-plus', id: 'create-file', label: t('exercises.editor.create_file'))
|
||||
= render('editor_button', classes: 'btn-block btn-warning btn-sm', data: {:'data-cause' => 'file', :'data-message-confirm' => t('shared.confirm_destroy')}, icon: 'fa fa-times', id: 'destroy-file', label: t('exercises.editor.destroy_file'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn', data: {:'data-cause' => 'file'}, icon: 'fa fa-plus', id: 'create-file', label: t('exercises.editor.create_file'))
|
||||
= render('editor_button', classes: 'btn-block btn-warning btn', data: {:'data-cause' => 'file', :'data-message-confirm' => t('shared.confirm_destroy')}, icon: 'fa fa-times', id: 'destroy-file', label: t('exercises.editor.destroy_file'))
|
||||
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm enforce-top-margin', icon: 'fa fa-download', id: 'download', label: t('exercises.editor.download'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', data: {:'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(@exercise)}, icon: 'fa fa-history', id: 'start-over', label: t('exercises.editor.start_over'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn enforce-top-margin', icon: 'fa fa-download', id: 'download', label: t('exercises.editor.download'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn', data: {:'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(@exercise)}, icon: 'fa fa-history', id: 'start-over', label: t('exercises.editor.start_over'))
|
||||
|
||||
//- if !@course_token.blank?
|
||||
.input-group.enforce-top-margin
|
||||
|
@ -11,5 +11,5 @@
|
||||
- else
|
||||
= link_to(file.native_file.file.name_with_extension, file.native_file.url)
|
||||
- else
|
||||
.editor-content.hidden data-file-id=file.ancestor_id = file.content
|
||||
.editor-content.d-none data-file-id=file.ancestor_id = file.content
|
||||
.editor data-file-id=file.ancestor_id data-indent-size=file.file_type.indent_size data-mode=file.file_type.editor_mode data-read-only=file.read_only data-allow-auto-completion=exercise.allow_auto_completion.to_s data-id=file.id
|
@ -1,19 +1,21 @@
|
||||
div id='output_sidebar_collapsed'
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'left'}, title: t('exercises.editor.expand_output_sidebar'), icon: 'fa fa-plus-square', id: 'toggle-sidebar-output-collapsed', label: '')
|
||||
div id='output_sidebar_uncollapsed' class='hidden col-sm-12 enforce-bottom-margin' data-message-no-output=t('exercises.implement.no_output')
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'left'}, title: t('exercises.editor.expand_output_sidebar'), icon: 'fa fa-plus-square', id: 'toggle-sidebar-output-collapsed', label: '')
|
||||
div.h-100 id='output_sidebar_uncollapsed' class='d-none col-sm-12 enforce-bottom-margin' data-message-no-output=t('exercises.implement.no_output')
|
||||
.row
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', icon: 'fa fa-minus-square', id: 'toggle-sidebar-output', label: t('exercises.editor.collapse_output_sidebar'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn', icon: 'fa fa-minus-square', id: 'toggle-sidebar-output', label: t('exercises.editor.collapse_output_sidebar'))
|
||||
|
||||
div.enforce-big-top-margin.hidden id='score_div'
|
||||
div.position-absolute.d-flex.mb-1.w-100 style="overflow: scroll; left: 0; bottom: 0; height: calc(100% - 3rem);"
|
||||
div.w-100
|
||||
div.enforce-big-top-margin.d-none id='score_div'
|
||||
#results
|
||||
h2 = t('exercises.implement.results')
|
||||
p.test-count == t('exercises.implement.test_count', count: 0)
|
||||
ul.list-unstyled
|
||||
ul#dummies.hidden.list-unstyled
|
||||
li.panel.panel-default
|
||||
.panel-heading
|
||||
h3.panel-title == t('exercises.implement.file', filename: '', number: 0)
|
||||
.panel-body
|
||||
ul#dummies.d-none.list-unstyled
|
||||
li.card.mt-2
|
||||
.card-header
|
||||
h3.card-title.m-0 == t('exercises.implement.file', filename: '', number: 0)
|
||||
.card-body.bg-white.text-dark
|
||||
= row(label: 'exercises.implement.passed_tests', value: t('shared.out_of', maximum_value: 0, value: 0).html_safe)
|
||||
= row(label: 'activerecord.attributes.submission.score', value: t('shared.out_of', maximum_value: 0, value: 0).html_safe)
|
||||
= row(label: 'exercises.implement.feedback')
|
||||
@ -30,29 +32,30 @@ div id='output_sidebar_uncollapsed' class='hidden col-sm-12 enforce-bottom-margi
|
||||
- if lti_outcome_service?(@exercise.id, external_user_id, consumer_id)
|
||||
p.text-center = render('editor_button', classes: 'btn-lg btn-success', data: {:'data-url' => submit_exercise_path(@exercise)}, icon: 'fa fa-send', id: 'submit', label: t('exercises.editor.submit'))
|
||||
- else
|
||||
p.text-center = render('editor_button', classes: 'btn-lg btn-warning-outline', data: {:'data-placement' => 'bottom', :'data-tooltip' => true}, icon: 'fa fa-clock-o', id: 'submit_outdated', label: t('exercises.editor.exercise_deadline_passed'), title: t('exercises.editor.tooltips.exercise_deadline_passed'))
|
||||
p.text-center = render('editor_button', classes: 'btn-lg btn-outline-warning disabled', data: {:'data-placement' => 'bottom', :'data-tooltip' => true}, icon: 'fa fa-clock-o', id: 'submit_outdated', label: t('exercises.editor.exercise_deadline_passed'), title: t('exercises.editor.tooltips.exercise_deadline_passed'))
|
||||
hr
|
||||
|
||||
div.enforce-big-top-margin
|
||||
#turtlediv
|
||||
canvas#turtlecanvas.hidden width=400 height=400
|
||||
canvas#turtlecanvas.d-none width=400 height=400
|
||||
div.enforce-big-top-margin
|
||||
#hint
|
||||
.panel.panel-warning
|
||||
.panel-heading = t('exercises.implement.hint')
|
||||
.panel-body
|
||||
.card.bg-warning
|
||||
.card-header = t('exercises.implement.hint')
|
||||
.card-body
|
||||
div.enforce-big-top-margin
|
||||
#prompt.input-group.hidden
|
||||
span.input-group-addon data-prompt=t('exercises.editor.input') = t('exercises.editor.input')
|
||||
#prompt.input-group.d-none
|
||||
div.input-group-prepend
|
||||
span.input-group-text data-prompt=t('exercises.editor.input') = t('exercises.editor.input')
|
||||
input#prompt-input.form-control type='text'
|
||||
span.input-group-btn
|
||||
button#prompt-submit.btn.btn-primary type="button" = t('exercises.editor.send')
|
||||
#error-hints
|
||||
.heading = t('exercises.implement.error_hints.heading')
|
||||
ul.body
|
||||
#output
|
||||
#output.mt-2
|
||||
pre = t('exercises.implement.no_output_yet')
|
||||
- if CodeOcean::Config.new(:code_ocean).read[:flowr][:enabled]
|
||||
#flowrHint.panel.panel-info data-url=CodeOcean::Config.new(:code_ocean).read[:flowr][:url] role='tab'
|
||||
.panel-heading = 'Gain more insights here'
|
||||
.panel-body
|
||||
#flowrHint.card.card.text-white.bg-info data-url=CodeOcean::Config.new(:code_ocean).read[:flowr][:url] role='tab'
|
||||
.card-header = 'Gain more insights here'
|
||||
.card-body
|
||||
|
@ -1,41 +1,42 @@
|
||||
- id = f.object.id
|
||||
|
||||
li.panel.panel-default
|
||||
.panel-heading role="tab" id="heading"
|
||||
a.file-heading data-toggle="collapse" href="#collapse#{id}"
|
||||
li.card.mt-2
|
||||
.card-header role="tab" id="heading"
|
||||
a.file-heading.collapsed data-toggle="collapse" href="#collapse#{id}"
|
||||
div.clearfix role="button"
|
||||
i class="fa" aria-hidden="true"
|
||||
span = f.object.name
|
||||
.panel-collapse.collapse class=('in' if f.object.name.nil?) id="collapse#{id}" role="tabpanel"
|
||||
.panel-body
|
||||
.card-collapse.collapse class=('in' if f.object.name.nil?) id="collapse#{id}" role="tabpanel"
|
||||
.card-body
|
||||
- if policy(f.object).destroy?
|
||||
.clearfix
|
||||
.btn.btn-warning.btn-sm.pull-right.delete-file data-file-url=code_ocean_file_path(id) = t('shared.destroy')
|
||||
.btn.btn-warning.btn-sm.float-right.delete-file data-file-url=code_ocean_file_path(id) = t('shared.destroy')
|
||||
.form-group
|
||||
= f.label(:name, t('activerecord.attributes.file.name'))
|
||||
= f.text_field(:name, class: 'form-control')
|
||||
.form-group
|
||||
= f.label(:path, t('activerecord.attributes.file.path'))
|
||||
= f.text_field(:path, class: 'form-control')
|
||||
.help-block = t('.hints.path')
|
||||
.help-block.form-text = t('.hints.path')
|
||||
.form-group
|
||||
= f.label(:file_type_id, t('activerecord.attributes.file.file_type_id'))
|
||||
= f.collection_select(:file_type_id, @file_types, :id, :name, {}, class: 'form-control')
|
||||
.form-group
|
||||
= f.label(:role, t('activerecord.attributes.file.role'))
|
||||
= f.select(:role, CodeOcean::File::TEACHER_DEFINED_ROLES.map { |role| [t("files.roles.#{role}"), role] }, {include_blank: true}, class: 'form-control')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:hidden)
|
||||
.form-check
|
||||
label.form-check-label
|
||||
= f.check_box(:hidden, class: 'form-check-input')
|
||||
= t('activerecord.attributes.file.hidden')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:read_only)
|
||||
.form-check.mb-3
|
||||
label.form-check-label
|
||||
= f.check_box(:read_only, class: 'form-check-input')
|
||||
= t('activerecord.attributes.file.read_only')
|
||||
.test-related-fields style="display: #{f.object.teacher_defined_test? ? 'initial' : 'none'};"
|
||||
.form-group
|
||||
= f.label(:name, t('activerecord.attributes.file.feedback_message'))
|
||||
= f.text_area(:feedback_message, class: 'form-control', maxlength: 255)
|
||||
.help-block = t('.hints.feedback_message')
|
||||
.help-block.form-text = t('.hints.feedback_message')
|
||||
.form-group
|
||||
= f.label(:role, t('activerecord.attributes.file.weight'))
|
||||
= f.number_field(:weight, class: 'form-control', min: 1, step: 'any')
|
||||
|
@ -1,14 +1,14 @@
|
||||
- execution_environments = ExecutionEnvironment.where('file_type_id IS NOT NULL').select(:file_type_id, :id)
|
||||
- file_types = FileType.where('file_extension IS NOT NULL').select(:file_extension, :id)
|
||||
|
||||
= form_for(@exercise, data: {execution_environments: execution_environments, file_types: file_types}, multipart: true) do |f|
|
||||
= form_for(@exercise, data: {execution_environments: execution_environments, file_types: file_types}, multipart: true, builder: PagedownFormBuilder) do |f|
|
||||
= render('shared/form_errors', object: @exercise)
|
||||
.form-group
|
||||
= f.label(:title)
|
||||
= f.text_field(:title, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= f.label(:description)
|
||||
= f.pagedown_editor :description
|
||||
= f.pagedown :description, input_html: { preview: true, rows: 10 }
|
||||
.form-group
|
||||
= f.label(:execution_environment_id)
|
||||
= f.collection_select(:execution_environment_id, @execution_environments, :id, :name, {}, class: 'form-control')
|
||||
@ -16,34 +16,34 @@
|
||||
= f.label(:instructions)
|
||||
= f.hidden_field(:instructions)
|
||||
.form-control.markdown
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:public)
|
||||
.form-check
|
||||
label.form-check-label
|
||||
= f.check_box(:public, class: 'form-check-input')
|
||||
= t('activerecord.attributes.exercise.public')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:hide_file_tree)
|
||||
.form-check
|
||||
label.form-check-label
|
||||
= f.check_box(:hide_file_tree, class: 'form-check-input')
|
||||
= t('activerecord.attributes.exercise.hide_file_tree')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:allow_file_creation)
|
||||
.form-check
|
||||
label.form-check-label
|
||||
= f.check_box(:allow_file_creation, class: 'form-check-input')
|
||||
= t('activerecord.attributes.exercise.allow_file_creation')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:allow_auto_completion)
|
||||
.form-check.mb-3
|
||||
label.form-check-label
|
||||
= f.check_box(:allow_auto_completion, class: 'form-check-input')
|
||||
= t('activerecord.attributes.exercise.allow_auto_completion')
|
||||
.form-group
|
||||
= f.label(t('activerecord.attributes.exercise.difficulty'))
|
||||
= f.number_field :expected_difficulty, in: 1..10, step: 1
|
||||
= f.number_field :expected_difficulty, in: 1..10, step: 1, class: 'form-control'
|
||||
|
||||
h2 = t('exercises.form.tags')
|
||||
ul.list-unstyled.panel-group
|
||||
li.panel.panel-default
|
||||
.panel-heading role="tab" id="heading"
|
||||
ul.list-unstyled.card-group
|
||||
li.card
|
||||
.card-header role="tab" id="heading"
|
||||
a.file-heading data-toggle="collapse" href="#tag-collapse"
|
||||
div.clearfix role="button"
|
||||
span = t('exercises.form.click_to_collapse')
|
||||
.panel-collapse.collapse id="tag-collapse" role="tabpanel"
|
||||
.card-collapse.collapse id="tag-collapse" role="tabpanel"
|
||||
.table-responsive
|
||||
table.table#tags-table
|
||||
thead
|
||||
@ -55,15 +55,15 @@
|
||||
tr
|
||||
td = b.check_box
|
||||
td = b.object.tag.name
|
||||
td = number_field "tag_factors[#{b.object.tag.id}]", :factor, :value => b.object.factor, in: 1..10, step: 1
|
||||
td = number_field "tag_factors[#{b.object.tag.id}]", :factor, :value => b.object.factor, in: 1..10, step: 1, class: 'form-control-sm'
|
||||
|
||||
h2 = t('activerecord.attributes.exercise.files')
|
||||
ul#files.list-unstyled.panel-group
|
||||
ul#files.list-unstyled
|
||||
= f.fields_for :files do |files_form|
|
||||
= render('file_form', f: files_form)
|
||||
|
||||
a#add-file.btn.btn-default.btn-sm.pull-right href='#' = t('.add_file')
|
||||
ul#dummies.hidden = f.fields_for(:files, CodeOcean::File.new, child_index: 'index') do |files_form|
|
||||
a#add-file.btn.btn-secondary.btn-sm.float-right href='#' = t('.add_file')
|
||||
ul#dummies.d-none = f.fields_for(:files, CodeOcean::File.new, child_index: 'index') do |files_form|
|
||||
= render('file_form', f: files_form)
|
||||
|
||||
.actions = render('shared/submit_button', f: f, object: @exercise)
|
@ -2,7 +2,7 @@ h5#rfc_intervention_text style='display: none;' = t('exercises.implement.rfc_int
|
||||
h5 = t('exercises.implement.comment.question')
|
||||
|
||||
|
||||
textarea.form-control#question(style='resize:none;')
|
||||
textarea.form-control.flex-grow-1#question(style='resize:none;')
|
||||
p = ''
|
||||
/ data-cause='requestComments' is not used here right now, we pass the button #requestComments (not askForCommentsButton) as initiator of the action.
|
||||
/ But if we use this button, it will work since the correct cause is supplied
|
||||
|
@ -10,21 +10,21 @@ h1 = "#{@exercise} (external user #{@external_user})"
|
||||
- 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) data-file-types=ActiveSupport::JSON.encode(file_types)
|
||||
.d-none#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
|
||||
- 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
|
||||
.files class=(@exercise.hide_file_tree ? 'd-none 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
|
||||
|
||||
.flex-container
|
||||
button.btn.btn-default id='play-button'
|
||||
button.btn.btn-secondary id='play-button'
|
||||
span.fa.fa-play
|
||||
#submissions-slider.flex-item
|
||||
input type='range' orient='horizontal' list='datapoints' min=0 max=@submissions.length-1 value=0
|
||||
input type='range' orient='horizontal' list='datapoints' min=0 max=@submissions.length-1 value=0 style="width: 100%"
|
||||
datalist#datapoints
|
||||
- index=0
|
||||
- @submissions.each do |submission|
|
||||
@ -59,7 +59,7 @@ h1 = "#{@exercise} (external user #{@external_user})"
|
||||
td =
|
||||
td = @working_times_until[index] if index > 0
|
||||
p = t('.addendum')
|
||||
.hidden#wtimes data-working_times=ActiveSupport::JSON.encode(@working_times_until);
|
||||
.d-none#wtimes data-working_times=ActiveSupport::JSON.encode(@working_times_until);
|
||||
div#progress_chart.col-lg-12
|
||||
.graph-functions-2
|
||||
|
||||
|
@ -8,17 +8,17 @@ h1 = link_to(@exercise, exercise_path(@exercise))
|
||||
- if @feedbacks.nil? or @feedbacks.size == 0
|
||||
.no-feedback = t('user_exercise_feedback.no_feedback')
|
||||
|
||||
ul.list-unstyled.panel-group
|
||||
ul.list-unstyled
|
||||
- @feedbacks.each do |feedback|
|
||||
li.panel.panel-default
|
||||
.panel-heading role="tab" id="heading"
|
||||
li.card.mt-2
|
||||
.card-header role="tab" id="heading"
|
||||
div.clearfix.feedback-header
|
||||
span.username = link_to(feedback.user.name, statistics_external_user_exercise_path(id: @exercise.id, external_user_id: feedback.user.id))
|
||||
- if feedback.anomaly_notification
|
||||
i class="fa fa-envelope-o" data-placement="top" data-toggle="tooltip" data-container="body" title=feedback.anomaly_notification.reason
|
||||
span.date = feedback.created_at
|
||||
.panel-collapse role="tabpanel"
|
||||
.panel-body.feedback
|
||||
.card-collapse role="tabpanel"
|
||||
.card-body.feedback
|
||||
.text = feedback.feedback_text
|
||||
.difficulty = "#{t('user_exercise_feedback.difficulty')} #{feedback.difficulty}" if feedback.difficulty
|
||||
.worktime = "#{t('user_exercise_feedback.working_time')} #{feedback.user_estimated_worktime}" if feedback.user_estimated_worktime
|
||||
|
@ -2,13 +2,13 @@
|
||||
#editor-column.col-md-12
|
||||
.exercise.clearfix
|
||||
div
|
||||
span.badge.pull-right.score
|
||||
span.badge.badge-pill.float-right.score
|
||||
|
||||
h1 id="exercise-headline"
|
||||
i class="fa fa-chevron-down" id="description-symbol"
|
||||
= @exercise.title
|
||||
|
||||
#description-panel.lead.description-panel
|
||||
#description-card.lead.description-card
|
||||
= render_markdown(@exercise.description)
|
||||
|
||||
a#toggle href="#" data-show=t('shared.show') data-hide=t('shared.hide') = t('shared.hide')
|
||||
|
@ -9,45 +9,43 @@ h1 = Exercise.model_name.human(count: 2)
|
||||
= f.search_field(:title_cont, class: 'form-control', placeholder: t('activerecord.attributes.exercise.title'))
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
table.table.mt-4
|
||||
thead
|
||||
tr
|
||||
th = sort_link(@search, :title, t('activerecord.attributes.exercise.title'))
|
||||
th = sort_link(@search, :execution_environment_id, t('activerecord.attributes.exercise.execution_environment'))
|
||||
th = t('.test_files')
|
||||
th = t('activerecord.attributes.exercise.maximum_score')
|
||||
th = t('activerecord.attributes.exercise.tags')
|
||||
th = t('activerecord.attributes.exercise.difficulty')
|
||||
th
|
||||
th.p-1 = sort_link(@search, :title, t('activerecord.attributes.exercise.title'))
|
||||
th.p-1 = sort_link(@search, :execution_environment_id, t('activerecord.attributes.exercise.execution_environment'))
|
||||
th.p-1 = t('.test_files')
|
||||
th.p-1 = t('activerecord.attributes.exercise.maximum_score')
|
||||
th.p-1 = t('activerecord.attributes.exercise.tags')
|
||||
th.p-1 = t('activerecord.attributes.exercise.difficulty')
|
||||
th.p-1
|
||||
= t('activerecord.attributes.exercise.public')
|
||||
- if policy(Exercise).batch_update?
|
||||
br
|
||||
span.batch = link_to(t('shared.batch_update'), '#', 'data-text' => t('shared.update', model: t('activerecord.models.exercise.other')))
|
||||
th colspan=6 = t('shared.actions')
|
||||
th.p-1 colspan=6 = t('shared.actions')
|
||||
tbody
|
||||
- @exercises.each do |exercise|
|
||||
tr data-id=exercise.id
|
||||
td = exercise.title
|
||||
td = link_to_if(exercise.execution_environment && policy(exercise.execution_environment).show?, exercise.execution_environment, exercise.execution_environment)
|
||||
td = exercise.files.teacher_defined_tests.count
|
||||
td = exercise.maximum_score
|
||||
td = exercise.exercise_tags.count
|
||||
td = exercise.expected_difficulty
|
||||
td.public data-value=exercise.public? = symbol_for(exercise.public?)
|
||||
td = link_to(t('shared.edit'), edit_exercise_path(exercise)) if policy(exercise).edit?
|
||||
td = link_to(t('.implement'), implement_exercise_path(exercise)) if policy(exercise).implement?
|
||||
td = link_to(t('shared.statistics'), statistics_exercise_path(exercise), 'data-turbolinks' => "false") if policy(exercise).statistics?
|
||||
td.p-1.pt-2 = link_to(exercise.title, exercise, 'data-turbolinks' => "false") if policy(exercise).show?
|
||||
td.p-1.pt-2 = link_to_if(exercise.execution_environment && policy(exercise.execution_environment).show?, exercise.execution_environment, exercise.execution_environment)
|
||||
td.p-1.pt-2 = exercise.files.teacher_defined_tests.count
|
||||
td.p-1.pt-2 = exercise.maximum_score
|
||||
td.p-1.pt-2 = exercise.exercise_tags.count
|
||||
td.p-1.pt-2 = exercise.expected_difficulty
|
||||
td.p-1.pt-2.public data-value=exercise.public? = symbol_for(exercise.public?)
|
||||
td.p-1.pt-2 = link_to(t('shared.edit'), edit_exercise_path(exercise)) if policy(exercise).edit?
|
||||
td.p-1.pt-2 = link_to(t('.implement'), implement_exercise_path(exercise)) if policy(exercise).implement?
|
||||
td.p-1.pt-2 = link_to(t('shared.statistics'), statistics_exercise_path(exercise), 'data-turbolinks' => "false") if policy(exercise).statistics?
|
||||
|
||||
td
|
||||
td.p-1
|
||||
.btn-group
|
||||
button.btn.btn-primary-outline.btn-xs.dropdown-toggle data-toggle="dropdown" type="button" = t('shared.actions_button')
|
||||
span.caret
|
||||
span.sr-only Toggle Dropdown
|
||||
ul.dropdown-menu.pull-right role="menu"
|
||||
li = link_to(t('shared.show'), exercise, 'data-turbolinks' => "false") if policy(exercise).show?
|
||||
li = link_to(t('activerecord.models.user_exercise_feedback.other'), feedback_exercise_path(exercise)) if policy(exercise).feedback?
|
||||
li = link_to(t('shared.destroy'), exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete) if policy(exercise).destroy?
|
||||
li = link_to(t('.clone'), clone_exercise_path(exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post) if policy(exercise).clone?
|
||||
button.btn.btn-outline-primary.btn-sm.dropdown-toggle data-toggle="dropdown" type="button" = t('shared.actions_button')
|
||||
ul.dropdown-menu.float-right role="menu"
|
||||
li = link_to(t('shared.show'), exercise, 'data-turbolinks' => "false", class: 'dropdown-item') if policy(exercise).show?
|
||||
li = link_to(t('activerecord.models.user_exercise_feedback.other'), feedback_exercise_path(exercise), class: 'dropdown-item') if policy(exercise).feedback?
|
||||
li = link_to(t('shared.destroy'), exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete, class: 'dropdown-item') if policy(exercise).destroy?
|
||||
li = link_to(t('.clone'), clone_exercise_path(exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post, class: 'dropdown-item') if policy(exercise).clone?
|
||||
|
||||
= render('shared/pagination', collection: @exercises)
|
||||
p = render('shared/new_button', model: Exercise)
|
||||
|
@ -12,7 +12,7 @@ h1
|
||||
|
||||
= row(label: 'exercise.title', value: @exercise.title)
|
||||
= row(label: 'exercise.user', value: link_to_if(policy(@exercise.author).show?, @exercise.author, @exercise.author))
|
||||
= row(label: 'exercise.description', value: render_markdown(@exercise.description))
|
||||
= row(label: 'exercise.description', value: render_markdown(@exercise.description), class: 'm-0')
|
||||
= row(label: 'exercise.execution_environment', value: link_to_if(policy(@exercise.execution_environment).show?, @exercise.execution_environment, @exercise.execution_environment))
|
||||
/= row(label: 'exercise.instructions', value: render_markdown(@exercise.instructions))
|
||||
= row(label: 'exercise.maximum_score', value: @exercise.maximum_score)
|
||||
@ -20,24 +20,23 @@ h1
|
||||
= row(label: 'exercise.hide_file_tree', value: @exercise.hide_file_tree?)
|
||||
= row(label: 'exercise.allow_file_creation', value: @exercise.allow_file_creation?)
|
||||
= row(label: 'exercise.allow_auto_completion', value: @exercise.allow_auto_completion?)
|
||||
= row(label: 'exercise.embedding_parameters') do
|
||||
= content_tag(:input, nil, class: 'form-control', readonly: true, value: embedding_parameters(@exercise))
|
||||
= row(label: 'exercise.difficulty', value: @exercise.expected_difficulty)
|
||||
= row(label: 'exercise.tags', value: @exercise.exercise_tags.map{|et| "#{et.tag.name} (#{et.factor})"}.sort.join(", "))
|
||||
= row(label: 'exercise.embedding_parameters', class: 'mb-4') do
|
||||
= content_tag(:input, nil, class: 'form-control mb-4', readonly: true, value: embedding_parameters(@exercise))
|
||||
|
||||
h2 = t('activerecord.attributes.exercise.files')
|
||||
h2.mt-4 = t('activerecord.attributes.exercise.files')
|
||||
|
||||
ul.list-unstyled.panel-group#files
|
||||
ul.list-unstyled#files
|
||||
- @exercise.files.each do |file|
|
||||
li.panel.panel-default
|
||||
.panel-heading role="tab" id="heading"
|
||||
a.file-heading data-toggle="collapse" data-parent="#files" href=".collapse#{file.id}"
|
||||
li.card.mt-2
|
||||
.card-header role="tab" id="heading"
|
||||
a.file-heading.collapsed data-toggle="collapse" data-parent="#files" href=".collapse#{file.id}"
|
||||
div.clearfix role="button"
|
||||
i class="fa" aria-hidden="true"
|
||||
span = file.name_with_extension
|
||||
// probably set an icon here that shows that the rows can be collapsed
|
||||
//span.pull-right.collapse.in class="collapse#{file.id}" ☼
|
||||
.panel-collapse.collapse class="collapse#{file.id}" role="tabpanel"
|
||||
.panel-body
|
||||
.card-collapse.collapse class="collapse#{file.id}" role="tabpanel"
|
||||
.card-body
|
||||
- if policy(file).destroy?
|
||||
.clearfix = link_to(t('shared.destroy'), file, class:'btn btn-warning btn-sm pull-right', data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
.clearfix = link_to(t('shared.destroy'), file, class:'btn btn-warning btn-sm float-right', data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
= render('shared/file', file: file)
|
||||
|
@ -32,7 +32,7 @@ h1 = @exercise
|
||||
-working_time = @exercise.average_working_time_for(user.id) or 0
|
||||
-working_time_array.push working_time
|
||||
hr
|
||||
.hidden#data data-working-time=ActiveSupport::JSON.encode(working_time_array)
|
||||
.d-none#data data-working-time=ActiveSupport::JSON.encode(working_time_array)
|
||||
.graph-functions
|
||||
div#chart_1
|
||||
hr
|
||||
|
@ -4,9 +4,9 @@ h1 = @user.name
|
||||
//= row(label: 'external_user.email', value: @user.email)
|
||||
= row(label: 'external_user.consumer', value: link_to(@user.consumer, @user.consumer))
|
||||
|
||||
h4 = link_to(t('.exercise_statistics'), statistics_external_user_path(@user))
|
||||
h4.mt-4 = link_to(t('.exercise_statistics'), statistics_external_user_path(@user))
|
||||
|
||||
h4 = t('.tag_statistics')
|
||||
h4.mt-4 = t('.tag_statistics')
|
||||
#loading
|
||||
.spinner
|
||||
= t('.loading_tag_statistics')
|
||||
|
@ -10,7 +10,7 @@ h1 = FileTemplate.model_name.human(count: 2)
|
||||
tbody
|
||||
- @file_templates.each do |file_template|
|
||||
tr
|
||||
td = file_template.name
|
||||
td = link_to(file_template.name, file_template)
|
||||
td = link_to(file_template.file_type, file_type_path(file_template.file_type))
|
||||
td = link_to(t('shared.show'), file_template)
|
||||
td = link_to(t('shared.edit'), edit_file_template_path(file_template))
|
||||
|
@ -12,16 +12,16 @@
|
||||
.form-group
|
||||
= f.label(:indent_size)
|
||||
= f.number_field(:indent_size, class: 'form-control', placeholder: 2, required: true)
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:binary)
|
||||
.form-check
|
||||
label.form-check-label
|
||||
= f.check_box(:binary, class: 'form-check-input')
|
||||
= t('activerecord.attributes.file_type.binary')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:executable)
|
||||
.form-check
|
||||
label.form-check-label
|
||||
= f.check_box(:executable, class: 'form-check-input')
|
||||
= t('activerecord.attributes.file_type.executable')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:renderable)
|
||||
.form-check.mb-3
|
||||
label.form-check-label
|
||||
= f.check_box(:renderable, class: 'form-check-input')
|
||||
= t('activerecord.attributes.file_type.renderable')
|
||||
.actions = render('shared/submit_button', f: f, object: @file_type)
|
||||
|
@ -11,7 +11,7 @@ h1 = FileType.model_name.human(count: 2)
|
||||
tbody
|
||||
- @file_types.each do |file_type|
|
||||
tr
|
||||
td = file_type.name
|
||||
td = link_to(file_type.name, file_type)
|
||||
td = link_to(file_type.author, file_type.author)
|
||||
td = file_type.file_extension
|
||||
td = link_to(t('shared.show'), file_type)
|
||||
|
1
app/views/file_types/show.json.jbuilder
Normal file
1
app/views/file_types/show.json.jbuilder
Normal file
@ -0,0 +1 @@
|
||||
json.extract! @file_type, :id, :name, :editor_mode, :file_extension, :executable, :renderable, :binary
|
@ -3,15 +3,15 @@
|
||||
.form-group
|
||||
= f.label(:name)
|
||||
= f.text_field(:name, class: 'form-control', required: true)
|
||||
.form
|
||||
.form-group
|
||||
= f.label(:locale)
|
||||
= f.select(:locale, I18n.available_locales.map { |locale| [t("locales.#{locale}"), locale] }, {}, class: 'form-control')
|
||||
.form-group
|
||||
= f.label(:message)
|
||||
= f.text_field(:message, class: 'form-control', placeholder: "'$2' has no method '$1'.", required: true)
|
||||
.help-block = t('.hints.message')
|
||||
.help-block.form-text = t('.hints.message')
|
||||
.form-group
|
||||
= f.label(:regular_expression)
|
||||
= f.text_field(:regular_expression, class: 'form-control', placeholder: 'undefined method (\w+) for (\w+)', required: true)
|
||||
.help-block = t('.hints.regular_expression')
|
||||
.help-block.form-text = t('.hints.regular_expression')
|
||||
.actions = render('shared/submit_button', f: f, object: @hint)
|
||||
|
@ -5,7 +5,7 @@
|
||||
= f.collection_select(:consumer_id, Consumer.all.sort_by(&:name), :id, :name, {}, class: 'form-control')
|
||||
.form-group
|
||||
= f.label(:email)
|
||||
= f.text_field(:email, class: 'form-control', required: true)
|
||||
= f.email_field(:email, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= f.label(:name)
|
||||
= f.text_field(:name, class: 'form-control', required: true)
|
||||
|
@ -9,4 +9,4 @@ h1 = t('.headline')
|
||||
= f.label(:password_confirmation)
|
||||
= f.password_field(:password_confirmation, class: 'form-control', required: true)
|
||||
= f.hidden_field(:activation_token)
|
||||
.actions = submit_tag(t('.submit'), class: 'btn btn-default')
|
||||
.actions = submit_tag(t('.submit'), class: 'btn btn-primary')
|
||||
|
@ -3,5 +3,5 @@ h1 = t('.headline')
|
||||
= form_tag do
|
||||
.form-group
|
||||
= label_tag(:email, t('activerecord.attributes.internal_user.email'))
|
||||
= text_field_tag(:email, params[:email], autofocus: true, class: 'form-control', required: true)
|
||||
.actions = submit_tag(t('.submit'), class: 'btn btn-default')
|
||||
= email_field_tag(:email, params[:email], autofocus: true, class: 'form-control', required: true)
|
||||
.actions = submit_tag(t('.submit'), class: 'btn btn-primary')
|
||||
|
@ -12,7 +12,7 @@ h1 = InternalUser.model_name.human(count: 2)
|
||||
= f.select(:role_eq, User::ROLES.map { |role| [t("users.roles.#{role}"), role] }, {}, class: 'form-control', prompt: t('activerecord.attributes.internal_user.role'))
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
table.table.mt-4
|
||||
thead
|
||||
tr
|
||||
th = t('activerecord.attributes.internal_user.name')
|
||||
|
@ -9,4 +9,4 @@ h1 = t('.headline')
|
||||
= f.label(:password_confirmation)
|
||||
= f.password_field(:password_confirmation, class: 'form-control', required: true)
|
||||
= f.hidden_field(:reset_password_token)
|
||||
.actions = submit_tag(t('.submit'), class: 'btn btn-default')
|
||||
.actions = submit_tag(t('.submit'), class: 'btn btn-primary')
|
||||
|
@ -13,22 +13,18 @@ html lang='en'
|
||||
= yield(:head)
|
||||
= csrf_meta_tags
|
||||
body
|
||||
nav.navbar.navbar-default role='navigation'
|
||||
nav.navbar.navbar-dark.bg-dark.navbar-expand-md.mb-4 role='navigation'
|
||||
.container
|
||||
.navbar-header
|
||||
button.navbar-toggle data-target='#navbar-collapse' data-toggle='collapse' type='button'
|
||||
span.sr-only Toggle navigation
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
button.navbar-toggler data-target='#navbar-collapse' data-toggle='collapse' type='button' aria-expanded='false' aria-label='Toggle navigation'
|
||||
span.navbar-toggler-icon.sr-only
|
||||
.navbar-brand
|
||||
i.fa.fa-code
|
||||
= application_name
|
||||
#navbar-collapse.collapse.navbar-collapse
|
||||
= render('navigation', cached: true)
|
||||
ul.nav.navbar-nav.navbar-right
|
||||
ul.nav.navbar-nav.ml-auto
|
||||
= render('locale_selector', cached: true)
|
||||
li = link_to(t('shared.help.link'), '#modal-help', data: {toggle: 'modal'})
|
||||
li.nav-item.mr-3 = link_to(t('shared.help.link'), '#modal-help', data: {toggle: 'modal'}, class: 'nav-link')
|
||||
= render('session')
|
||||
.container data-controller=controller_name
|
||||
= render('flash')
|
||||
|
@ -1,11 +1,11 @@
|
||||
= form_for(@proxy_exercise, multipart: true) do |f|
|
||||
= form_for(@proxy_exercise, multipart: true, builder: PagedownFormBuilder) do |f|
|
||||
= render('shared/form_errors', object: @proxy_exercise)
|
||||
.form-group
|
||||
= f.label(:title)
|
||||
= f.text_field(:title, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= f.label(:description)
|
||||
= f.pagedown_editor :description
|
||||
= f.pagedown :description, input_html: { preview: true, rows: 10 }
|
||||
|
||||
h3 Exercises
|
||||
.table-responsive
|
||||
|
@ -6,30 +6,30 @@ h1 = ProxyExercise.model_name.human(count: 2)
|
||||
= f.search_field(:title_cont, class: 'form-control', placeholder: t('activerecord.attributes.proxy_exercise.title'))
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
table.table.mt-4
|
||||
thead
|
||||
tr
|
||||
th = sort_link(@search, :title, t('activerecord.attributes.proxy_exercise.title'))
|
||||
th = t('activerecord.attributes.exercise.token')
|
||||
th = t('activerecord.attributes.proxy_exercise.files_count')
|
||||
th colspan=6 = t('shared.actions')
|
||||
th.p-1 = sort_link(@search, :title, t('activerecord.attributes.proxy_exercise.title'))
|
||||
th.p-1 = t('activerecord.attributes.exercise.token')
|
||||
th.p-1 = t('activerecord.attributes.proxy_exercise.files_count')
|
||||
th.p-1 colspan=6 = t('shared.actions')
|
||||
tbody
|
||||
- @proxy_exercises.each do |proxy_exercise|
|
||||
tr data-id=proxy_exercise.id
|
||||
td = link_to(proxy_exercise.title,proxy_exercise)
|
||||
td = proxy_exercise.token
|
||||
td = proxy_exercise.count_files
|
||||
td = link_to(t('shared.edit'), edit_proxy_exercise_path(proxy_exercise)) if policy(proxy_exercise).edit?
|
||||
td.p-1.pt-2 = link_to(proxy_exercise.title,proxy_exercise)
|
||||
td.p-1.pt-2 = proxy_exercise.token
|
||||
td.p-1.pt-2 = proxy_exercise.count_files
|
||||
td.p-1.pt-2 = link_to(t('shared.edit'), edit_proxy_exercise_path(proxy_exercise)) if policy(proxy_exercise).edit?
|
||||
|
||||
td
|
||||
td.p-1
|
||||
.btn-group
|
||||
button.btn.btn-primary-outline.btn-xs.dropdown-toggle data-toggle="dropdown" type="button" = t('shared.actions_button')
|
||||
button.btn.btn-outline-primary.btn-sm.dropdown-toggle data-toggle="dropdown" type="button" = t('shared.actions_button')
|
||||
span.caret
|
||||
span.sr-only Toggle Dropdown
|
||||
ul.dropdown-menu.pull-right role="menu"
|
||||
li = link_to(t('shared.show'), proxy_exercise, 'data-turbolinks' => "false") if policy(proxy_exercise).show?
|
||||
li = link_to(t('shared.destroy'), proxy_exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete) if policy(proxy_exercise).destroy?
|
||||
li = link_to(t('.clone'), clone_proxy_exercise_path(proxy_exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post) if policy(proxy_exercise).clone?
|
||||
ul.dropdown-menu.float-right role="menu"
|
||||
li = link_to(t('shared.show'), proxy_exercise, 'data-turbolinks' => "false", class: 'dropdown-item') if policy(proxy_exercise).show?
|
||||
li = link_to(t('shared.destroy'), proxy_exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete, class: 'dropdown-item') if policy(proxy_exercise).destroy?
|
||||
li = link_to(t('.clone'), clone_proxy_exercise_path(proxy_exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post, class: 'dropdown-item') if policy(proxy_exercise).clone?
|
||||
|
||||
= render('shared/pagination', collection: @proxy_exercises)
|
||||
p = render('shared/new_button', model: ProxyExercise)
|
||||
|
@ -14,7 +14,8 @@ h1
|
||||
= row(label: 'proxy_exercise.files_count', value: @exercises.count)
|
||||
= row(label: 'exercise.description', value: @proxy_exercise.description)
|
||||
= row(label: 'exercise.token', value: @proxy_exercise.token)
|
||||
h3 Exercises
|
||||
|
||||
h2.mt-4 Exercises
|
||||
.table-responsive
|
||||
table.table
|
||||
thead
|
||||
|
@ -1,9 +1,8 @@
|
||||
br
|
||||
h4 Admin Menu
|
||||
h5
|
||||
ul
|
||||
hr
|
||||
h5.mt-4 Admin Menu
|
||||
ul.text
|
||||
li = link_to "User's current status of this exercise", statistics_external_user_exercise_path(id: @request_for_comment.exercise_id, external_user_id: @request_for_comment.user_id)
|
||||
li = link_to "All exercises of this user", statistics_external_user_path(id: @request_for_comment.user_id)
|
||||
ul
|
||||
ul.text
|
||||
li = link_to "Implement the exercise yourself", implement_exercise_path(id: @request_for_comment.exercise_id)
|
||||
li = link_to "Show the exercise", exercise_path(id: @request_for_comment.exercise_id)
|
||||
|
@ -4,4 +4,4 @@ button.btn.btn-primary#mark-as-solved-button = t('request_for_comments.mark_as_s
|
||||
p = t('request_for_comments.write_a_thank_you_node')
|
||||
textarea#thank-you-note
|
||||
button.btn.btn-primary#send-thank-you-note = t('request_for_comments.send_thank_you_note')
|
||||
button.btn.btn-default#cancel-thank-you-note = t('request_for_comments.cancel_thank_you_note')
|
||||
button.btn.btn-secondary#cancel-thank-you-note = t('request_for_comments.cancel_thank_you_note')
|
||||
|
@ -9,7 +9,7 @@ h1 = RequestForComment.model_name.human(count: 2)
|
||||
= f.select(:solved_not_eq, [[t('request_for_comments.show_all'), 2], [t('request_for_comments.show_unsolved'), 1], [t('request_for_comments.show_solved'), 0]])
|
||||
|
||||
.table-responsive
|
||||
table.table.sortable
|
||||
table.table.sortable.mt-4
|
||||
thead
|
||||
tr
|
||||
th
|
||||
@ -39,7 +39,7 @@ h1 = RequestForComment.model_name.human(count: 2)
|
||||
- else
|
||||
td = '-'
|
||||
td = request_for_comment.comments_count
|
||||
td = request_for_comment.user.displayname
|
||||
td = link_to_if(request_for_comment.user && policy(request_for_comment.user).show?, request_for_comment.user.displayname, request_for_comment.user)
|
||||
td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.created_at))
|
||||
td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.last_comment.nil? ? request_for_comment.updated_at : request_for_comment.last_comment))
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
</div>
|
||||
|
||||
<div class="question">
|
||||
<h5>
|
||||
<h5 class="mt-4">
|
||||
<%= t('activerecord.attributes.request_for_comments.question')%>
|
||||
</h5>
|
||||
<div class="text">
|
||||
@ -42,7 +42,7 @@
|
||||
<div class="testruns">
|
||||
<% output_runs = testruns.select { |run| run.cause == 'run' } %>
|
||||
<% if output_runs.size > 0 %>
|
||||
<h5><%= t('request_for_comments.runtime_output') %></h5>
|
||||
<h5 class="mt-4"><%= t('request_for_comments.runtime_output') %></h5>
|
||||
<div class="collapsed testrun-output text">
|
||||
<span class="fa fa-chevron-down collapse-button"></span>
|
||||
<% output_runs.each do |testrun| %>
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
<% assess_runs = testruns.select { |run| run.cause == 'assess' } %>
|
||||
<% if assess_runs.size > 0 %>
|
||||
<h5><%= t('request_for_comments.test_results') %></h5>
|
||||
<h5 class="mt-4"><%= t('request_for_comments.test_results') %></h5>
|
||||
<div class="testrun-assess-results">
|
||||
<% assess_runs.each do |testrun| %>
|
||||
<div class="testrun-container">
|
||||
@ -86,7 +86,7 @@
|
||||
<hr>
|
||||
|
||||
<div class="howto">
|
||||
<h5>
|
||||
<h5 class="mt-4">
|
||||
<%= t('request_for_comments.howto_title') %>
|
||||
</h5>
|
||||
<div class="text">
|
||||
@ -96,7 +96,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden sanitizer"></div>
|
||||
<div class="d-none sanitizer"></div>
|
||||
<!--
|
||||
do not put a carriage return in the line below. it will be present in the presentation of the source code, otherwise.
|
||||
also, all settings from the rails model needed for the editor configuration in the JavaScript are attached to the editor as data attributes here.
|
||||
@ -205,16 +205,16 @@ also, all settings from the rails model needed for the editor configuration in t
|
||||
<div class="comment-header"> \
|
||||
<div class="comment-username">' + preprocess(comment.username) + '</div> \
|
||||
<div class="comment-date">' + comment.date + '</div> \
|
||||
<div class="comment-updated' + (comment.updated ? '' : ' hidden') + '"> \
|
||||
<div class="comment-updated' + (comment.updated ? '' : ' d-none') + '"> \
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> \
|
||||
<%= t('request_for_comments.comment_edited') %> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="comment-content">' + commentText + '</div> \
|
||||
<textarea class="comment-editor">' + commentText + '</textarea> \
|
||||
<div class="comment-actions' + (comment.editable ? '' : ' hidden') + '"> \
|
||||
<button class="action-edit btn btn-xs btn-warning"><%= t('shared.edit') %></button> \
|
||||
<button class="action-delete btn btn-xs btn-danger"><%= t('shared.destroy') %></button> \
|
||||
<div class="comment-actions' + (comment.editable ? '' : ' d-none') + '"> \
|
||||
<button class="action-edit btn btn-sm btn-warning"><%= t('shared.edit') %></button> \
|
||||
<button class="action-delete btn btn-sm btn-danger"><%= t('shared.destroy') %></button> \
|
||||
</div> \
|
||||
</div>';
|
||||
});
|
||||
@ -380,7 +380,7 @@ also, all settings from the rails model needed for the editor configuration in t
|
||||
$(target).popover('show');
|
||||
$(target).on('mouseleave', function () {
|
||||
$(this).off('mouseleave');
|
||||
$(this).popover('destroy');
|
||||
$(this).popover('dispose');
|
||||
});
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ also, all settings from the rails model needed for the editor configuration in t
|
||||
deleteButton.show();
|
||||
commentContent.show();
|
||||
commentEditor.hide();
|
||||
commentUpdated.removeClass('hidden');
|
||||
commentUpdated.removeClass('d-none');
|
||||
});
|
||||
} else {
|
||||
button.text('<%= t('comments.save_update') %>');
|
||||
|
@ -3,13 +3,14 @@ h1 = t('.headline')
|
||||
= form_tag(sessions_path) do
|
||||
.form-group
|
||||
= label_tag(:email, t('activerecord.attributes.internal_user.email'))
|
||||
= text_field_tag(:email, params[:email], autofocus: true, class: 'form-control', required: true)
|
||||
= email_field_tag(:email, params[:email], autofocus: true, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= label_tag(:password, t('activerecord.attributes.internal_user.password'))
|
||||
= password_field_tag(:password, nil, class: 'form-control', required: true)
|
||||
.checkbox
|
||||
label
|
||||
= check_box_tag(:remember_me)
|
||||
.form-check.form-group
|
||||
label.form-check-label
|
||||
// Set values 1 and true/false explicit to allow passing a custom HTML class
|
||||
= check_box_tag(:remember_me, 1, true, class: 'form-check-input')
|
||||
= t('.remember_me')
|
||||
span.pull-right = link_to(t('.forgot_password'), forgot_password_path)
|
||||
.actions = submit_tag(t('.link'), class: 'btn btn-default')
|
||||
span.float-right = link_to(t('.forgot_password'), forgot_password_path)
|
||||
.actions = submit_tag(t('.link'), class: 'btn btn-primary')
|
||||
|
@ -1,3 +1,3 @@
|
||||
// default value for fetch will always be evaluated even if it is not returned
|
||||
- link_target = local_assigns.fetch(:path, false) || send(:"edit_#{object.class.name.underscore}_path", object)
|
||||
= link_to(t('shared.edit'), link_target, class: 'btn btn-default pull-right')
|
||||
= link_to(t('shared.edit'), link_target, class: 'btn btn-secondary float-right')
|
||||
|
@ -5,6 +5,6 @@
|
||||
= row(label: 'file.hidden', value: file.hidden)
|
||||
= row(label: 'file.read_only', value: file.read_only)
|
||||
- if file.teacher_defined_test?
|
||||
= row(label: 'file.feedback_message', value: render_markdown(file.feedback_message))
|
||||
= row(label: 'file.feedback_message', value: render_markdown(file.feedback_message), class: 'm-0')
|
||||
= row(label: 'file.weight', value: file.weight)
|
||||
= row(label: 'file.content', value: file.native_file? ? link_to(file.native_file.file.filename, file.native_file.url) : code_tag(file.content))
|
||||
|
@ -1,11 +1,9 @@
|
||||
.well
|
||||
.card.card-body.bg-light
|
||||
= search_form_for(@search, class: 'clearfix filter-form form-inline') do |f|
|
||||
= yield(f)
|
||||
.btn-group.pull-right
|
||||
button.btn.btn-default.btn-sm type='submit' = t('shared.apply_filters')
|
||||
button.btn.btn-default.btn-sm.dropdown-toggle data-toggle='dropdown' type='button'
|
||||
span.caret
|
||||
span.sr-only Toggle Dropdown
|
||||
.btn-group.ml-auto
|
||||
button.btn.btn-primary type='submit' = t('shared.apply_filters')
|
||||
button.btn.btn-primary.dropdown-toggle data-toggle='dropdown' type='button'
|
||||
ul.dropdown-menu role='menu'
|
||||
li
|
||||
a href=request.path = t('shared.reset_filters')
|
||||
a.dropdown-item href=request.path = t('shared.reset_filters')
|
||||
|
@ -2,10 +2,10 @@
|
||||
.modal-dialog class=local_assigns[:classes]
|
||||
.modal-content
|
||||
.modal-header
|
||||
h4#modal-title.modal-title = title
|
||||
button.close data-dismiss='modal' type='button'
|
||||
span aria-hidden=true ×
|
||||
span.sr-only Close
|
||||
h4#modal-title.modal-title = title
|
||||
.modal-body
|
||||
- if local_assigns.has_key?(:body)
|
||||
= body
|
||||
|
@ -1,3 +1,2 @@
|
||||
- if (pagination = will_paginate(collection, container: false)).present?
|
||||
.text-center
|
||||
ul.pagination = pagination
|
||||
- if (pagination = will_paginate(collection, container: false, renderer: WillPaginate::ActionView::Bootstrap4LinkRenderer)).present?
|
||||
ul.pagination.justify-content-center = pagination
|
||||
|
@ -1 +1 @@
|
||||
= f.submit(class: 'btn btn-default', value: t(object.new_record? ? 'shared.create' : 'shared.update', model: object.class.model_name.human))
|
||||
= f.submit(class: 'btn btn-primary', value: t(object.new_record? ? 'shared.create' : 'shared.update', model: object.class.model_name.human))
|
||||
|
@ -10,11 +10,11 @@
|
||||
h1 = t('.user_activity')
|
||||
a href=statistics_graphs_user_activity_history_path = t('.history')
|
||||
.spinner
|
||||
.graph#user-activity
|
||||
.graph.mb-5#user-activity
|
||||
|
||||
.group
|
||||
.title
|
||||
h1 = t('.rfc_activity')
|
||||
a href=statistics_graphs_rfc_activity_history_path = t('.history')
|
||||
.spinner
|
||||
.graph#rfc-activity
|
||||
.graph.mb-5#rfc-activity
|
||||
|
@ -9,7 +9,7 @@ h1 = Submission.model_name.human(count: 2)
|
||||
= f.select(:cause_eq, Submission.select(:cause).distinct.map(&:cause).sort, class: 'form-control', prompt: t('activerecord.attributes.submission.cause'))
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
table.table.mt-4
|
||||
thead
|
||||
tr
|
||||
th = sort_link(@search, :exercise_id, t('activerecord.attributes.submission.exercise'))
|
||||
|
@ -1,3 +1,10 @@
|
||||
- content_for :head do
|
||||
// Force a full page reload, see https://github.com/turbolinks/turbolinks/issues/326.
|
||||
Otherwise, code might not be highlighted correctly (race condition)
|
||||
meta name='turbolinks-visit-control' content='reload'
|
||||
= javascript_include_tag(asset_path('highlight.min.js', type: :javascript))
|
||||
= stylesheet_link_tag(asset_path('highlight-default.css', type: :stylesheet))
|
||||
|
||||
h1 = @submission
|
||||
|
||||
= row(label: 'submission.exercise', value: link_to(@submission.exercise, @submission.exercise))
|
||||
@ -5,9 +12,9 @@ h1 = @submission
|
||||
= row(label: 'submission.cause', value: t("submissions.causes.#{@submission.cause}"))
|
||||
= row(label: 'submission.score', value: @submission.score)
|
||||
|
||||
h2 = t('activerecord.attributes.submission.files')
|
||||
h2.mt-4 = t('activerecord.attributes.submission.files')
|
||||
|
||||
ul.list-unstyled
|
||||
- @files.each do |file|
|
||||
li.panel.panel-default
|
||||
.panel-body = render('shared/file', file: file)
|
||||
li.card.mt-2
|
||||
.card-body = render('shared/file', file: file)
|
||||
|
@ -4,7 +4,7 @@ h1 = @submission
|
||||
= row(label: 'submission.score', value: @submission.score)
|
||||
= row(label: '.siblings', value: @submission.siblings.count)
|
||||
|
||||
h2 = t('.history')
|
||||
h2.mt-4 = t('.history')
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
|
@ -1,6 +1,6 @@
|
||||
= form_for(@uef) do |f|
|
||||
div
|
||||
span.badge.pull-right.score
|
||||
span.badge.badge-pill.float-right.score
|
||||
|
||||
h1 id="exercise-headline"
|
||||
= t('activerecord.models.user_exercise_feedback.one') + " "
|
||||
@ -8,16 +8,16 @@
|
||||
= render('shared/form_errors', object: @uef)
|
||||
h4
|
||||
== t('user_exercise_feedback.description')
|
||||
#description-panel.lead.description-panel
|
||||
#description-card.lead.description-card
|
||||
u = t('activerecord.attributes.exercise.description')
|
||||
= render_markdown(@exercise.description)
|
||||
.form-group
|
||||
= f.text_area(:feedback_text, class: 'form-control', required: true, :rows => "10")
|
||||
h4 = t('user_exercise_feedback.difficulty')
|
||||
= f.collection_radio_buttons :difficulty, @texts, :first, :last, html_options={class: "radio-inline"} do |b|
|
||||
= b.label(:class => 'radio') { b.radio_button + b.text }
|
||||
= f.collection_radio_buttons :difficulty, @texts, :first, :last, html_options={class: "form-check-inline"} do |b|
|
||||
= b.label(:class => 'form-check') { b.radio_button + b.text }
|
||||
h4 = t('user_exercise_feedback.working_time')
|
||||
= f.collection_radio_buttons :user_estimated_worktime, @times, :first, :last, html_options={class: "radio-inline"} do |b|
|
||||
= b.label(:class => 'radio') { b.radio_button + b.text }
|
||||
= f.collection_radio_buttons :user_estimated_worktime, @times, :first, :last, html_options={class: "form-check-inline"} do |b|
|
||||
= b.label(:class => 'form-check') { b.radio_button + b.text }
|
||||
= f.hidden_field(:exercise_id, :value => @exercise.id)
|
||||
.actions = render('shared/submit_button', f: f, object: @uef)
|
||||
|
Reference in New Issue
Block a user