Implement support for some basic embed options for work sheets via LTI

This commit also fixes an issue with the flash messages being positioned too high and displayed for too long
This commit is contained in:
Sebastian Serth
2018-12-10 16:53:43 +01:00
parent 4fd128b31b
commit a0d8b30ef2
25 changed files with 178 additions and 90 deletions

View File

@@ -1,19 +1,20 @@
- if current_user.try(:internal_user?)
ul.breadcrumb
- if model = Kernel.const_get(controller_path.classify) rescue nil
- object = model.find_by(id: params[:id])
- if model.try(:nested_resource?)
li.breadcrumb-item = model.model_name.human(count: 2)
- if object
li.breadcrumb-item = object
- else
li.breadcrumb-item = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
- if object
li.breadcrumb-item = link_to(object, send(:"#{model.model_name.singular}_path", object))
li.breadcrumb-item.active
- if I18n.translation_present?("shared.#{params[:action]}")
= t("shared.#{params[:action]}")
.container
ul.breadcrumb
- if model = Kernel.const_get(controller_path.classify) rescue nil
- object = model.find_by(id: params[:id])
- if model.try(:nested_resource?)
li.breadcrumb-item = model.model_name.human(count: 2)
- if object
li.breadcrumb-item = object
- else
= t("#{controller_name}.index.#{params[:action]}")
- else
li.breadcrumb-item.active = t("breadcrumbs.#{controller_name}.#{params[:action]}")
li.breadcrumb-item = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path"))
- if object
li.breadcrumb-item = link_to(object, send(:"#{model.model_name.singular}_path", object))
li.breadcrumb-item.active
- if I18n.translation_present?("shared.#{params[:action]}")
= t("shared.#{params[:action]}")
- else
= t("#{controller_name}.index.#{params[:action]}")
- else
li.breadcrumb-item.active = t("breadcrumbs.#{controller_name}.#{params[:action]}")

View File

@@ -1,4 +1,4 @@
#flash-container
#flash-container.container
#flash.container.fixed_error_messages data-message-failure=t('shared.message_failure')
- %w[alert danger info notice success warning].each do |severity|
div.alert.flash class="alert-#{{'alert' => 'warning', 'notice' => 'success'}.fetch(severity, severity)} alert-dismissible fade show"

View File

@@ -5,26 +5,29 @@
- show_rfc_interventions = @show_rfc_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-course_token=@course_token data-search-save-url=search_exercise_path(@exercise)
div id="sidebar" class=(@exercise.hide_file_tree ? 'sidebar-col-collapsed' : 'sidebar-col') = render('editor_file_tree', exercise: @exercise, files: @files)
- unless @embed_options[:hide_sidebar]
div id="sidebar" class=(@exercise.hide_file_tree ? 'sidebar-col-collapsed' : 'sidebar-col') = 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'))
= 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'))
= 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'))
= 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'))
= 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'))
= 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]
// todo: check this
- if not hide_rfc_button
- unless hide_rfc_button
= render('editor_button', icon: 'fa 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)
#autosave-label
= t('exercises.editor.lastsaved')
span
button style="display:none" id="autosave"
div id='output_sidebar' class='output-col-collapsed' = render('exercises/editor_output', external_user_id: external_user_id, consumer_id: consumer_id )
- unless @embed_options[:disable_run] && @embed_options[:disable_score]
div id='output_sidebar' class='output-col-collapsed' = render('exercises/editor_output', external_user_id: external_user_id, consumer_id: consumer_id )
= render('shared/modal', id: 'comment-modal', title: t('exercises.implement.comment.request'), template: 'exercises/_request_comment_dialogcontent')
= render('shared/modal', id: 'break-intervention-modal', title: t('exercises.implement.break_intervention.title'), template: 'interventions/_break_intervention_modal')
= 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]

View File

@@ -10,17 +10,18 @@ div.h-100 id='output_sidebar_uncollapsed' class='d-none col-sm-12 enforce-bottom
#results
h2 = t('exercises.implement.results')
p.test-count == t('exercises.implement.test_count', count: 0)
ul.list-unstyled
ul#dummies.d-none.list-unstyled
li.card.mt-2
.card-header.py-2
h5.card-title.m-0 == t('exercises.implement.file', filename: '', number: 0)
.card-body.bg-white.text-dark
= row(label: 'exercises.implement.passed_tests', value: t('shared.out_of', maximum_value: 0, value: 0).html_safe)
= row(label: 'activerecord.attributes.submission.score', value: t('shared.out_of', maximum_value: 0, value: 0).html_safe)
= row(label: 'exercises.implement.feedback')
= row(label: 'exercises.implement.error_messages')
/= row(label: 'exercises.implement.output', value: link_to(t('shared.show'), '#'))
- unless @embed_options[:hide_test_results]
ul.list-unstyled
ul#dummies.d-none.list-unstyled
li.card.mt-2
.card-header.py-2
h5.card-title.m-0 == t('exercises.implement.file', filename: '', number: 0)
.card-body.bg-white.text-dark
= row(label: 'exercises.implement.passed_tests', value: t('shared.out_of', maximum_value: 0, value: 0).html_safe)
= row(label: 'activerecord.attributes.submission.score', value: t('shared.out_of', maximum_value: 0, value: 0).html_safe)
= row(label: 'exercises.implement.feedback')
= row(label: 'exercises.implement.error_messages')
/= row(label: 'exercises.implement.output', value: link_to(t('shared.show'), '#'))
#score data-maximum-score=@exercise.maximum_score data-score=@submission.try(:score)
h4
span == "#{t('activerecord.attributes.submission.score')}: "
@@ -44,12 +45,13 @@ div.h-100 id='output_sidebar_uncollapsed' class='d-none col-sm-12 enforce-bottom
input#prompt-input.form-control type='text'
span.input-group-btn
button#prompt-submit.btn.btn-primary type="button" = t('exercises.editor.send')
#error-hints
.heading = t('exercises.implement.error_hints.heading')
ul.body
- 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]
- 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

