Lint Slim files and fix offenses

The fixing was partially done manually and partially automatically.
This commit is contained in:
Sebastian Serth
2024-04-13 20:06:03 +02:00
committed by Dominic Sauer
parent ddfa06ffaa
commit 9a9efd5caa
91 changed files with 378 additions and 392 deletions

View File

@@ -1,7 +1,7 @@
.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 }
= 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', 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

@@ -1,5 +1,5 @@
#otherComments
h5 =t('exercises.implement.comment.others')
h5 = t('exercises.implement.comment.others')
.container
label
@@ -7,6 +7,6 @@ label
= t('request_for_comments.subscribe_to_author')
#myComment.d-grid
h5 =t('exercises.implement.comment.addyours')
h5 = t('exercises.implement.comment.addyours')
textarea.form-control
button#addCommentButton.btn.btn-primary(type='button') =t('exercises.implement.comment.addCommentButton')
button#addCommentButton.btn.btn-primary(type='button') = t('exercises.implement.comment.addCommentButton')

View File

@@ -1,4 +1,4 @@
div.enforce-bottom-margin.overflow-scroll.d-none#download-files
.enforce-bottom-margin.overflow-scroll.d-none#download-files
.card.border-secondary
.card-header.d-flex.justify-content-between.align-items-center.px-0.py-1
.px-2 = t('exercises.download_file_tree.file_root')

View File

@@ -1,10 +1,10 @@
- external_user_external_id = current_user.respond_to?(:external_id) ? current_user.external_id : ''
- show_break_interventions = @show_break_interventions || "false"
- show_rfc_interventions = @show_rfc_interventions || "false"
- show_tips_interventions = @show_tips_interventions || "false"
- 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-message-out-of-memory=t('exercises.editor.out_of_memory', memory_limit: @exercise.execution_environment.memory_limit) data-submissions-url=submissions_path 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
#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-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
- unless @embed_options[:hide_sidebar]
- additional_classes = 'sidebar-col'
- if @tips.blank?
@@ -12,24 +12,23 @@
- additional_classes = 'sidebar-col-collapsed'
- else
- additional_classes = 'sidebar-col w-25'
div id="sidebar" class=additional_classes = render('editor_file_tree', exercise: @exercise, files: @files)
#sidebar class=additional_classes = render('editor_file_tree', exercise: @exercise, files: @files)
div.editor-col.col.p-0 id='frames'
.editor-col.col.p-0#frames
#editor-buttons.btn-group.enforce-bottom-margin
= 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]
span.flex-grow-1.d-inline-flex#run-stop-button-group data-bs-placement='top' data-bs-toggle='tooltip' data-bs-container='body' title=t('shared.tooltips.shortcut', shortcut: 'ALT + r')
= 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'),}, icon: 'fa-solid fa-play', id: 'run', label: t('exercises.editor.run'), classes: 'w-100 h-100 btn-primary') unless @embed_options[:disable_run]
= render('editor_button', icon: 'fa-solid fa-stop', id: 'stop', label: t('exercises.editor.stop'), classes: 'w-100 h-100 btn-primary') 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]
= 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')}, icon: 'fa-solid fa-play', id: 'run', label: t('exercises.editor.run'), classes: 'w-100 h-100 btn-primary') unless @embed_options[:disable_run]
= render('editor_button', icon: 'fa-solid fa-stop', id: 'stop', label: t('exercises.editor.stop'), classes: 'w-100 h-100 btn-primary') 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', data: {:'data-bs-placement' => 'top', :'data-bs-toggle' => 'tooltip', :'data-bs-container' => 'body'}, icon: 'fa-solid fa-comment', id: 'requestComments', label: t('exercises.editor.requestComments'), title: t('exercises.editor.requestCommentsTooltip'))
= render('editor_button', data: {'data-bs-placement': 'top', 'data-bs-toggle': 'tooltip', 'data-bs-container': 'body'}, 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]
= render('editor_frame', exercise: exercise, file: file)
= render('editor_frame', exercise:, file:)
#statusbar.d-flex.justify-content-between
div
@@ -50,11 +49,11 @@
- if current_contributor.programming_group?
span#pg_session
= t('exercises.editor.is_offline', name: @programming_partners_name)
= " | "
= ' | '
= t('exercises.editor.lastsaved')
span id="autosave"
span#autosave
= " | "
= ' | '
button#start-over-active-file.p-0.border-0.btn-link.bg-body.text-primary data-message-confirm=t('exercises.editor.confirm_start_over_active_file') data-url=reload_exercise_path(@exercise)
i.fa-solid.fa-circle-notch.fa-spin.d-none
@@ -62,9 +61,8 @@
= t('exercises.editor.start_over_active_file')
- unless @embed_options[:disable_run] && @embed_options[:disable_score]
div id='output_sidebar' class='output-col-collapsed' = render('exercises/editor_output')
.output-col-collapsed#output_sidebar = render('exercises/editor_output')
= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent') unless @embed_options[:disable_rfc]
= render('shared/modal', id: 'break-intervention-modal', title: t('exercises.implement.break_intervention.title'), template: 'interventions/_break_intervention_modal') unless @embed_options[:disable_interventions]
= render('shared/modal', id: 'tips-intervention-modal', title: t('exercises.implement.tips.heading'), template: 'interventions/_tips_intervention_modal') unless @embed_options[:disable_hints] or @tips.blank?
= render('shared/modal', id: 'tips-intervention-modal', title: t('exercises.implement.tips.heading'), template: 'interventions/_tips_intervention_modal') unless @embed_options[:disable_hints] || @tips.blank?

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-solid.fa-circle-notch.fa-spin.d-none 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

