Merge branch 'master' into feature-file-templates
Conflicts: app/views/application/_navigation.html.slim config/locales/de.yml config/locales/en.yml db/schema.rb
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
- if current_user.admin?
|
||||
li = link_to(t('breadcrumbs.dashboard.show'), admin_dashboard_path)
|
||||
li.divider
|
||||
- models = [ExecutionEnvironment, Exercise, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser, Submission, Team].sort_by { |model| model.model_name.human(count: 2) }
|
||||
- models = [ExecutionEnvironment, Exercise, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser, Submission].sort_by { |model| model.model_name.human(count: 2) }
|
||||
- models.each do |model|
|
||||
- if policy(model).index?
|
||||
li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
|
||||
|
@@ -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.request'), template: 'exercises/_request_comment_dialogcontent')
|
||||
= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent')
|
||||
|
@@ -14,6 +14,6 @@
|
||||
.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
|
||||
button.btn.btn-primary.requestCommentsButton type='button' id="requestComments"
|
||||
i.fa.fa-comment
|
||||
= t('exercises.editor.requestComments')
|
@@ -1,10 +1,10 @@
|
||||
- id = f.object.id
|
||||
li.panel.panel-default
|
||||
.panel-heading role="tab" id="heading"
|
||||
div.clearfix role="button"
|
||||
span = f.object.name
|
||||
a.pull-right data-toggle="collapse" data-parent="#files" href="#collapse#{id}" collapse
|
||||
.panel-collapse.collapse.in id="collapse#{id}" role="tabpanel"
|
||||
a.file-heading data-toggle="collapse" data-parent="#files" href="#collapse#{id}"
|
||||
div.clearfix role="button"
|
||||
span = f.object.name
|
||||
.panel-collapse.collapse-in id="collapse#{id}" role="tabpanel"
|
||||
.panel-body
|
||||
.clearfix = link_to(t('shared.destroy'), '#', class:'btn btn-warning btn-sm discard-file pull-right')
|
||||
.form-group
|
||||
|
@@ -17,9 +17,6 @@
|
||||
= f.label(:instructions)
|
||||
= f.hidden_field(:instructions)
|
||||
.form-control.markdown
|
||||
/.form-group
|
||||
= f.label(:team_id)
|
||||
= f.collection_select(:team_id, @teams, :id, :name, {include_blank: true}, class: 'form-control')
|
||||
.checkbox
|
||||
label
|
||||
= f.check_box(:public)
|
||||
|
@@ -50,9 +50,9 @@ h1 = "#{@exercise} (external user #{@external_user})"
|
||||
td
|
||||
-submission.testruns.each do |run|
|
||||
- if run.passed
|
||||
.unit-test-result.positive-result
|
||||
.unit-test-result.positive-result title=run.output
|
||||
- else
|
||||
.unit-test-result.negative-result
|
||||
.unit-test-result.negative-result title=run.output
|
||||
td = Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0
|
||||
-working_times_until.push((Time.at(deltas[1..index].inject(:+)).utc.strftime("%H:%M:%S") if index > 0))
|
||||
p = t('.addendum')
|
||||
|
@@ -78,6 +78,9 @@
|
||||
br
|
||||
- if session[:lti_parameters].try(:has_key?, 'lis_outcome_service_url')
|
||||
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'))
|
||||
|
||||
- if qa_url
|
||||
#questions-column
|
||||
#questions-holder data-url="#{qa_url}/qa/index/#{@exercise.id}/#{@user_id}"
|
||||
|
@@ -27,7 +27,7 @@ h1 = Exercise.model_name.human(count: 2)
|
||||
- @exercises.each do |exercise|
|
||||
tr data-id=exercise.id
|
||||
td = exercise.title
|
||||
td = link_to_if(policy(exercise.author).show?, exercise.author, exercise.author)
|
||||
td = link_to_if(exercise.author && policy(exercise.author).show?, exercise.author, exercise.author)
|
||||
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
|
||||
|
@@ -12,7 +12,6 @@ h1
|
||||
= row(label: 'exercise.description', value: render_markdown(@exercise.description))
|
||||
= 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.team', value: @exercise.team ? link_to(@exercise.team, @exercise.team) : nil)
|
||||
= 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?)
|
||||
@@ -23,13 +22,15 @@ h1
|
||||
h2 = t('activerecord.attributes.exercise.files')
|
||||
|
||||
ul.list-unstyled.panel-group#files
|
||||
- @exercise.files.each do |file|
|
||||
- @exercise.files.order('name').each do |file|
|
||||
li.panel.panel-default
|
||||
.panel-heading role="tab" id="heading"
|
||||
div.clearfix role="button"
|
||||
span.panel-title = file.name_with_extension
|
||||
a.pull-right data-toggle="collapse" data-parent="#files" href="#collapse#{file.id}" collapse
|
||||
.panel-collapse.collapse.in id="collapse#{file.id}" role="tabpanel"
|
||||
a.file-heading data-toggle="collapse" data-parent="#files" href=".collapse#{file.id}"
|
||||
div.clearfix role="button"
|
||||
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
|
||||
- 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)
|
||||
|
@@ -4,19 +4,29 @@ h1 = RequestForComment.model_name.human(count: 2)
|
||||
table.table.sortable
|
||||
thead
|
||||
tr
|
||||
th
|
||||
i class="fa fa-lightbulb-o" aria-hidden="true" title = t('request_for_comments.solved') align="right"
|
||||
th = t('activerecord.attributes.request_for_comments.exercise')
|
||||
th = t('activerecord.attributes.request_for_comments.question')
|
||||
th
|
||||
i class="fa fa-comment" aria-hidden="true" title = t('request_for_comments.comments') align="center"
|
||||
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
|
||||
- if request_for_comment.solved?
|
||||
td
|
||||
span class="fa fa-check" aria-hidden="true"
|
||||
- else
|
||||
td = ''
|
||||
td = link_to(request_for_comment.exercise.title, request_for_comment)
|
||||
- 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.comments_count
|
||||
td = request_for_comment.user.displayname
|
||||
td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.requested_at))
|
||||
td = t('shared.time.before', time: distance_of_time_in_words_to_now(request_for_comment.created_at))
|
||||
|
||||
= render('shared/pagination', collection: @request_for_comments)
|
@@ -1,46 +1,76 @@
|
||||
<div class="list-group">
|
||||
<h4 class="list-group-item-heading"><%= Exercise.find(@request_for_comment.exercise_id) %></h4>
|
||||
<h4 id ="exercise_caption" class="list-group-item-heading" data-rfc-id = "<%= @request_for_comment.id %>" ><%= link_to(@request_for_comment.exercise.title, [:implement, @request_for_comment.exercise]) %></h4>
|
||||
<p class="list-group-item-text">
|
||||
<%
|
||||
user = @request_for_comment.user
|
||||
submission_id = ActiveRecord::Base.connection.execute("select id from submissions
|
||||
where exercise_id =
|
||||
#{@request_for_comment.exercise_id} AND
|
||||
user_id = #{@request_for_comment.user_id} AND
|
||||
'#{@request_for_comment.created_at}' > created_at
|
||||
order by created_at desc
|
||||
limit 1").first['id'].to_i
|
||||
submission = Submission.find(submission_id)
|
||||
submission = @request_for_comment.submission
|
||||
%>
|
||||
<%= user.displayname %> | <%= @request_for_comment.requested_at %>
|
||||
<%= user.displayname %> | <%= @request_for_comment.created_at.localtime %>
|
||||
</p>
|
||||
<h5>
|
||||
<u><%= t('activerecord.attributes.exercise.description') %>:</u> "<%= render_markdown(@request_for_comment.exercise.description) %>"
|
||||
</h5>
|
||||
|
||||
<h5>
|
||||
<% if @request_for_comment.question and not @request_for_comment.question == '' %>
|
||||
<%= t('activerecord.attributes.request_for_comments.question')%>: "<%= @request_for_comment.question %>"
|
||||
<u><%= t('activerecord.attributes.request_for_comments.question')%>:</u> "<%= @request_for_comment.question %>"
|
||||
<% else %>
|
||||
<%= t('request_for_comments.no_question') %>
|
||||
<u><%= t('activerecord.attributes.request_for_comments.question')%>:</u> <%= t('request_for_comments.no_question') %>
|
||||
<% end %>
|
||||
</h5>
|
||||
<% if (policy(@request_for_comment).mark_as_solved? and not @request_for_comment.solved?) %>
|
||||
<button class="btn btn-default" id="mark-as-solved-button"><%= t('request_for_comments.mark_as_solved') %></button>
|
||||
<% elsif (@request_for_comment.solved?) %>
|
||||
<button type="button" class="btn btn-success"><%= t('request_for_comments.solved') %></button>
|
||||
<% else %>
|
||||
|
||||
<% end %>
|
||||
</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.
|
||||
-->
|
||||
<% submission.files.each do |file| %>
|
||||
<%= (file.path or "") + "/" + file.name + file.file_type.file_extension %>
|
||||
<div id='commentitor' class='editor' data-read-only='true' data-file-id='<%=file.id%>'><%= file.content %>
|
||||
<div id='commentitor' class='editor' data-read-only='true' data-file-id='<%=file.id%>' data-mode='<%=file.file_type.editor_mode%>'><%= file.content %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.dialogtitle'), template: 'exercises/_comment_dialogcontent') %>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var solvedButton = $('#mark-as-solved-button');
|
||||
|
||||
solvedButton.on('click', function(event){
|
||||
var jqrequest = $.ajax({
|
||||
dataType: 'json',
|
||||
method: 'GET',
|
||||
url: location + '/mark_as_solved'
|
||||
});
|
||||
|
||||
jqrequest.done(function(response){
|
||||
if(response.solved){
|
||||
solvedButton.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// set file paths for ace
|
||||
var ACE_FILES_PATH = '/assets/ace/';
|
||||
_.each(['modePath', 'themePath', 'workerPath'], function(attribute) {
|
||||
ace.config.set(attribute, ACE_FILES_PATH);
|
||||
});
|
||||
|
||||
var commentitor = $('.editor');
|
||||
var userid = commentitor.data('user-id');
|
||||
|
||||
commentitor.each(function (index, editor) {
|
||||
var currentEditor = ace.edit(editor);
|
||||
currentEditor.setReadOnly(true);
|
||||
// set editor mode (used for syntax highlighting
|
||||
currentEditor.getSession().setMode($(editor).data('mode'));
|
||||
|
||||
setAnnotations(currentEditor, $(editor).data('file-id'));
|
||||
currentEditor.on("guttermousedown", handleSidebarClick);
|
||||
@@ -101,7 +131,8 @@ do not put a carriage return in the line below. it will be present in the presen
|
||||
file_id: file_id,
|
||||
row: row,
|
||||
column: 0,
|
||||
text: commenttext
|
||||
text: commenttext,
|
||||
request_id: $('h4#exercise_caption').data('rfc-id')
|
||||
}
|
||||
},
|
||||
dataType: 'json',
|
||||
|
@@ -1 +1 @@
|
||||
json.extract! @request_for_comment, :id, :user_id, :exercise_id, :file_id, :requested_at, :created_at, :updated_at, :user_type
|
||||
json.extract! @request_for_comment, :id, :user_id, :exercise_id, :file_id, :requested_at, :created_at, :updated_at, :user_type, :solved
|
||||
|
@@ -1 +1 @@
|
||||
json.extract! @submission, :download_url, :id, :score_url, :render_url, :run_url, :stop_url, :test_url, :files
|
||||
json.extract! @submission, :download_url, :download_file_url, :id, :score_url, :render_url, :run_url, :stop_url, :test_url, :files
|
||||
|
@@ -1,9 +0,0 @@
|
||||
= form_for(@team) do |f|
|
||||
= render('shared/form_errors', object: @team)
|
||||
.form-group
|
||||
= f.label(:name)
|
||||
= f.text_field(:name, class: 'form-control', required: true)
|
||||
.form-group
|
||||
= f.label(:internal_user_ids)
|
||||
= f.collection_select(:internal_user_ids, InternalUser.all.order(:name), :id, :name, {}, {class: 'form-control', multiple: true})
|
||||
.actions = render('shared/submit_button', f: f, object: @team)
|
@@ -1,3 +0,0 @@
|
||||
h1 = @hint
|
||||
|
||||
= render('form')
|
@@ -1,20 +0,0 @@
|
||||
h1 = Team.model_name.human(count: 2)
|
||||
|
||||
.table-responsive
|
||||
table.table
|
||||
thead
|
||||
tr
|
||||
th = t('activerecord.attributes.team.name')
|
||||
th = t('activerecord.attributes.team.internal_user_ids')
|
||||
th colspan=3 = t('shared.actions')
|
||||
tbody
|
||||
- @teams.each do |team|
|
||||
tr
|
||||
td = team.name
|
||||
td = team.members.count
|
||||
td = link_to(t('shared.show'), team_path(team.id))
|
||||
td = link_to(t('shared.edit'), edit_team_path(team.id))
|
||||
td = link_to(t('shared.destroy'), team_path(team.id), data: {confirm: t('shared.confirm_destroy')}, method: :delete)
|
||||
|
||||
= render('shared/pagination', collection: @teams)
|
||||
p = render('shared/new_button', model: Team, path: new_team_path)
|
@@ -1,3 +0,0 @@
|
||||
h1 = t('shared.new_model', model: Team.model_name.human)
|
||||
|
||||
= render('form')
|
@@ -1,9 +0,0 @@
|
||||
h1
|
||||
= @team
|
||||
= render('shared/edit_button', object: @team, path: edit_team_path(@team.id))
|
||||
|
||||
= row(label: 'team.name', value: @team.name)
|
||||
= row(label: 'team.internal_user_ids') do
|
||||
ul.list-unstyled
|
||||
- @team.members.order(:name).each do |internal_user|
|
||||
li = link_to(internal_user, internal_user)
|
1
app/views/user_mailer/got_new_comment.slim
Normal file
1
app/views/user_mailer/got_new_comment.slim
Normal file
@@ -0,0 +1 @@
|
||||
== t('mailers.user_mailer.got_new_comment.body', receiver_displayname: @receiver_displayname, link: link_to(@rfc_link, @rfc_link), commenting_user_displayname: @commenting_user_displayname, comment_text: @comment_text)
|
Reference in New Issue
Block a user