merge master

This commit is contained in:
Karol
2022-08-20 22:20:52 +02:00
291 changed files with 5413 additions and 9429 deletions

View File

@@ -1,7 +1,7 @@
- tips = Tip.order(:title)
form#tip-selection
.form-group
.mb-3
span.badge = t('activerecord.attributes.exercise_tip.tip')
.mb-2
= collection_select({}, :tip_ids, tips, :id, :to_s, {}, {id: 'add-tip-list', class: 'form-control', multiple: true})

View File

@@ -1,7 +1,7 @@
.form-group class="form-group-#{attribute.to_s.gsub('_', '-')}"
= form.label(attribute, label)
.mb-3
= form.label(attribute, label, class: 'form-label')
= form.text_area(attribute, class: 'code-field form-control', rows: 16, style: "display:none;")
= render partial: 'editor_edit', locals: { exercise: @exercise }
.card.border-warning.p-2.my-2
= form.file_field(attribute, class: 'form-control-file', style: "display: inline-block;")
= form.file_field(attribute, class: 'form-control', style: "display: inline-block;")
.help-block.form-text = t('exercises.file_form.hints.upload')

View File

@@ -3,10 +3,10 @@
.container
label
input#subscribe type='checkbox' title=t('request_for_comments.subscribe_to_author') data-subscription=Subscription.where(user: current_user, request_for_comment_id: @request_for_comment.id, subscription_type: 'author', deleted: false).try(:first).try(:id)
input#subscribe.form-check-input type='checkbox' title=t('request_for_comments.subscribe_to_author') data-subscription=Subscription.where(user: current_user, request_for_comment_id: @request_for_comment.id, subscription_type: 'author', deleted: false).try(:first).try(:id)
= t('request_for_comments.subscribe_to_author')
#myComment
#myComment.d-grid
h5 =t('exercises.implement.comment.addyours')
textarea.form-control
button#addCommentButton.btn.btn-block.btn-primary(type='button') =t('exercises.implement.comment.addCommentButton')
button#addCommentButton.btn.btn-primary(type='button') =t('exercises.implement.comment.addCommentButton')

View File