@@ -2,4 +2,4 @@
#frames
.edit-frame
.editor-content.d-none
.editor.allow_ace_tooltip
.editor.allow_ace_tooltip

View File

@@ -1,24 +1,24 @@
div.d-grid.gap-2 id='sidebar-collapsed' class=(@exercise.hide_file_tree && @tips.blank? ? '' : 'd-none')
= render('editor_button', classes: 'btn-outline-contrast', 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'))
.d-grid.gap-2#sidebar-collapsed class=(@exercise.hide_file_tree && @tips.blank? ? '' : 'd-none')
= render('editor_button', classes: 'btn-outline-contrast', 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-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'))
- unless @embed_options[:disable_hints] || @tips.blank?
= 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'))
div.d-grid.enforce-bottom-margin id='sidebar-uncollapsed' class=(@exercise.hide_file_tree && @tips.blank? ? 'd-none' : '')
.d-grid.enforce-bottom-margin#sidebar-uncollapsed class=(@exercise.hide_file_tree && @tips.blank? ? 'd-none' : '')
= render('editor_button', classes: 'btn-outline-contrast 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
.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' }, icon: 'fa-regular fa-trash-can', id: 'destroy-file', label: '', title: t('exercises.editor.destroy_file'))
= 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'}, 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'))
= 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'))
.card-body.pt-0.pe-0.ps-1.pb-1
@@ -26,7 +26,7 @@ div.d-grid.enforce-bottom-margin id='sidebar-uncollapsed' class=(@exercise.hide_
hr
- unless @embed_options[:disable_hints] or @tips.blank?
- unless @embed_options[:disable_hints] || @tips.blank?
= render(partial: 'tips_content')
- if @exercise.allow_file_creation?

View File

@@ -1,4 +1,4 @@
div class=(defined?(own_solution) ? "own-frame" : "frame") data-executable=file.file_type.executable? data-filename=file.filepath data-renderable=file.file_type.renderable? data-role=file.role data-binary=file.file_type.binary? data-read-only=file.read_only
div class=(defined?(own_solution) ? 'own-frame' : 'frame') data-executable=file.file_type.executable? data-filename=file.filepath data-renderable=file.file_type.renderable? data-role=file.role data-binary=file.file_type.binary? data-read-only=file.read_only
- if file.file_type.binary?
- file_path = protected_upload_path(id: file.id, filename: file.filepath)
.binary-file data-file-id=file.ancestor_id
@@ -13,4 +13,4 @@ div class=(defined?(own_solution) ? "own-frame" : "frame") data-executable=file.
= link_to(file.native_file.file.filename, file_path)
- else
.editor-content.d-none data-file-id=file.ancestor_id = file.content
div class=(defined?(own_solution) ? "own-editor" : "editor") data-file-id=file.ancestor_id data-indent-size=file.file_type.indent_size data-mode=file.file_type.editor_mode data-allow-auto-completion=exercise.allow_auto_completion.to_s data-id=file.id
div class=(defined?(own_solution) ? 'own-editor' : 'editor') data-file-id=file.ancestor_id data-indent-size=file.file_type.indent_size data-mode=file.file_type.editor_mode data-allow-auto-completion=exercise.allow_auto_completion.to_s data-id=file.id

View File

@@ -1,13 +1,12 @@
div.d-grid id='output_sidebar_collapsed'
= render('editor_button', classes: 'btn-outline-contrast 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')
.d-grid#output_sidebar_collapsed
= render('editor_button', classes: 'btn-outline-contrast 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: '')
.d-grid.d-none.col-sm-12.enforce-bottom-margin#output_sidebar_uncollapsed data-message-no-output=t('exercises.implement.no_output_yet')
= render('editor_button', classes: 'btn-outline-contrast btn overflow-hidden mb-2', icon: 'fa-solid fa-square-minus', id: 'toggle-sidebar-output', label: t('exercises.editor.collapse_output_sidebar'))
#content-right-sidebar.overflow-scroll
= render('download_file_tree')
div.enforce-bottom-margin.overflow-auto.d-none id='score_div'
.enforce-bottom-margin.overflow-auto.d-none#score_div
#results
h2 = t('exercises.implement.results')
p.test-count == t('exercises.implement.test_count', count: 0)
@@ -67,12 +66,12 @@ div.d-grid id='output_sidebar_uncollapsed' class='d-none col-sm-12 enforce-botto
hr
#turtlediv.enforce-big-bottom-margin.overflow-auto.d-none
canvas#turtlecanvas width=400 height=400
div.enforce-big-bottom-margin.overflow-auto
.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')
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')

View File

@@ -2,12 +2,10 @@
= 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 !uuid_found || update_right
= 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')
- elsif !exported && (!uuid_found || update_right)
= 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 float-end export-button', data: {bs_dismiss: 'modal'} do
i.fa-solid.fa-xmark.abort-icon

View File

@@ -1,14 +1,14 @@
- id = f.object.id
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-bs-toggle="collapse" href="#collapse#{f.index}" aria-expanded="#{aria_expanded}"
div.clearfix role="button"
i.fa-solid aria-hidden="true"
.card-header#heading role='tab'
- collapsed_class = f.index == 'index' ? nil : 'collapsed'
- aria_expanded = f.index == 'index' ? 'true' : 'false'
a class=['file-heading', collapsed_class] data-bs-toggle='collapse' href="#collapse#{f.index}" aria-expanded=aria_expanded
.clearfix role='button'
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-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
@@ -25,7 +25,7 @@ li.card.mt-2
= f.collection_select(:file_type_id, @file_types, :id, :name, {}, class: 'form-control')
.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')
= f.select(:role, CodeOcean::File::TEACHER_DEFINED_ROLES.map {|role| [t("files.roles.#{role}"), role] }, {}, class: 'form-control')
.form-check
label.form-check-label
= f.check_box(:hidden, class: 'form-check-input')

View File

@@ -4,10 +4,10 @@
meta name='turbolinks-visit-control' content='reload'
- 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)
- execution_environments = ExecutionEnvironment.where.not(file_type_id: nil).select(:file_type_id, :id)
- file_types = FileType.where.not(file_extension: nil).select(:file_extension, :id)
= form_for(@exercise, data: {execution_environments: execution_environments, file_types: file_types}, multipart: true, builder: PagedownFormBuilder) do |f|
= form_for(@exercise, data: {execution_environments:, file_types:}, multipart: true, builder: PagedownFormBuilder) do |f|
= render('shared/form_errors', object: @exercise)
.mb-3
= f.label(:title, class: 'form-label')
@@ -18,7 +18,7 @@
.help-block.form-text == t('.hints.internal_title')
.mb-3
= f.label(:description, class: 'form-label')
= f.pagedown :description, input_html: { preview: true, rows: 10 }
= f.pagedown :description, input_html: {preview: true, rows: 10}
.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')
@@ -63,11 +63,11 @@
h2 = t('exercises.form.tags')
ul.list-unstyled.card-group
li.card
.card-header role="tab" id="heading"
a.file-heading data-bs-toggle="collapse" href="#tag-collapse"
div.clearfix role="button"
.card-header#heading role='tab'
a.file-heading data-bs-toggle='collapse' href='#tag-collapse'
.clearfix role='button'
span = t('exercises.form.click_to_collapse')
.card-collapse.collapse id="tag-collapse" role="tabpanel"
.card-collapse.collapse#tag-collapse role='tabpanel'
.table-responsive
table.table#tags-table
thead
@@ -79,17 +79,17 @@
tr
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 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-bs-toggle="collapse" href="#tip-collapse"
div.clearfix role="button"
.card-header#tip-heading role='tab'
a.file-heading data-bs-toggle='collapse' href='#tip-collapse'
.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: "")
.card-collapse.collapse.mx-2#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-bs-toggle='modal' data-bs-target='#add-tips-modal' = t('.add_tips')
@@ -103,6 +103,6 @@
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)
.actions = render('shared/submit_button', f:, object: @exercise)
= render('shared/modal', id: 'add-tips-modal', title: t('.add_tips'), template: 'exercises/_add_tip_modal')

