Merge branch 'master' into john-graph
# Conflicts: # Gemfile
This commit is contained in:
@@ -1,19 +1,17 @@
|
||||
- if current_user
|
||||
- if current_user.internal_user?
|
||||
li.dropdown
|
||||
a.dropdown-toggle data-toggle='dropdown' href='#'
|
||||
i.fa.fa-user
|
||||
= current_user
|
||||
span.caret
|
||||
ul.dropdown-menu role='menu'
|
||||
li.dropdown
|
||||
a.dropdown-toggle data-toggle='dropdown' href='#'
|
||||
i.fa.fa-user
|
||||
= current_user
|
||||
span.caret
|
||||
ul.dropdown-menu 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_comment_requests'), my_request_for_comments_path)
|
||||
- if current_user.internal_user?
|
||||
li = link_to(t('sessions.destroy.link'), sign_out_path, method: :delete)
|
||||
- else
|
||||
li
|
||||
p.navbar-text
|
||||
i.fa.fa-user
|
||||
= current_user
|
||||
- else
|
||||
li = link_to(sign_in_path) do
|
||||
i.fa.fa-sign-in
|
||||
|
@@ -38,4 +38,4 @@
|
||||
= t('exercises.editor.test')
|
||||
= render('editor_button', data: {:'data-placement' => 'top', :'data-tooltip' => true}, icon: 'fa fa-trophy', id: 'assess', label: t('exercises.editor.score'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + s'))
|
||||
|
||||
= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.dialogtitle'), template: 'exercises/_comment_dialogcontent')
|
||||
= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent')
|
@@ -2,9 +2,9 @@
|
||||
|
||||
hr
|
||||
|
||||
= 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-sm', icon: 'fa fa-download', id: 'download', label: t('exercises.editor.download'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', icon: 'fa fa-bullhorn', id: 'request-for-comments', label: t('exercises.editor.requestComments'))
|
||||
- if @exercise.allow_file_creation?
|
||||
= 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('shared/modal', id: 'modal-file', template: 'code_ocean/files/_form', title: t('exercises.editor.create_file'))
|
||||
|
||||
= render('shared/modal', id: 'modal-file', template: 'code_ocean/files/_form', title: t('exercises.editor.create_file'))
|
||||
= render('editor_button', classes: 'btn-block btn-primary btn-sm', icon: 'fa fa-download', id: 'download', label: t('exercises.editor.download'))
|
||||
|
@@ -13,3 +13,7 @@
|
||||
- else
|
||||
.editor-content.hidden 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-id=file.id
|
||||
|
||||
button.btn.btn-primary.requestCommentsButton type='button'
|
||||
i.fa.fa-comment-o
|
||||
= t('exercises.editor.requestComments')
|
@@ -28,6 +28,10 @@
|
||||
label
|
||||
= f.check_box(:hide_file_tree)
|
||||
= t('activerecord.attributes.exercise.hide_file_tree')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:allow_file_creation)
|
||||
= t('activerecord.attributes.exercise.allow_file_creation')
|
||||
h2 = t('activerecord.attributes.exercise.files')
|
||||
ul#files.list-unstyled.panel-group
|
||||
= f.fields_for :files do |files_form|
|
||||
|
@@ -0,0 +1,4 @@
|
||||
h5 = t('exercises.implement.comment.question')
|
||||
textarea.form-control#question(style='resize:none;')
|
||||
p = ''
|
||||
button#askForCommentsButton.btn.btn-block.btn-primary(type='button' data-message-success=t('exercises.editor.request_for_comments_sent')) =t('exercises.implement.comment.request')
|
@@ -28,7 +28,7 @@ h1 = Exercise.model_name.human(count: 2)
|
||||
tr data-id=exercise.id
|
||||
td = exercise.title
|
||||
td = link_to_if(policy(exercise.author).show?, exercise.author, exercise.author)
|
||||
td = link_to_if(policy(exercise.execution_environment).show?, exercise.execution_environment, exercise.execution_environment)
|
||||
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.public data-value=exercise.public? = symbol_for(exercise.public?)
|
||||
|
@@ -16,6 +16,7 @@ h1
|
||||
= row(label: 'exercise.maximum_score', value: @exercise.maximum_score)
|
||||
= row(label: 'exercise.public', value: @exercise.public?)
|
||||
= 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.embedding_parameters') do
|
||||
= content_tag(:input, nil, class: 'form-control', readonly: true, value: embedding_parameters(@exercise))
|
||||
|
||||
|
@@ -22,7 +22,7 @@ html lang='en'
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.navbar-brand href=root_path
|
||||
.navbar-brand
|
||||
i.fa.fa-code
|
||||
= application_name
|
||||
#navbar-collapse.collapse.navbar-collapse
|
||||
|
@@ -1,19 +1,22 @@
|
||||
h1 = RequestForComment.model_name.human(count: 2)
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
table.table.sortable
|
||||
thead
|
||||
tr
|
||||
th = t('activerecord.attributes.request_for_comments.exercise')
|
||||
th = t('activerecord.attributes.request_for_comments.execution_environment')
|
||||
th = t('activerecord.attributes.request_for_comments.question')
|
||||
th = t('activerecord.attributes.request_for_comments.username')
|
||||
th = t('activerecord.attributes.request_for_comments.requested_at')
|
||||
tbody
|
||||
- @request_for_comments.each do |request_for_comment|
|
||||
tr data-id=request_for_comment.id
|
||||
td = link_to(request_for_comment.exercise.title, request_for_comment)
|
||||
td = request_for_comment.exercise.execution_environment
|
||||
td = request_for_comment.user.name
|
||||
td = request_for_comment.requested_at
|
||||
- if request_for_comment.has_attribute?(:question) && request_for_comment.question
|
||||
td = truncate(request_for_comment.question, length: 200)
|
||||
- else
|
||||
td = '-'
|
||||
td = request_for_comment.user.displayname
|
||||
td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.requested_at))
|
||||
|
||||
= render('shared/pagination', collection: @request_for_comments)
|
@@ -14,6 +14,13 @@
|
||||
%>
|
||||
<%= user %> | <%= @request_for_comment.requested_at %>
|
||||
</p>
|
||||
<h5>
|
||||
<% if @request_for_comment.question and not @request_for_comment.question == '' %>
|
||||
<%= t('activerecord.attributes.request_for_comments.question')%>: "<%= @request_for_comment.question %>"
|
||||
<% else %>
|
||||
<%= t('request_for_comments.no_question') %>
|
||||
<% end %>
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
@@ -25,27 +32,22 @@ do not put a carriage return in the line below. it will be present in the presen
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.dialogtitle'), template: 'exercises/_comment_dialogcontent') %>
|
||||
|
||||
<script type="text/javascript">
|
||||
var commentitor = $('.editor');
|
||||
var userid = commentitor.data('user-id');
|
||||
|
||||
commentitor.each(function (index, editor) {
|
||||
currentEditor = ace.edit(editor);
|
||||
var currentEditor = ace.edit(editor);
|
||||
currentEditor.setReadOnly(true);
|
||||
|
||||
setAnnotations(currentEditor, $(editor).data('file-id'));
|
||||
currentEditor.on("guttermousedown", handleSidebarClick);
|
||||
});
|
||||
|
||||
function setAnnotations(editor, fileid) {
|
||||
var session = editor.getSession()
|
||||
|
||||
var inputHtml = ''
|
||||
inputHtml += '<div class="input-group">'
|
||||
inputHtml += '<input type="text" class="form-control" id="commentInput"'
|
||||
inputHtml += 'placeholder="I\'d suggest a variable here" required>'
|
||||
inputHtml += '<span class="input-group-btn"><button id="submitComment"'
|
||||
inputHtml += 'class="btn btn-default"><%= t("exercises.implement.comment.addComment") %>!</button></span>'
|
||||
inputHtml += '</div>'
|
||||
var session = editor.getSession();
|
||||
|
||||
var jqrequest = $.ajax({
|
||||
dataType: 'json',
|
||||
@@ -58,57 +60,109 @@ do not put a carriage return in the line below. it will be present in the presen
|
||||
|
||||
jqrequest.done(function(response){
|
||||
$.each(response, function(index, comment) {
|
||||
comment.className = "code-ocean_comment"
|
||||
comment.className = "code-ocean_comment";
|
||||
comment.text = comment.username + ": " + comment.text
|
||||
})
|
||||
});
|
||||
|
||||
editor.getSession().setAnnotations(response)
|
||||
|
||||
$(editor.container).find('.ace_gutter-cell').popover({
|
||||
title: 'Add a comment',
|
||||
html: true,
|
||||
content: inputHtml,
|
||||
position: 'right',
|
||||
trigger: 'focus click'
|
||||
}).on('shown.bs.popover', function() {
|
||||
var container = $(editor.container)
|
||||
container.find('#commentInput').focus()
|
||||
container.find('#submitComment').click(_.partial(addComment, editor, fileid));
|
||||
container.find('#commentInput').data('line', $(this).text())
|
||||
})
|
||||
session.setAnnotations(response);
|
||||
})
|
||||
}
|
||||
|
||||
function addComment(editor, fileid) {
|
||||
var commentInput = $(editor.container).find('#commentInput');
|
||||
var comment = commentInput.val()
|
||||
var line = commentInput.data('line')
|
||||
function hasCommentsInRow(editor, row){
|
||||
return editor.getSession().getAnnotations().some(function(element) {
|
||||
return element.row === row;
|
||||
})
|
||||
}
|
||||
|
||||
if (line == '' || comment == '') {
|
||||
return
|
||||
} else {
|
||||
line = parseInt(line) - 1
|
||||
}
|
||||
function getCommentsForRow(editor, row){
|
||||
return editor.getSession().getAnnotations().filter(function(element) {
|
||||
return element.row === row;
|
||||
})
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
function deleteComment(file_id, row, editor) {
|
||||
var jqxhr = $.ajax({
|
||||
type: 'DELETE',
|
||||
url: "/comments",
|
||||
data: {
|
||||
row: row,
|
||||
file_id: file_id }
|
||||
});
|
||||
jqxhr.done(function (response) {
|
||||
setAnnotations(editor, file_id);
|
||||
});
|
||||
jqxhr.fail(ajaxError);
|
||||
}
|
||||
|
||||
function createComment(file_id, row, editor, commenttext){
|
||||
var jqxhr = $.ajax({
|
||||
data: {
|
||||
comment: {
|
||||
user_id: userid,
|
||||
file_id: fileid,
|
||||
row: line,
|
||||
file_id: file_id,
|
||||
row: row,
|
||||
column: 0,
|
||||
text: comment
|
||||
text: commenttext
|
||||
}
|
||||
},
|
||||
dataType: 'json',
|
||||
method: 'POST',
|
||||
url: "/comments"
|
||||
}).done(setAnnotations(editor, fileid))
|
||||
|
||||
$('.ace_gutter-cell').popover('hide')
|
||||
});
|
||||
jqxhr.done(function(response){
|
||||
setAnnotations(editor, file_id);
|
||||
});
|
||||
jqxhr.fail(ajaxError);
|
||||
}
|
||||
|
||||
function handleSidebarClick(e) {
|
||||
var target = e.domEvent.target;
|
||||
var editor = e.editor;
|
||||
|
||||
if (target.className.indexOf("ace_gutter-cell") == -1) return;
|
||||
//if (!editor.isFocused()) return;
|
||||
//if (e.clientX > 25 + target.getBoundingClientRect().left) return;
|
||||
|
||||
|
||||
var row = e.getDocumentPosition().row;
|
||||
e.stop();
|
||||
|
||||
var commentModal = $('#comment-modal');
|
||||
|
||||
if (hasCommentsInRow(editor, row)) {
|
||||
var rowComments = getCommentsForRow(editor, row);
|
||||
var comments = _.pluck(rowComments, 'text').join('\n');
|
||||
commentModal.find('#other-comments').text(comments);
|
||||
} else {
|
||||
commentModal.find('#other-comments').text('none');
|
||||
}
|
||||
|
||||
commentModal.find('#addCommentButton').off('click');
|
||||
commentModal.find('#removeAllButton').off('click');
|
||||
|
||||
commentModal.find('#addCommentButton').on('click', function(e){
|
||||
var commenttext = commentModal.find('textarea').val();
|
||||
var file_id = $(editor.container).data('file-id');
|
||||
|
||||
if (commenttext !== "") {
|
||||
createComment(file_id, row, editor, commenttext);
|
||||
commentModal.modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
commentModal.find('#removeAllButton').on('click', function(e){
|
||||
var file_id = $(editor.container).data('file-id');
|
||||
deleteComment(file_id, row, editor);
|
||||
commentModal.modal('hide');
|
||||
});
|
||||
|
||||
commentModal.modal('show');
|
||||
}
|
||||
|
||||
function ajaxError(response) {
|
||||
var message = ((response || {}).responseJSON || {}).message || '';
|
||||
|
||||
$.flash.danger({
|
||||
text: message.length > 0 ? message : $('#flash').data('message-failure')
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
#commentitor, .ace_gutter, .ace_gutter-layer { overflow: visible }
|
||||
.popover { width: 400px; max-width: none; }
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user