@@ -1,13 +1,13 @@
- external_user_external_id = @current_user.respond_to?(:external_id) ? @current_user.external_id : '' #'tests' #(@current_user.uuid.present? ? @current_user.uuid : '')
- external_user_id = @current_user.respond_to?(:external_id) ? @current_user.id : '' #'tests' #(@current_user.uuid.present? ? @current_user.uuid : '')
- consumer_id = @current_user.respond_to?(:external_id) ? @current_user.consumer_id : '' #'tests' #(@current_user.uuid.present? ? @current_user.uuid : '')
- external_user_external_id = @current_user.respond_to?(:external_id) ? @current_user.external_id : ''
- external_user_id = @current_user.respond_to?(:external_id) ? @current_user.id : ''
- consumer_id = @current_user.respond_to?(:external_id) ? @current_user.consumer_id : ''
- show_break_interventions = @show_break_interventions || "false"
- show_rfc_interventions = @show_rfc_interventions || "false"
- show_tips_interventions = @show_tips_interventions || "false"
- 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-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-tips-interventions=show_tips_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise)
- unless @embed_options[:hide_sidebar]
#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-message-out-of-memory=t('exercises.editor.out_of_memory', memory_limit: @exercise.execution_environment.memory_limit) 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-tips-interventions=show_tips_interventions data-course_token=@course_token data-search-save-url=search_exercise_path(@exercise)
- unless @embed_options[:hide_sidebar]
- additional_classes = 'sidebar-col'
- if @tips.blank?
- if @exercise.hide_file_tree
@@ -15,16 +15,18 @@
- else
- additional_classes = 'sidebar-col w-25'
div id="sidebar" class=additional_classes = render('editor_file_tree', exercise: @exercise, files: @files)
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')) unless @embed_options[:hide_run_button]
= render('editor_button', data: {:'data-message-failure' => t('exercises.editor.run_failure'), :'data-message-network' => t('exercises.editor.network'), :'data-message-success' => t('exercises.editor.run_success'), :'data-placement' => 'top', :'data-toggle' => 'tooltip', :'data-container' => 'body'}, icon: 'fa fa-play', id: 'run', label: t('exercises.editor.run'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + r')) unless @embed_options[:disable_run]
= render('editor_button', data: {:'data-placement' => 'top', :'data-toggle' => 'tooltip', :'data-container' => 'body'}, icon: 'fa fa-stop', id: 'stop', label: t('exercises.editor.stop'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + r')) unless @embed_options[:disable_run]
= render('editor_button', data: {:'data-placement' => 'top', :'data-toggle' => 'tooltip', :'data-container' => 'body'}, icon: 'fa fa-rocket', id: 'test', label: t('exercises.editor.test'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + t')) unless @embed_options[:disable_run]
= render('editor_button', data: {:'data-placement' => 'top', :'data-toggle' => 'tooltip', :'data-container' => 'body'}, icon: 'fa fa-trophy', id: 'assess', label: t('exercises.editor.score'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + s')) unless @embed_options[:disable_score]
= render('editor_button', disabled: true, icon: 'fa-solid fa-ban', id: 'dummy', label: t('exercises.editor.dummy'))
= render('editor_button', icon: 'fa-solid fa-desktop', id: 'render', label: t('exercises.editor.render')) unless @embed_options[:hide_run_button]
= render('editor_button', data: {:'data-message-failure' => t('exercises.editor.run_failure'), :'data-message-network' => t('exercises.editor.network'), :'data-message-success' => t('exercises.editor.run_success'), :'data-bs-placement' => 'top', :'data-bs-toggle' => 'tooltip', :'data-bs-container' => 'body'}, icon: 'fa-solid fa-play', id: 'run', label: t('exercises.editor.run'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + r')) unless @embed_options[:disable_run]
= render('editor_button', data: {:'data-bs-placement' => 'top', :'data-bs-toggle' => 'tooltip', :'data-bs-container' => 'body'}, icon: 'fa-solid fa-stop', id: 'stop', label: t('exercises.editor.stop'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + r')) unless @embed_options[:disable_run]
= render('editor_button', data: {:'data-bs-placement' => 'top', :'data-bs-toggle' => 'tooltip', :'data-bs-container' => 'body'}, icon: 'fa-solid fa-rocket', id: 'test', label: t('exercises.editor.test'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + t')) unless @embed_options[:disable_run]
= render('editor_button', data: {:'data-bs-placement' => 'top', :'data-bs-toggle' => 'tooltip', :'data-bs-container' => 'body'}, icon: 'fa-solid fa-trophy', id: 'assess', label: t('exercises.editor.score'), title: t('shared.tooltips.shortcut', shortcut: 'ALT + s')) unless @embed_options[:disable_score]
- unless hide_rfc_button
= render('editor_button', icon: 'fa fa-comment', id: 'requestComments', label: t('exercises.editor.requestComments'), title: t('exercises.editor.requestCommentsTooltip'))
= render('editor_button', icon: 'fa-solid fa-comment', id: 'requestComments', label: t('exercises.editor.requestComments'), title: t('exercises.editor.requestCommentsTooltip'))
- @files.each do |file|
- file.read_only = true if @embed_options[:read_only]
@@ -33,8 +35,8 @@
#statusbar.d-flex.justify-content-between
div
- if !@embed_options[:disable_download] && @exercise.hide_file_tree?
button#download.p-0.border-0.btn-link.visible.bg-white
i.fas.fa-arrow-down
button#download.p-0.border-0.btn-link.visible.bg-white.text-primary
i.fa-solid.fa-arrow-down
= t('exercises.editor.download')
div
@@ -44,8 +46,8 @@
= " | "
button#start-over-active-file.p-0.border-0.btn-link.bg-white data-message-confirm=t('exercises.editor.confirm_start_over_active_file') data-url=reload_exercise_path(@exercise)
i.fa.fa-history
button#start-over-active-file.p-0.border-0.btn-link.bg-white.text-primary data-message-confirm=t('exercises.editor.confirm_start_over_active_file') data-url=reload_exercise_path(@exercise)
i.fa-solid.fa-clock-rotate-left
= t('exercises.editor.start_over_active_file')
- unless @embed_options[:disable_run] && @embed_options[:disable_score]

View File

@@ -1,4 +1,4 @@
button.btn class=local_assigns.fetch(:classes, 'btn-primary') *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 class=(label.blank? ? "m-0" : '')
i.fa-solid.fa-circle-notch.fa-spin.d-none class=(label.blank? ? "m-0" : '')
i class=(label.present? ? icon : "#{icon} m-0")
= label

View File

@@ -1,41 +1,36 @@
div id='sidebar-collapsed' class=(@exercise.hide_file_tree && @tips.blank? ? '' : 'd-none')
= render('editor_button', classes: 'btn-block btn-outline-dark 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'))
div.d-grid.gap-2 id='sidebar-collapsed' class=(@exercise.hide_file_tree && @tips.blank? ? '' : 'd-none')
= render('editor_button', classes: 'btn-outline-dark', data: {:'data-bs-toggle' => 'tooltip', :'data-bs-placement' => 'right'}, icon: 'fa-solid fa-square-plus', id: 'sidebar-collapse-collapsed', label:'', title:t('exercises.editor.expand_action_sidebar'))
- unless @embed_options[:disable_hints] or @tips.blank?
= render('editor_button', classes: 'btn-block btn-secondary btn mb-4', data: {:'data-toggle' => 'tooltip', :'data-placement' => 'right'}, icon: 'fa fa-lightbulb', id: 'tips-collapsed', label:'', title: t('exercises.form.tips'))
= render('editor_button', classes: 'btn-secondary btn mb-4', data: {:'data-bs-toggle' => 'tooltip', :'data-bs-placement' => 'right'}, icon: 'fa-solid fa-lightbulb', id: 'tips-collapsed', label:'', title: t('exercises.form.tips'))
//- 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'))
= render('editor_button', classes: 'btn-primary btn enforce-top-margin', data: {:'data-bs-toggle' => 'tooltip', :'data-bs-placement' => 'right'}, icon: 'fa-solid fa-magnifying-glass', id: 'sidebar-search-collapsed', label: '', title: t('search.search_in_forum'))
div.h-100.col-sm-12.enforce-bottom-margin id='sidebar-uncollapsed' class=(@exercise.hide_file_tree && @tips.blank? ? 'd-none' : '')
.position-absolute.d-flex.mb-1.w-100 style="overflow: auto; left: 0; top: 0; height: 100%;"
.w-100
= render('editor_button', classes: 'btn-block btn-outline-dark btn', icon: 'fa fa-minus-square', id: 'sidebar-collapse', label: t('exercises.editor.collapse_action_sidebar'))
div.d-grid.enforce-bottom-margin id='sidebar-uncollapsed' class=(@exercise.hide_file_tree && @tips.blank? ? 'd-none' : '')
= render('editor_button', classes: 'btn-outline-dark overflow-hidden mb-2', icon: 'fa-solid fa-square-minus', id: 'sidebar-collapse', label: t('exercises.editor.collapse_action_sidebar'))
#content-left-sidebar.overflow-scroll
- unless @exercise.hide_file_tree
div.overflow-scroll
.card.border-secondary
.card-header.d-flex.justify-content-between.align-items-center.px-0.py-1
.px-2 = I18n.t('exercises.editor_file_tree.file_root')
div
- if @exercise.allow_file_creation
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-bs-toggle' => 'tooltip', :'data-cause' => 'file'}, icon: 'fa-solid fa-plus', id: 'create-file', label: '', title: t('exercises.editor.create_file'))
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-bs-toggle' => 'tooltip', :'data-cause' => 'file', :'data-message-confirm' => t('shared.confirm_destroy') }, icon: 'fa-regular fa-trash-can', id: 'destroy-file', label: '', title: t('exercises.editor.destroy_file'))
- unless @embed_options[:disable_download]
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-bs-toggle' => 'tooltip'}, icon: 'fa-solid fa-arrow-down', id: 'download', label:'', title: t('exercises.editor.download'))
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-bs-toggle' => 'tooltip', :'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(@exercise)}, icon: 'fa-solid fa-clock-rotate-left', id: 'start-over', label: '', title: t('exercises.editor.start_over'))
- unless @exercise.hide_file_tree
div
hr
.card-body.pt-0.pe-0.ps-1.pb-1
.card.border-secondary
.card-header.d-flex.justify-content-between.align-items-center.px-0.py-1
.px-2 = I18n.t('exercises.editor_file_tree.file_root')
div
- if @exercise.allow_file_creation
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-toggle' => 'tooltip', :'data-cause' => 'file'}, icon: 'fa fa-plus', id: 'create-file', label: '', title: t('exercises.editor.create_file'))
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-toggle' => 'tooltip', :'data-cause' => 'file', :'data-message-confirm' => t('shared.confirm_destroy') }, icon: 'far fa-trash-alt', id: 'destroy-file', label: '', title: t('exercises.editor.destroy_file'))
- unless @embed_options[:disable_download]
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-toggle' => 'tooltip'}, icon: 'fas fa-arrow-down', id: 'download', label:'', title: t('exercises.editor.download'))
= render('editor_button', classes: 'btn-default btn-sm', data: {:'data-toggle' => 'tooltip', :'data-message-confirm' => t('exercises.editor.confirm_start_over'), :'data-url' => reload_exercise_path(@exercise)}, icon: 'fa fa-history', id: 'start-over', label: '', title: t('exercises.editor.start_over'))
#files data-entries=FileTree.new(files).to_js_tree
.card-body.pt-0.pr-0.pl-1.pb-1
hr
#files data-entries=FileTree.new(files).to_js_tree
hr
- unless @embed_options[:disable_hints] or @tips.blank?
= render(partial: 'tips_content')
.mb-4
- unless @embed_options[:disable_hints] or @tips.blank?
= render(partial: 'tips_content')
//- if !@course_token.blank?
.input-group.enforce-top-margin
@@ -43,7 +38,7 @@ div.h-100.col-sm-12.enforce-bottom-margin id='sidebar-uncollapsed' class=(@exerc
= text_field_tag 'search-input-text', nil, placeholder: t('search.search_in_forum'), class: 'form-control'
.input-group-btn
= button_tag(class: 'btn btn-primary', id: 'btn-search-col') do
i.fa.fa-search
i.fa-solid.fa-magnifying-glass
- if @exercise.allow_file_creation?
= render('shared/modal', id: 'modal-file', template: 'code_ocean/files/_form', title: t('exercises.editor.create_file'))

View File

@@ -1,90 +1,86 @@
div id='output_sidebar_collapsed'
= render('editor_button', classes: 'btn-block btn-outline-dark 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_yet')
.row
= render('editor_button', classes: 'btn-block btn-outline-dark btn', icon: 'fa fa-minus-square', id: 'toggle-sidebar-output', label: t('exercises.editor.collapse_output_sidebar'))
div.d-grid id='output_sidebar_collapsed'
= render('editor_button', classes: 'btn-outline-dark btn', data: {:'data-bs-toggle' => 'tooltip', :'data-bs-placement' => 'left'}, title: t('exercises.editor.expand_output_sidebar'), icon: 'fa-solid fa-square-plus', id: 'toggle-sidebar-output-collapsed', label: '')
div.d-grid id='output_sidebar_uncollapsed' class='d-none col-sm-12 enforce-bottom-margin' data-message-no-output=t('exercises.implement.no_output_yet')
= render('editor_button', classes: 'btn-outline-dark btn overflow-hidden mb-2', icon: 'fa-solid fa-square-minus', id: 'toggle-sidebar-output', label: t('exercises.editor.collapse_output_sidebar'))
div.position-absolute.d-flex.mb-1.w-100 style="overflow: auto; 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)
- unless @embed_options[:hide_test_results]
ul.list-unstyled
ul#test-dummies.d-none.list-unstyled
li.card.mt-2
.card-header.py-2
h5.card-title.m-0 == t('exercises.implement.test_file', filename: '', number: 0)
.card-body.bg-white.text-dark
= row(label: 'exercises.implement.passed_tests') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'activerecord.attributes.submission.score') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'exercises.implement.feedback')
= row(label: 'exercises.implement.error_messages')
/= row(label: 'exercises.implement.output', value: link_to(t('shared.show'), '#'))
ul#linter-dummies.d-none.list-unstyled
li.card.mt-2
.card-header.py-2
h5.card-title.m-0 == t('exercises.implement.linter_file', filename: '', number: 0)
.card-body.bg-white.text-dark
= row(label: 'exercises.implement.code_rating') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'activerecord.attributes.submission.score') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'exercises.implement.feedback')
= row(label: 'exercises.implement.messages')
#score data-maximum-score=@exercise.maximum_score data-score=@exercise.final_submission(@current_user).try(:score)
h4
span == "#{t('activerecord.attributes.submission.score')}:&nbsp;"
span.score
.progress
.progress-bar role='progressbar'
#content-right-sidebar.overflow-scroll
div.enforce-bottom-margin.overflow-auto.d-none id='score_div'
#results
h2 = t('exercises.implement.results')
p.test-count == t('exercises.implement.test_count', count: 0)
- unless @embed_options[:hide_test_results]
ul.list-unstyled
ul#test-dummies.d-none.list-unstyled
li.card.mt-2
.card-header.py-2
h5.card-title.m-0 == t('exercises.implement.test_file', filename: '', number: 0)
.card-body.bg-white.text-dark
= row(label: 'exercises.implement.passed_tests') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'activerecord.attributes.submission.score') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'exercises.implement.feedback')
= row(label: 'exercises.implement.error_messages')
/= row(label: 'exercises.implement.output', value: link_to(t('shared.show'), '#'))
ul#linter-dummies.d-none.list-unstyled
li.card.mt-2
.card-header.py-2
h5.card-title.m-0 == t('exercises.implement.linter_file', filename: '', number: 0)
.card-body.bg-white.text-dark
= row(label: 'exercises.implement.code_rating') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'activerecord.attributes.submission.score') do
span.number
| 0
=<> t('shared.out_of')
span.number
| 0
= row(label: 'exercises.implement.feedback')
= row(label: 'exercises.implement.messages')
#score data-maximum-score=@exercise.maximum_score data-score=@exercise.final_submission(@current_user).try(:score)
h4
span == "#{t('activerecord.attributes.submission.score')}:&nbsp;"
span.score
.progress
.progress-bar role='progressbar'
br
- if lti_outcome_service?(@exercise.id, external_user_id)
p.text-center = render('editor_button', classes: 'btn-lg btn-success d-none', data: {:'data-url' => submit_exercise_path(@exercise)}, icon: 'fa fa-send', id: 'submit', label: t('exercises.editor.submit'))
- if @exercise.submission_deadline.present? || @exercise.late_submission_deadline.present?
#deadline data-submission-deadline=@exercise.submission_deadline&.rfc2822 data-late-submission-deadline=@exercise.late_submission_deadline&.rfc2822
h4 = t('exercises.editor.deadline')
= t('exercises.editor.hints.disclaimer')
- else
p.text-center = render('editor_button', classes: 'btn-lg btn-secondary 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.d-none width=400 height=400
div.enforce-big-top-margin
#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')
- unless @embed_options[:disable_hints]
#error-hints
.heading = t('exercises.implement.error_hints.heading')
ul.body
#output.mt-2
pre = t('exercises.implement.no_output_yet')
- if CodeOcean::Config.new(:code_ocean).read[:flowr][:enabled] && !@embed_options[:disable_hints] && !@embed_options[:hide_test_results]
#flowrHint.card.text-white.bg-info data-url=CodeOcean::Config.new(:code_ocean).read[:flowr][:url] role='tab'
.card-header = t('exercises.implement.flowr.heading')
.card-body.text-dark.bg-white
br
- if lti_outcome_service?(@exercise.id, external_user_id)
p.text-center = render('editor_button', classes: 'btn-lg btn-success d-none', data: {:'data-url' => submit_exercise_path(@exercise)}, icon: 'fa-solid fa-paper-plane', id: 'submit', label: t('exercises.editor.submit'))
- if @exercise.submission_deadline.present? || @exercise.late_submission_deadline.present?
#deadline data-submission-deadline=@exercise.submission_deadline&.rfc2822 data-late-submission-deadline=@exercise.late_submission_deadline&.rfc2822
h4 = t('exercises.editor.deadline')
= t('exercises.editor.hints.disclaimer')
- else
p.text-center = render('editor_button', classes: 'btn-lg btn-secondary disabled', data: {:'data-bs-placement' => 'bottom', :'data-tooltip' => true}, icon: 'fa-regular fa-clock', id: 'submit_outdated', label: t('exercises.editor.exercise_deadline_passed'), title: t('exercises.editor.tooltips.exercise_deadline_passed'))
hr
#turtlediv.enforce-big-bottom-margin.overflow-auto.d-none
canvas#turtlecanvas width=400 height=400
div.enforce-big-bottom-margin.overflow-auto
#prompt.input-group.mb-2.d-none
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')
- unless @embed_options[:disable_hints]
#error-hints.mb-2.p-2
.heading = t('exercises.implement.error_hints.heading')
ul.body.mb-0
#output
pre.overflow-scroll = t('exercises.implement.no_output_yet')
- if CodeOcean::Config.new(:code_ocean).read[:flowr][:enabled] && !@embed_options[:disable_hints] && !@embed_options[:hide_test_results]
#flowrHint.mb-2.card.text-white.bg-info data-url=CodeOcean::Config.new(:code_ocean).read[:flowr][:url] role='tab'
.card-header = t('exercises.implement.flowr.heading')
.card-body.text-dark.bg-white

View File

@@ -1,14 +1,14 @@
- if error
= button_tag type: 'button', class:'btn btn-primary pull-right export-button export-retry-button', data: {exercise_id: exercise.id} do
i.fa.fa-refresh.confirm-icon
= button_tag type: 'button', class:'btn btn-primary float-end export-button export-retry-button', data: {exercise_id: exercise.id} do
i.fa-solid.fa-arrows-rotate.confirm-icon
= t('exercises.export_codeharbor.buttons.retry')
- else
- unless exported
- if !task_found || update_right
= button_tag type: 'button', class:'btn btn-primary pull-right export-action export-button', data: {exercise_id: exercise.id} do
i.fa.fa-check.confirm-icon
= button_tag type: 'button', class:'btn btn-primary float-end export-action export-button', data: {exercise_id: exercise.id} do
i.fa-solid.fa-check.confirm-icon
= t('exercises.export_codeharbor.buttons.export')
= button_tag type: 'submit', class:'btn btn-secondary pull-right export-button', data: {dismiss: 'modal'} do
i.fa.fa-remove.abort-icon
= button_tag type: 'submit', class:'btn btn-secondary float-end export-button', data: {dismiss: 'modal'} do
i.fa-solid.fa-xmark.abort-icon
= exported ? t('exercises.export_codeharbor.buttons.close') : t('exercises.export_codeharbor.buttons.abort')

View File

@@ -4,27 +4,27 @@ li.card.mt-2
.card-header role="tab" id="heading"
- collapsed_class = f.index != 'index' ? 'collapsed' : nil
- aria_expanded = f.index != 'index' ? 'false' : 'true'
a class=['file-heading', collapsed_class] data-toggle="collapse" href="#collapse#{f.index}" aria-expanded="#{aria_expanded}"
a class=['file-heading', collapsed_class] data-bs-toggle="collapse" href="#collapse#{f.index}" aria-expanded="#{aria_expanded}"
div.clearfix role="button"
i class="fa" aria-hidden="true"
i.fa-solid aria-hidden="true"
span = f.object.filepath
.card-collapse.collapse class=('in' if f.object.name.nil?) id="collapse#{f.index}" role="tabpanel"
.card-body
- if policy(f.object).destroy? && id.present?
.clearfix
.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'))
.btn.btn-warning.btn-sm.float-end.delete-file data-file-url=code_ocean_file_path(id) = t('shared.destroy')
.mb-3
= f.label(:name, t('activerecord.attributes.file.name'), class: 'form-label')
= f.text_field(:name, class: 'form-control')
.form-group
= f.label(:path, t('activerecord.attributes.file.path'))
.mb-3
= f.label(:path, t('activerecord.attributes.file.path'), class: 'form-label')
= f.text_field(:path, class: 'form-control')
.help-block.form-text = t('.hints.path')
.form-group
= f.label(:file_type_id, t('activerecord.attributes.file.file_type_id'))
.mb-3
= f.label(:file_type_id, t('activerecord.attributes.file.file_type_id'), class: 'form-label')
= f.collection_select(:file_type_id, @file_types, :id, :name, {}, class: 'form-control')
.form-group
= f.label(:role, t('activerecord.attributes.file.role'))
.mb-3
= f.label(:role, t('activerecord.attributes.file.role'), class: 'form-label')
= f.select(:role, CodeOcean::File::TEACHER_DEFINED_ROLES.map { |role| [t("files.roles.#{role}"), role] }, {}, class: 'form-control')
.form-check
label.form-check-label
@@ -35,11 +35,11 @@ li.card.mt-2
= f.check_box(:read_only, class: 'form-check-input')
= t('activerecord.attributes.file.read_only')
.test-related-fields style="display: #{f.object.teacher_defined_assessment? ? 'initial' : 'none'};"
.form-group
= f.label(:name, t('activerecord.attributes.file.feedback_message'))
.mb-3
= f.label(:name, t('activerecord.attributes.file.feedback_message'), class: 'form-label')
= f.text_area(:feedback_message, class: 'form-control', maxlength: 255)
.help-block.form-text = t('.hints.feedback_message')
.form-group
= f.label(:role, t('activerecord.attributes.file.weight'))
.mb-3
= f.label(:role, t('activerecord.attributes.file.weight'), class: 'form-label')
= f.number_field(:weight, class: 'form-control', min: 0, step: 'any')
= render('code_field', attribute: :content, form: f, label: t('activerecord.attributes.file.content'))

View File

@@ -2,33 +2,33 @@
// 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_pack_tag('sortable', 'data-turbolinks-track': true)
- append_javascript_pack_tag('sortable')
- 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, builder: PagedownFormBuilder) do |f|
= render('shared/form_errors', object: @exercise)
.form-group
= f.label(:title)
.mb-3
= f.label(:title, class: 'form-label')
= f.text_field(:title, class: 'form-control', required: true)
.form-group
= f.label(:description)
.mb-3
= f.label(:description, class: 'form-label')
= f.pagedown :description, input_html: { preview: true, rows: 10 }
.form-group
= f.label(:execution_environment_id)
.mb-3
= f.label(:execution_environment_id, class: 'form-label')
= f.collection_select(:execution_environment_id, @execution_environments, :id, :name, {include_blank: t('exercises.form.none')}, class: 'form-control')
/.form-group
= f.label(:instructions)
/.mb-3
= f.label(:instructions, class: 'form-label')
= f.hidden_field(:instructions)
.form-control.markdown
.form-group
= f.label(:submission_deadline)
.mb-3
= f.label(:submission_deadline, class: 'form-label')
.chosen-inline
= f.datetime_select(:submission_deadline, include_blank: true)
.help-block.form-text == t('.hints.submission_deadline')
.form-group
= f.label(:late_submission_deadline)
.mb-3
= f.label(:late_submission_deadline, class: 'form-label')
.chosen-inline
= f.datetime_select(:late_submission_deadline, include_blank: true)
.help-block.form-text == t('.hints.late_submission_deadline')
@@ -52,15 +52,15 @@
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'))
.mb-3
= f.label(t('activerecord.attributes.exercise.difficulty'), class: 'form-label')
= f.number_field :expected_difficulty, in: 1..10, step: 1, class: 'form-control'
h2 = t('exercises.form.tags')
ul.list-unstyled.card-group
li.card
.card-header role="tab" id="heading"
a.file-heading data-toggle="collapse" href="#tag-collapse"
a.file-heading data-bs-toggle="collapse" href="#tag-collapse"
div.clearfix role="button"
span = t('exercises.form.click_to_collapse')
.card-collapse.collapse id="tag-collapse" role="tabpanel"
@@ -69,33 +69,33 @@
thead
tr
th = t('activerecord.attributes.exercise.selection')
th = sort_link(@search, :title, t('activerecord.attributes.tag.name'))
th = t('activerecord.attributes.tag.name')
th = t('activerecord.attributes.tag.difficulty')
= collection_check_boxes :exercise, :tag_ids, @exercise_tags, :tag_id, :id do |b|
tr
td = b.check_box
td = b.check_box class: 'form-check-input'
td = b.object.tag.name
td = number_field "tag_factors[#{b.object.tag.id}]", :factor, :value => b.object.factor, in: 1..10, step: 1, class: 'form-control-sm'
td = number_field "tag_factors[#{b.object.tag.id}]", :factor, :value => b.object.factor, in: 1..10, step: 1, class: 'form-control form-control-sm'
h2 = t('.tips')
ul.list-unstyled.card-group
li.card
.card-header role="tab" id="tip-heading"
a.file-heading data-toggle="collapse" href="#tip-collapse"
a.file-heading data-bs-toggle="collapse" href="#tip-collapse"
div.clearfix role="button"
span = t('exercises.form.click_to_collapse')
.card-collapse.collapse.mx-2 id="tip-collapse" role="tabpanel"
= f.hidden_field(:tips, id: "tips-json", value: "")
.list-group.nested-sortable-list.mt-2#tip-list
= render(partial: 'tips/sortable_tip', collection: @tips, as: :exercise_tip)
button.btn.btn-outline-primary.my-2.w-100 type='button' data-toggle='modal' data-target='#add-tips-modal' = t('.add_tips')
button.btn.btn-outline-primary.my-2.w-100 type='button' data-bs-toggle='modal' data-bs-target='#add-tips-modal' = t('.add_tips')
h2 = t('activerecord.attributes.exercise.files')
ul#files.list-unstyled
= f.fields_for :files do |files_form|
= render('file_form', f: files_form)
a#add-file.btn.btn-secondary.btn-sm.float-right href='#' = t('.add_file')
a#add-file.btn.btn-secondary.btn-sm.float-end 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)

View File

@@ -1,11 +1,11 @@
h5#rfc_intervention_text style='display: none;' = raw t('exercises.implement.rfc_intervention.text')
h5 = raw t('exercises.implement.comment.question')
#rfc_intervention_text style='display: none;' == t('exercises.implement.rfc_intervention.text')
== t('exercises.implement.comment.question')
textarea.form-control.flex-grow-1#question(style='resize:none;')
textarea.form-control.flex-grow-1#question(style='resize:none; height: 15vh;')
p = ''
/ data-cause='requestComments' is not used here right now, we pass the button #requestComments (not askForCommentsButton) as initiator of the action.
/ 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
div
button#askForCommentsButton.btn.btn-block.btn-primary(type='button' data-cause='requestComments' data-message-success=t('exercises.editor.request_for_comments_sent')) =t('exercises.implement.comment.request')
button#closeAskForCommentsButton.btn.btn-block.btn-warning(type='button') =t('activerecord.attributes.request_for_comments.close')
.d-grid.gap-2
button#askForCommentsButton.btn.btn-primary(type='button' data-cause='requestComments' data-message-success=t('exercises.editor.request_for_comments_sent')) =t('exercises.implement.comment.request')
button#closeAskForCommentsButton.btn.btn-warning(type='button') =t('activerecord.attributes.request_for_comments.close')

View File

@@ -2,12 +2,12 @@
// 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_pack_tag('highlight', 'data-turbolinks-track': true)
= stylesheet_pack_tag('highlight', media: 'all', 'data-turbolinks-track': true)
- append_javascript_pack_tag('highlight')
- append_stylesheet_pack_tag('highlight')
#tips.card.mt-2 role="tab" style="display: block;"
#tips.card.d-block.overflow-scroll role="tab"
.card-header.py-2
i.fa.fa-lightbulb
i.fa-solid.fa-lightbulb
= t('exercises.implement.tips.heading')
.card-body.text-dark.bg-white.p-2
= render(partial: 'tips/collapsed_card', collection: @tips, as: :exercise_tip, locals: { tip_prefix: '' })

View File

@@ -3,20 +3,21 @@ h1
' (external user
= link_to_if(policy(@external_user).show?, @external_user.displayname, @external_user)
' )
- current_submission = @submissions.first
- submissions = @all_events.filter{|event| event.is_a? Submission}
- current_submission = submissions.first
- if current_submission
- initial_files = current_submission.files.to_a
- all_files = []
- file_types = Set.new()
- @submissions.each do |submission|
- submissions.each do |submission|
- submission.files.each do |file|
- file_types.add(ActiveSupport::JSON.encode(file.file_type))
- all_files.push(submission.files)
- all_files.reject!(&:blank?)
- file_types.reject!(&:blank?)
.d-none#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
@@ -28,16 +29,28 @@ h1
.flex-container
button.btn.btn-secondary id='play-button'
span.fa.fa-play
span.fa-solid.fa-play
#submissions-slider.flex-item
input type='range' orient='horizontal' list='datapoints' min=0 max=all_files.length-1 value=0 style="width: 100%"
datalist#datapoints
- index=0
- @submissions.each do |submission|
- submissions.each do |submission|
- next if submission.files.blank?
option data-submission=submission
=index
- index += 1
- if policy(@exercise).detailed_statistics?
.bg-light.w-100.p-2.mb-4.align-items-center.d-flex.justify-content-between
- if @show_autosaves
span.ps-1.pb-1
i.fa-solid.fa-circle-info.align-middle
small.me-5.ms-1 = t('.toggle_status_on')
= link_to t('.toggle_autosave_off'), statistics_external_user_exercise_path(show_autosaves: false), class: "btn btn-outline-dark float-end btn-sm"
- else
span.ps-1.pb-1
i.fa-solid.fa-circle-info.align-middle
small.me-5.ms-1 = t('.toggle_status_off')
= link_to t('.toggle_autosave_on'), statistics_external_user_exercise_path(show_autosaves: true), class: "btn btn-outline-dark float-end btn-sm"
#timeline
.table-responsive
table.table
@@ -65,9 +78,9 @@ h1
td.align-middle
-this.testruns.includes(:file).order("files.name").each do |run|
- if run.passed
.unit-test-result.positive-result title=[run.file&.filepath, run.output].join("\n").strip
.unit-test-result.positive-result title=[run.file&.filepath, run.log].join.strip
- else
.unit-test-result.unknown-result title=[run.file&.filepath, run.output].join("\n").strip
.unit-test-result.unknown-result title=[run.file&.filepath, run.log].join.strip
td = @working_times_until[index] if index > 0 if policy(@exercise).detailed_statistics?
- elsif this.is_a? UserExerciseIntervention
td = this.created_at.strftime("%F %T")

View File

@@ -4,7 +4,7 @@ h1 = link_to_if(policy(@exercise).show?, @exercise, exercise_path(@exercise))
.header = t('activerecord.attributes.exercise.description')
.value = render_markdown(@exercise.description)
span.header.col-sm-3.pl-0 = "#{t('activerecord.attributes.exercise.maximum_score')}"
span.header.col-sm-3.ps-0 = "#{t('activerecord.attributes.exercise.maximum_score')}"
span.col-sm-9 = @exercise.maximum_score
.header.mt-3 = t('activerecord.models.user_exercise_feedback.other')
@@ -21,7 +21,7 @@ h1 = link_to_if(policy(@exercise).show?, @exercise, exercise_path(@exercise))
- if policy(@exercise).detailed_statistics?
span.username = link_to_if(policy(feedback.user).show?, feedback.user.displayname, 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
i class="fa-regular fa-envelope" data-bs-placement="top" data-bs-toggle="tooltip" data-bs-container="body" title=feedback.anomaly_notification.reason
span.date = feedback.created_at
.card-collapse role="tabpanel"
.card-body.feedback
@@ -32,8 +32,8 @@ h1 = link_to_if(policy(@exercise).show?, @exercise, exercise_path(@exercise))
.card-footer
div.clearfix.feedback-header
span.points.flex-grow-1 = "#{t('exercises.statistics.score')}: #{@submissions[index].score}"
span.working_time.pull-right = "#{t('exercises.statistics.worktime')}: #{@exercise.average_working_time_for(feedback.user.id) or 0}"
span.working_time.float-end = "#{t('exercises.statistics.worktime')}: #{@exercise.average_working_time_for(feedback.user) or 0}"
= render('shared/pagination', collection: @feedbacks)
script type="text/javascript" $(function () { $('[data-toggle="tooltip"]').tooltip() });
script type="text/javascript" $(function () { $('[data-bs-toggle="tooltip"]').tooltip() });

View File

@@ -3,36 +3,31 @@
Otherwise, lti_parameters might be nil
meta name="turbolinks-cache-control" content="no-cache"
.row
#editor-column.col-md-12
- unless @embed_options[:hide_exercise_description]
.exercise.clearfix
div
span.badge.badge-pill.badge-primary.float-right.score
// col-md-12 required for CodePilot
#editor-column.col-md-12
- unless @embed_options[:hide_exercise_description]
.exercise.clearfix
div
span.badge.rounded-pill.bg-primary.float-end.score
h1 id="exercise-headline"
i id="description-symbol" class=(@embed_options[:collapse_exercise_description] ? 'fa fa-chevron-right' : 'fa fa-chevron-down')
= @exercise.title
h1 id="exercise-headline"
i id="description-symbol" class=(@embed_options[:collapse_exercise_description] ? 'fa-solid fa-chevron-right' : 'fa-solid fa-chevron-down')
= @exercise.title
#description-card.lead class=(@embed_options[:collapse_exercise_description] ? 'description-card-collapsed' : 'description-card')
= render_markdown(@exercise.description)
#description-card.lead class=(@embed_options[:collapse_exercise_description] ? 'description-card-collapsed' : 'description-card')
= render_markdown(@exercise.description)
a#toggle href="#" data-show=t('shared.show') data-hide=t('shared.hide')
- if @embed_options[:collapse_exercise_description]
= t('shared.show')
- else
= t('shared.hide')
a#toggle href="#" data-show=t('shared.show') data-hide=t('shared.hide')
- if @embed_options[:collapse_exercise_description]
= t('shared.show')
- else
= t('shared.hide')
#alert.alert.alert-danger role='alert'
h4 = t('.alert.title')
p = t('.alert.text', application_name: application_name)
#development-environment
.tab-content
#workspace.tab-pane.active = render('editor', exercise: @exercise, files: @files, submission: @submission)
= render('editor', exercise: @exercise, files: @files, submission: @submission)
- if qa_url
#questions-column
#questions-holder data-url="#{qa_url}/qa/index/#{@exercise.id}/#{@user_id}"
= qa_js_tag
- if qa_url
#questions-column
#questions-holder data-url="#{qa_url}/qa/index/#{@exercise.id}/#{@user_id}"
= qa_js_tag

View File

@@ -1,16 +1,15 @@
h1 = Exercise.model_name.human(count: 2)
= render(layout: 'shared/form_filters') do |f|
.row.px-3
.form-group
= f.label(:execution_environment_id_eq, t('activerecord.attributes.exercise.execution_environment'), class: 'sr-only')
= f.collection_select(:execution_environment_id_eq, @execution_environments.with_exercises, :id, :name, class: 'form-control', prompt: t('activerecord.attributes.exercise.execution_environment'))
.form-group
= f.label(:title_cont, t('activerecord.attributes.exercise.title'), class: 'sr-only')
= f.search_field(:title_cont, class: 'form-control', placeholder: t('activerecord.attributes.exercise.title'))
.col-auto
= f.label(:execution_environment_id_eq, t('activerecord.attributes.exercise.execution_environment'), class: 'visually-hidden form-label')
= f.collection_select(:execution_environment_id_eq, @execution_environments.with_exercises, :id, :name, class: 'form-control', prompt: t('activerecord.attributes.exercise.execution_environment'))
.col-auto
= f.label(:title_cont, t('activerecord.attributes.exercise.title'), class: 'visually-hidden form-label')
= f.search_field(:title_cont, class: 'form-control', placeholder: t('activerecord.attributes.exercise.title'))
.table-responsive
table.table.mt-4
table.table.mt-2
thead
tr
th.p-1 = sort_link(@search, :title, t('activerecord.attributes.exercise.title'))
@@ -41,8 +40,8 @@ h1 = Exercise.model_name.human(count: 2)
td.p-1
.btn-group
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"
button.btn.btn-outline-primary.btn-sm.dropdown-toggle data-bs-toggle="dropdown" type="button" = t('shared.actions_button')
ul.dropdown-menu.float-end 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('activerecord.models.request_for_comment.other'), rfcs_for_exercise_path(exercise), class: 'dropdown-item') if policy(exercise).rfcs_for_exercise?

View File

@@ -2,14 +2,14 @@
// 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_pack_tag('highlight', 'data-turbolinks-track': true)
= stylesheet_pack_tag('highlight', media: 'all', 'data-turbolinks-track': true)
- append_javascript_pack_tag('highlight')
- append_stylesheet_pack_tag('highlight')
h1.d-inline-block = @exercise
.btn-group.float-right
.btn-group.float-end
= render('shared/edit_button', object: @exercise)
button.btn.btn-secondary.float-right.dropdown-toggle data-toggle='dropdown' type='button'
ul.dropdown-menu.dropdown-menu-right role='menu'
button.btn.btn-secondary.float-end.dropdown-toggle data-bs-toggle='dropdown' type='button'
ul.dropdown-menu.dropdown-menu-end role='menu'
li = link_to(t('exercises.index.implement'), implement_exercise_path(@exercise), 'data-turbolinks' => "false", class: 'dropdown-item text-dark') if policy(@exercise).implement?
li = link_to(t('shared.statistics'), statistics_exercise_path(@exercise), 'data-turbolinks' => "false", class: 'dropdown-item text-dark') if policy(@exercise).statistics?
li = link_to(t('activerecord.models.user_exercise_feedback.other'), feedback_exercise_path(@exercise), class: 'dropdown-item text-dark') if policy(@exercise).feedback?
@@ -35,9 +35,10 @@ h1.d-inline-block = @exercise
= row(label: 'exercise.uuid', value: @exercise.uuid)
= 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: @exercise.unpublished? ? t('exercises.show.is_unpublished') : embedding_parameters(@exercise))
= content_tag(:input, nil, class: 'form-control bg-secondary mb-4', readonly: true, value: @exercise.unpublished? ? t('exercises.show.is_unpublished') : embedding_parameters(@exercise))
- unless @tips.blank?
.mt-2
= render(partial: 'tips_content')
h2.mt-4 = t('activerecord.attributes.exercise.files')
@@ -46,14 +47,14 @@ ul.list-unstyled#files
- @exercise.files.each do |file|
li.card.mt-2
.card-header role="tab" id="heading"
a.file-heading.collapsed data-toggle="collapse" data-parent="#files" href=".collapse#{file.id}"
a.file-heading.collapsed data-bs-toggle="collapse" data-bs-parent="#files" href=".collapse#{file.id}"
div.clearfix role="button"
i class="fa" aria-hidden="true"
i.fa-solid aria-hidden="true"
span = file.filepath
.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 float-right', data: {confirm: t('shared.confirm_destroy')}, method: :delete)
.clearfix = link_to(t('shared.destroy'), file, class:'btn btn-warning btn-sm float-end', data: {confirm: t('shared.confirm_destroy')}, method: :delete)
= render('shared/file', file: file)
= render('shared/modal', id: 'export-modal', title: t('exercises.export_codeharbor.dialogtitle'), template: 'exercises/_export_dialogcontent')

View File

@@ -2,7 +2,7 @@
// 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_pack_tag('d3-tip', 'data-turbolinks-track': true)
- append_javascript_pack_tag('d3-tip')
h1 = @exercise
= row(label: '.participants', value: @exercise.users.distinct.count)
@@ -48,7 +48,7 @@ h1 = @exercise
- if symbol==:external_users
- working_time_array = []
- @exercise.send(symbol).distinct().each do |user|
- working_time = @exercise.average_working_time_for(user.id) or 0
- working_time = @exercise.average_working_time_for(user) or 0
- working_time_array.push working_time
hr
.d-none#data data-working-time=ActiveSupport::JSON.encode(working_time_array)
@@ -73,10 +73,10 @@ h1 = @exercise
tbody
- users = symbol.to_s.classify.constantize.where(id: submissions.joins(symbol).group(:user_id).select(:user_id).distinct)
- users.each do |user|
- if user_statistics[user.id] then us = user_statistics[user.id] else us = {"maximum_score" => nil, "runs" => nil}
- if user_statistics[user.class.name][user.id] then us = user_statistics[user.class.name][user.id] else us = {"maximum_score" => nil, "runs" => nil}
- label = "#{user.displayname}"
tr
td = link_to_if symbol==:external_users && policy(user).statistics?, label, {controller: "exercises", action: "statistics", external_user_id: user.id, id: @exercise.id}
td = link_to_if symbol==:external_users && policy(user).statistics?, label, {controller: "exercises", action: "external_user_statistics", external_user_id: user.id, id: @exercise.id}
td = us['maximum_score'] or 0
td.align-middle
- latest_user_submission = submissions.where(user: user).final.latest
@@ -88,4 +88,4 @@ h1 = @exercise
- elsif latest_user_submission.after_late_deadline?
.unit-test-result.negative-result.after_late_deadline
td = us['runs'] if policy(@exercise).detailed_statistics?
td = @exercise.average_working_time_for(user.id) or 0 if policy(@exercise).detailed_statistics?
td = @exercise.average_working_time_for(user) or 0 if policy(@exercise).detailed_statistics?

View File

@@ -2,7 +2,7 @@
// 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_pack_tag('d3-tip', 'data-turbolinks-track': true)
- append_javascript_pack_tag('d3-tip')
h1
= t('.live_dashboard')
@@ -15,8 +15,8 @@ h4.mt-4
.d-none#initial_graph_data data-graph_data=ActiveSupport::JSON.encode(@graph_data);
div.w-100#chart_stacked
.d-none.badge-info.container.py-2#no_chart_data
i class="fa fa-info" aria-hidden="true"
.d-none.bg-info.container.py-2#no_chart_data
i class="fa-solid fa-info" aria-hidden="true"
= t('.no_data_yet')
h4.mt-4
@@ -27,9 +27,9 @@ h4.mt-4
thead
tr
th.text-center
i.mr-0 class="fa fa-lightbulb-o" aria-hidden="true" title = t('request_for_comments.solved')
i.me-0 class="fa-regular fa-lightbulb" aria-hidden="true" title = t('request_for_comments.solved')
th.text-center
i.mr-0 class="fa fa-comment" aria-hidden="true" title = t('request_for_comments.comments') align="center"
i.me-0 class="fa-solid fa-comment" aria-hidden="true" title = t('request_for_comments.comments') align="center"
th.col-12 = t('activerecord.attributes.request_for_comments.question')
th = t('activerecord.attributes.request_for_comments.username')
th.text-nowrap = t('activerecord.attributes.request_for_comments.requested_at')