View File

@@ -1,7 +1,6 @@
#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; height: 15vh;')
p = ''
/ data-cause='requestComments' is not used here right now, we pass the button #requestComments (not askForCommentsButton) as initiator of the action.
@@ -9,5 +8,5 @@ p = ''
.d-grid.gap-2
button#askForCommentsButton.btn.btn-primary(type='button' data-cause='requestComments' data-message-success=t('exercises.editor.request_for_comments_sent'))
i.fa-solid.fa-circle-notch.fa-spin.d-none
=t('exercises.implement.comment.request')
button#closeAskForCommentsButton.btn.btn-warning(type='button') =t('activerecord.attributes.request_for_comments.close')
= t('exercises.implement.comment.request')
button#closeAskForCommentsButton.btn.btn-warning(type='button') = t('activerecord.attributes.request_for_comments.close')

View File

@@ -5,9 +5,9 @@
- append_javascript_pack_tag('highlight')
- append_stylesheet_pack_tag('highlight')
#tips.card.d-block.overflow-scroll role="tab"
#tips.card.d-block.overflow-scroll role='tab'
.card-header.py-2
i.fa-solid.fa-lightbulb
= t('exercises.implement.tips.heading')
.card-body.p-2
= render(partial: 'tips/collapsed_card', collection: @tips, as: :exercise_tip, locals: { tip_prefix: '' })
= render(partial: 'tips/collapsed_card', collection: @tips, as: :exercise_tip, locals: {tip_prefix: ''})