View File

@@ -1,17 +1,18 @@
.row
#editor-column.col-md-12
.exercise.clearfix
div
span.badge.badge-pill.badge-primary.float-right.score
- unless @embed_options[:hide_exercise_description]
.exercise.clearfix
div
span.badge.badge-pill.badge-primary.float-right.score
h1 id="exercise-headline"
i class="fa fa-chevron-down" id="description-symbol"
= @exercise.title
h1 id="exercise-headline"
i class="fa fa-chevron-down" id="description-symbol"
= @exercise.title
#description-card.lead.description-card
= render_markdown(@exercise.description)
#description-card.lead.description-card
= render_markdown(@exercise.description)
a#toggle href="#" data-show=t('shared.show') data-hide=t('shared.hide') = t('shared.hide')
a#toggle href="#" data-show=t('shared.show') data-hide=t('shared.hide') = t('shared.hide')
#alert.alert.alert-danger role='alert'
h4 = t('.alert.title')

View File

@@ -13,22 +13,23 @@ html lang='en'
= yield(:head)
= csrf_meta_tags
body
nav.navbar.navbar-dark.bg-dark.navbar-expand-md.mb-4.py-1 role='navigation'
.container
.navbar-brand
i.fa.fa-code
= application_name
button.navbar-toggler data-target='#navbar-collapse' data-toggle='collapse' type='button' aria-expanded='false' aria-label='Toggle navigation'
span.navbar-toggler-icon
#navbar-collapse.collapse.navbar-collapse
= render('navigation', cached: true)
ul.nav.navbar-nav.ml-auto
= render('locale_selector', cached: true)
li.nav-item.mr-3 = link_to(t('shared.help.link'), '#modal-help', data: {toggle: 'modal'}, class: 'nav-link')
= render('session')
.container data-controller=controller_name
- unless @embed_options[:hide_navbar]
nav.navbar.navbar-dark.bg-dark.navbar-expand-md.mb-4.py-1 role='navigation'
.container
.navbar-brand
i.fa.fa-code
= application_name
button.navbar-toggler data-target='#navbar-collapse' data-toggle='collapse' type='button' aria-expanded='false' aria-label='Toggle navigation'
span.navbar-toggler-icon
#navbar-collapse.collapse.navbar-collapse
= render('navigation', cached: true)
ul.nav.navbar-nav.ml-auto
= render('locale_selector', cached: true)
li.nav-item.mr-3 = link_to(t('shared.help.link'), '#modal-help', data: {toggle: 'modal'}, class: 'nav-link')
= render('session')
div data-controller=controller_name
= render('flash')
= render('breadcrumbs') if current_user.try(:internal_user?)
= render('breadcrumbs') if current_user.try(:internal_user?) && !@embed_options[:hide_navbar]
- if (controller_name == "exercises" && action_name == "implement")
.container-fluid
= yield

View File

@@ -1,8 +1,8 @@
json.extract! @submission, :id, :files
json.download_url download_submission_path(@submission)
json.score_url score_submission_path(@submission)
json.stop_url stop_submission_path(@submission)
json.download_file_url download_file_submission_path(@submission, 'a.').gsub(/a\.$/, '{filename}')
json.render_url render_submission_path(@submission, 'a.').gsub(/a\.$/, '{filename}')
json.run_url run_submission_path(@submission, 'a.').gsub(/a\.$/, '{filename}')
json.test_url test_submission_path(@submission, 'a.').gsub(/a\.$/, '{filename}')
json.download_url download_submission_path(@submission, format: :json)
json.score_url score_submission_path(@submission, format: :json)
json.stop_url stop_submission_path(@submission, format: :json)
json.download_file_url download_file_submission_path(@submission, 'a.', format: :json).gsub(/a\.\.json$/, '{filename}.json')
json.render_url render_submission_path(@submission, 'a.', format: :json).gsub(/a\.\.json$/, '{filename}.json')
json.run_url run_submission_path(@submission, 'a.', format: :json).gsub(/a\.\.json$/, '{filename}.json')
json.test_url test_submission_path(@submission, 'a.', format: :json).gsub(/a\.\.json$/, '{filename}.json')