View File

@@ -3,19 +3,17 @@ h1
' (external user
= link_to_if(policy(@external_user).show?, @external_user.displayname, @external_user)
' )
- submissions = @all_events.filter{|event| event.is_a? Submission}
- 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()
- file_types = Set.new
- submissions.each do |submission|
- submission.files.each do |file|
- file_types.add(ActiveSupport::JSON.encode(file.file_type))
- all_files.push(submission.files)
- all_files.reject!(&:blank?)
- file_types.reject!(&:blank?)
- all_files.compact_blank!
- file_types.reject!(&:blank?) # rubocop:disable Rails/CompactBlank because it's a set
.d-none#data data-submissions=ActiveSupport::JSON.encode(submissions) data-files=ActiveSupport::JSON.encode(all_files) data-file-types=ActiveSupport::JSON.encode(file_types)
@@ -28,16 +26,16 @@ h1
#current-file.editor
.flex-container
button.btn.btn-secondary id='play-button'
button.btn.btn-secondary#play-button
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%"
input.w-100 type='range' orient='horizontal' list='datapoints' value=0 min=0 max=all_files.length - 1
datalist#datapoints
- index=0
- index = 0
- submissions.each do |submission|
- next if submission.files.blank?
option data-submission=submission
=index
= index
- index += 1
- if policy(@exercise).detailed_statistics?
.bg-body-secondary.w-100.p-2.mb-4.align-items-center.d-flex.justify-content-between
@@ -45,12 +43,12 @@ h1
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-contrast float-end btn-sm"
= link_to t('.toggle_autosave_off'), statistics_external_user_exercise_path(show_autosaves: false), class: 'btn btn-outline-contrast 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-contrast float-end btn-sm"
= link_to t('.toggle_autosave_on'), statistics_external_user_exercise_path(show_autosaves: true), class: 'btn btn-outline-contrast float-end btn-sm'
#timeline
.table-responsive
table.table
@@ -62,8 +60,8 @@ h1
th.header = t('.tests')
th.header = t('.time_difference') if policy(@exercise).detailed_statistics?
tbody
- @all_events.each_with_index do |this, index|
- highlight = (index > 0 and @deltas.present? and @deltas[index] == 0 and this.created_at.to_s != @all_events[index - 1].created_at.to_s)
- @all_events.each_with_index do |this, event_index|
- highlight = event_index.positive? && @deltas.present? && @deltas[event_index].zero? && this.created_at.to_s != @all_events[event_index - 1].created_at.to_s
- row_classes = ''
- row_classes += ' highlight' if highlight
- row_classes += ' before_deadline' if this.is_a?(Submission) && this.before_deadline?
@@ -72,22 +70,22 @@ h1
tr data-id=this.id class=row_classes
- if this.is_a?(Submission)
td class=(this.files.present? ? 'clickable' : '')
= this.created_at.strftime("%F %T")
= this.created_at.strftime('%F %T')
td = this.cause
td = this.score
td.align-middle
-this.testruns.sort_by {|t| [t.file&.name ? 0 : 1, t.file&.name]}.each do |run|
-this.testruns.sort_by {|t| [t.file&.name ? 0 : 1, t.file&.name] }.each do |run|
- if run.passed
.unit-test-result.positive-result title=[run.file&.filepath, run.log].join("\n").strip
- else
.unit-test-result.unknown-result title=[run.file&.filepath, run.log].join("\n").strip
td = @working_times_until[index] if index > 0 if policy(@exercise).detailed_statistics?
td = @working_times_until[event_index] if event_index.positive? && policy(@exercise).detailed_statistics?
- elsif this.is_a? UserExerciseIntervention
td = this.created_at.strftime("%F %T")
td = this.created_at.strftime('%F %T')
td = this.intervention.name
td =
td =
td = @working_times_until[index] if index > 0 if policy(@exercise).detailed_statistics?
td
td
td = @working_times_until[event_index] if event_index.positive? && policy(@exercise).detailed_statistics?
small
b
= t('.legend')
@@ -105,8 +103,8 @@ h1
p.mt-2 = t('.filter')
- if current_user.try(:admin?)
p = t('.addendum', delta: StatisticsHelper::WORKING_TIME_DELTA_IN_SECONDS / 60)
.d-none#wtimes data-working_times=ActiveSupport::JSON.encode(@working_times_until);
div#progress_chart.col-lg-12
.d-none#wtimes data-working_times=ActiveSupport::JSON.encode(@working_times_until)
#progress_chart.col-lg-12
.graph-functions-2
- else

View File

@@ -8,7 +8,7 @@ h1 = link_to_if(policy(@exercise).show?, @exercise, exercise_path(@exercise))
span.col-sm-9 =< @exercise.maximum_score
.header.mt-3 = t('activerecord.models.user_exercise_feedback.other')
- if @feedbacks.nil? or @feedbacks.size == 0
- if @feedbacks.blank?
.no-feedback = t('user_exercise_feedback.no_feedback')
ul.list-unstyled
@@ -16,22 +16,22 @@ h1 = link_to_if(policy(@exercise).show?, @exercise, exercise_path(@exercise))
- time_presets = UserExerciseFeedbacksController.new.time_presets
- @feedbacks.each_with_index do |feedback, index|
li.card.mt-2
.card-header role="tab" id="heading"
div.clearfix.feedback-header
.card-header#heading role='tab'
.clearfix.feedback-header
- 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-regular fa-envelope" data-bs-placement="top" data-bs-toggle="tooltip" data-bs-container="body" title=feedback.anomaly_notification.reason
i.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-collapse role='tabpanel'
.card-body.feedback
.text style="white-space: pre-wrap;" = feedback.feedback_text
.difficulty = "#{t('user_exercise_feedback.difficulty')} #{comment_presets[feedback.difficulty].join(' - ')}" if feedback.difficulty
.worktime = "#{t('user_exercise_feedback.working_time')} #{time_presets[feedback.user_estimated_worktime].join(' - ')}" if feedback.user_estimated_worktime
- if policy(@exercise).detailed_statistics?
.card-footer
div.clearfix.feedback-header
.clearfix.feedback-header
span.points.flex-grow-1 = "#{t('exercises.statistics.score')}: #{@submissions[index].score}"
span.working_time.float-end = "#{t('exercises.statistics.worktime')}: #{@exercise.average_working_time_for(feedback.user) or 0}"
span.working_time.float-end = "#{t('exercises.statistics.worktime')}: #{@exercise.average_working_time_for(feedback.user) || 0}"
= render('shared/pagination', collection: @feedbacks)

View File

@@ -1,25 +1,25 @@
- content_for :head do
// Force a full page reload, see https://github.com/turbolinks/turbolinks/issues/326.
Otherwise, lti_parameters might be nil
meta name="turbolinks-cache-control" content="no-cache"
meta name='turbolinks-cache-control' content='no-cache'
#editor-column
- unless @embed_options[:hide_exercise_description]
.exercise.clearfix
div.col-9div.d-lg-flex.flex-row.justify-content-between.align-items-baseline
div.col-lg-7
h1 id="exercise-headline"
i id="description-symbol" class=(@embed_options[:collapse_exercise_description] ? 'fa-solid fa-chevron-right' : 'fa-solid fa-chevron-down')
.col-9.d-lg-flex.flex-row.justify-content-between.align-items-baseline
.col-lg-7
h1#exercise-headline
i#description-symbol class=(@embed_options[:collapse_exercise_description] ? 'fa-solid fa-chevron-right' : 'fa-solid fa-chevron-down')
= @exercise.title
div.col-lg-5.float-lg-end.ms-md-3.mb-md-3.d-flex.justify-content-end.pe-lg-3
.col-lg-5.float-lg-end.ms-md-3.mb-md-3.d-flex.justify-content-end.pe-lg-3
- if current_contributor.programming_group?
span.me-3.mt-1
button.btn.btn-sm.btn-primary.text-nowrap.w-100#start_chat data= { url: "https://jitsi.fem.tu-ilmenau.de/openHPI_ProgrammingGroup#{current_contributor.id}" }
button.btn.btn-sm.btn-primary.text-nowrap.w-100#start_chat data= {url: "https://jitsi.fem.tu-ilmenau.de/openHPI_ProgrammingGroup#{current_contributor.id}"}
i.fa-solid.fa-video
= t('exercises.editor.start_video')
div.small.text-body-tertiary.text-nowrap.mt-1
.small.text-body-tertiary.text-nowrap.mt-1
a href='https://www.tu-ilmenau.de/datenschutz' target='_blank' rel='noopener'
= t('exercises.implement.external_privacy_policy')
@@ -30,13 +30,13 @@
span.badge.rounded-pill.bg-primary.float-end.mt-2.mb-5.score
- if !current_contributor.programming_group?
- unless current_contributor.programming_group?
span.badge.rounded-pill.bg-primary.float-end.mt-2.score
#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')
a#toggle href='#' data-show=t('shared.show') data-hide=t('shared.hide')
- if @embed_options[:collapse_exercise_description]
= t('shared.show')
- else

View File

@@ -22,38 +22,38 @@ h1 = Exercise.model_name.human(count: 2)
= 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')))
span.batch = link_to(t('shared.batch_update'), '#', 'data-text': t('shared.update', model: t('activerecord.models.exercise.other')))
th.p-1 colspan=6 = t('shared.actions')
tbody
- @exercises.each do |exercise|
tr data-id=exercise.id
td.p-1.pt-2
= link_to_if(policy(exercise).show?, exercise.title, exercise, 'data-turbolinks' => "false")
= link_to_if(policy(exercise).show?, exercise.title, exercise, 'data-turbolinks': 'false')
- if exercise.internal_title.present?
p.mb-0.text-muted
i.fa-solid.fa-arrow-turn-up.fa-rotate-90
span = exercise.internal_title
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.filter(&:teacher_defined_assessment?).length
td.p-1.pt-2 = exercise.files.count(&:teacher_defined_assessment?)
td.p-1.pt-2 = exercise.maximum_score
td.p-1.pt-2 = exercise.exercise_tags.length
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.p-1.pt-2 = link_to(t('shared.statistics'), statistics_exercise_path(exercise), 'data-turbolinks': 'false') if policy(exercise).statistics?
td.p-1
.btn-group
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?
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'), exercise_request_for_comments_path(exercise), class: 'dropdown-item') if policy(exercise).rfcs_for_exercise?
li = link_to(t('activerecord.models.programming_group.other'), exercise_programming_groups_path(exercise), class: 'dropdown-item') if policy(exercise).programming_groups_for_exercise?
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?
li = link_to(t('exercises.export_codeharbor.label'), '', class: 'dropdown-item export-start', data: {'exercise-id' => exercise.id}) if policy(exercise).export_external_confirm?
li = link_to(t('exercises.export_codeharbor.label'), '', class: 'dropdown-item export-start', data: {'exercise-id': exercise.id}) if policy(exercise).export_external_confirm?
= render('shared/pagination', collection: @exercises)
p = render('shared/new_button', model: Exercise)

View File

@@ -15,14 +15,14 @@ h1.d-inline-block
= render('shared/edit_button', object: @exercise)
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') if policy(@exercise).implement?
li = link_to(t('shared.statistics'), statistics_exercise_path(@exercise), 'data-turbolinks' => "false", class: 'dropdown-item') if policy(@exercise).statistics?
li = link_to(t('exercises.index.implement'), implement_exercise_path(@exercise), 'data-turbolinks': 'false', class: 'dropdown-item') if policy(@exercise).implement?
li = link_to(t('shared.statistics'), statistics_exercise_path(@exercise), 'data-turbolinks': 'false', class: 'dropdown-item') if policy(@exercise).statistics?
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'), exercise_request_for_comments_path(@exercise), class: 'dropdown-item') if policy(@exercise).rfcs_for_exercise?
li = link_to(t('activerecord.models.programming_group.other'), exercise_programming_groups_path(@exercise), class: 'dropdown-item') if policy(@exercise).programming_groups_for_exercise?
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('exercises.index.clone'), clone_exercise_path(@exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post, class: 'dropdown-item') if policy(@exercise).clone?
li = link_to(t('exercises.export_codeharbor.label'), '', class: 'dropdown-item export-start', data: {'exercise-id' => @exercise.id}) if policy(@exercise).export_external_confirm?
li = link_to(t('exercises.export_codeharbor.label'), '', class: 'dropdown-item export-start', data: {'exercise-id': @exercise.id}) if policy(@exercise).export_external_confirm?
= row(label: 'exercise.title', value: @exercise.title)
= row(label: 'exercise.internal_title', value: @exercise.internal_title)
@@ -40,11 +40,11 @@ h1.d-inline-block
= row(label: 'exercise.allow_auto_completion', value: @exercise.allow_auto_completion?)
= row(label: 'exercise.difficulty', value: @exercise.expected_difficulty)
= 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.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 bg-body-secondary mb-4', readonly: true, value: @exercise.unpublished? ? t('exercises.show.is_unpublished') : embedding_parameters(@exercise))
- unless @tips.blank?
- if @tips.present?
.mt-2
= render(partial: 'tips_content')
@@ -53,15 +53,15 @@ h2.mt-4 = t('activerecord.attributes.exercise.files')
ul.list-unstyled#files
- @exercise.files.each do |file|
li.card.mt-2
.card-header role="tab" id="heading"
a.file-heading.collapsed data-bs-toggle="collapse" data-bs-parent="#files" href=".collapse#{file.id}"
div.clearfix role="button"
i.fa-solid aria-hidden="true"
.card-header#heading role='tab'
a.file-heading.collapsed data-bs-toggle='collapse' data-bs-parent='#files' href=".collapse#{file.id}"
.clearfix role='button'
i.fa-solid aria-hidden='true'
span = file.filepath
.card-collapse.collapse class="collapse#{file.id}" role="tabpanel"
.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-end', data: {confirm: t('shared.confirm_destroy')}, method: :delete)
= render('shared/file', file: file)
.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:)
= render('shared/modal', id: 'export-modal', title: t('exercises.export_codeharbor.dialogtitle'), template: 'exercises/_export_dialogcontent')

View File

@@ -7,7 +7,7 @@ h1 = @exercise
= row(label: '.participants', value: @exercise.contributors.size)
- [:intermediate, :final].each do |scope|
- %i[intermediate final].each do |scope|
= row(label: ".#{scope}_submissions") do
/TODO: Refactor next line
= "#{@exercise.submissions.send(scope).count} (#{t('.users_and_programming_groups', count: Submission.from(@exercise.submissions.send(scope).group(:contributor_id, :contributor_type).select(:contributor_id, :contributor_type)).count)})"
@@ -24,7 +24,7 @@ h1 = @exercise
- else
= empty
- finishers_count = @exercise.contributors.size
- finishers_percentage = finishers_count == 0 ? 0 : (100.0 / finishers_count * @exercise.finishers_count).round(2)
- finishers_percentage = finishers_count.zero? ? 0 : (100.0 / finishers_count * @exercise.finishers_count).round(2)
p = progress_bar(finishers_percentage)
= row(label: '.average_score') do
@@ -43,27 +43,27 @@ h1 = @exercise
= row(label: '.average_worktime') do
p = @exercise.average_working_time
- Hash[:internal_users => t('.internal_users'), :external_users => t('.external_users'), :programming_groups => t('.programming_groups')].each_pair do |symbol, label|
- {internal_users: t('.internal_users'), external_users: t('.external_users'), programming_groups: t('.programming_groups')}.each_pair do |symbol, label|
- submissions = Submission.where(contributor: @exercise.send(symbol), exercise: @exercise).in_study_group_of(current_user)
- if !policy(@exercise).detailed_statistics?
- unless policy(@exercise).detailed_statistics?
- submissions = submissions.final
- if submissions.any?
strong = label
- if symbol==:external_users
- if symbol == :external_users
- working_time_array = []
- @exercise.send(symbol).distinct().each do |user|
- working_time = @exercise.average_working_time_for(user) or 0
- @exercise.send(symbol).distinct.each do |user|
- working_time = @exercise.average_working_time_for(user) || 0
- working_time_array.push working_time
hr
.d-none#data data-working-time=ActiveSupport::JSON.encode(working_time_array)
.working-time-graphs
div#chart_1
#chart_1
hr
div#chart_2
#chart_2
hr
- contributors = symbol.to_s.classify.constantize.where(id: submissions.joins(symbol).group(:contributor_id).select(:contributor_id).distinct)
.table-responsive.mb-4
table.table.table-striped class="#{contributors.present? ? 'sortable' : ''}"
table.table.table-striped class=(contributors.present? ? 'sortable' : '')
thead
tr
th.header = t('.user')
@@ -73,11 +73,11 @@ h1 = @exercise
th.header = t('.worktime') if policy(@exercise).detailed_statistics?
tbody
- contributors.each do |contributor|
- if contributor_statistics[contributor.class.name][contributor.id] then us = contributor_statistics[contributor.class.name][contributor.id] else us = {"maximum_score" => nil, "runs" => nil}
- label = "#{contributor.displayname}"
- us = contributor_statistics[contributor.class.name][contributor.id] || {'maximum_score' => nil, 'runs' => nil}
- label = contributor.displayname.to_s
tr
td = link_to_if symbol==:external_users && policy(contributor).statistics?, label, {controller: "exercises", action: "external_user_statistics", external_user_id: contributor.id, id: @exercise.id}
td = us['maximum_score'] or 0
td = link_to_if symbol == :external_users && policy(contributor).statistics?, label, {controller: 'exercises', action: 'external_user_statistics', external_user_id: contributor.id, id: @exercise.id}
td = us['maximum_score'] || 0
td.align-middle
- latest_user_submission = submissions.where(contributor:).final.latest
- if latest_user_submission.present?
@@ -88,4 +88,4 @@ h1 = @exercise
- elsif latest_user_submission.after_late_deadline?
.unit-test-result.negative-result
td = us['runs'] if policy(@exercise).detailed_statistics?
td = @exercise.average_working_time_for(contributor) or 0 if policy(@exercise).detailed_statistics?
td = @exercise.average_working_time_for(contributor) || 0 if policy(@exercise).detailed_statistics?

View File

@@ -7,16 +7,16 @@
h1
= t('.live_dashboard')
div.teacher_dashboard data-exercise-id=@exercise.id.to_s data-study-group-id=@study_group_id.to_s
.teacher_dashboard data-exercise-id=@exercise.id.to_s data-study-group-id=@study_group_id.to_s
h4.mt-4
= t('.time_spent_per_learner')
.d-none#initial_graph_data data-graph_data=ActiveSupport::JSON.encode(@graph_data);
div.w-100#chart_stacked
.d-none#initial_graph_data data-graph_data=ActiveSupport::JSON.encode(@graph_data)
.w-100#chart_stacked
.d-none.bg-info.container.py-2#no_chart_data
i class="fa-solid fa-info" aria-hidden="true"
i.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.me-0 class="fa-regular fa-lightbulb" aria-hidden="true" title = t('request_for_comments.solved')
i.me-0.fa-regular.fa-lightbulb aria-hidden='true' title = t('request_for_comments.solved')
th.text-center
i.me-0 class="fa-solid fa-comment" aria-hidden="true" title = t('request_for_comments.comments') align="center"
i.me-0.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')