diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 286af9a0..28e44ba6 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2020-02-19 12:47:00 -0700 using RuboCop version 0.79.0. +# on 2020-03-04 11:06:04 -0700 using RuboCop version 0.79.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -9,11 +9,21 @@ # Offense count: 1 Naming/AccessorMethodName: Exclude: - - "app/policies/organization_policy.rb" + - 'app/policies/organization_policy.rb' # Offense count: 1 # Configuration parameters: Include. # Include: **/Rakefile, **/*.rake Rails/RakeEnvironment: Exclude: - - "lib/capistrano/tasks/*" + - 'lib/capistrano/tasks/set_rollbar.rake' + +# Offense count: 1 +Style/MethodMissingSuper: + Exclude: + - 'spec/support/views/pundit_view_policy.rb' + +# Offense count: 1 +Style/MissingRespondToMissing: + Exclude: + - 'spec/support/views/pundit_view_policy.rb' diff --git a/app/assets/javascripts/admin/courses.js b/app/assets/javascripts/admin/courses.js index e59b9d1e..10826a98 100644 --- a/app/assets/javascripts/admin/courses.js +++ b/app/assets/javascripts/admin/courses.js @@ -15,14 +15,17 @@ $(document).ready(function() { return false; }); - // If the user enters text in the topics textbox, mark the checkbox too. - $("body").on("change", "#course_other_topic_text", function() { - if ( - $(this) - .val() - .trim() !== "" - ) { - $("#course_other_topic").prop("checked", true); + // Only show other topic input if box is checked + $("#course_other_topic").on("change", function() { + if ($("#course_other_topic").prop("checked")) { + $(".topic-box") + .show() + .prop("required", true); + } else { + $(".topic-box") + .val("") + .hide() + .prop("required", false); } }); diff --git a/app/assets/javascripts/lessons.js b/app/assets/javascripts/lessons.js index b62deb60..0a12a18c 100644 --- a/app/assets/javascripts/lessons.js +++ b/app/assets/javascripts/lessons.js @@ -3,8 +3,15 @@ $(document).ready(function() { // match the event from the ASL file: // window.parent.sendLessonCompletedEvent(); sendLessonCompletedEvent = function() { + var preview = getUrlParameter("preview"); + var requestUrl = window.location.pathname + "/complete"; + + if (preview == "true") { + requestUrl = requestUrl + "?preview=true"; + } + $.ajax({ - url: window.location.pathname + "/complete", + url: requestUrl, type: "POST", dataType: "json" }).always(function(data) { @@ -14,6 +21,15 @@ $(document).ready(function() { }); }; + getUrlParameter = function(name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + var results = regex.exec(location.search); + return results === null + ? "" + : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + getDLCTransition = function(_) { sendLessonCompletedEvent(); }; diff --git a/app/assets/stylesheets/components/_course_form.scss b/app/assets/stylesheets/components/_course_form.scss index 5826bfc6..3c01fe06 100644 --- a/app/assets/stylesheets/components/_course_form.scss +++ b/app/assets/stylesheets/components/_course_form.scss @@ -1,8 +1,10 @@ .course-form { + margin-top: 2em; display: grid; grid-template-columns: minmax(0, 50%) minmax(0, 50%); grid-gap: 2em; grid-template-areas: + "errors errors" "title title" "author author" "summary summary" @@ -12,13 +14,36 @@ "additional_content additional_content" "topics categories" "language format" - "course_level pub_status" - "access_level ." + "course_level access_level" "seo_title seo_title" "seo_meta seo_meta" - "propagation propagation" + "pub_status ." "actions actions"; + &.restricted { + grid-template-areas: + "errors errors" + "categories access_level" + "resources resources" + "additional_content additional_content" + "pub_status ." + "actions actions" + "title title" + "author author" + "summary summary" + "description description" + "text_copies text_copies" + "topics ." + "language format" + "course_level ." + "seo_title seo_title" + "seo_meta seo_meta"; + } + + .error_explanation { + grid-area: errors; + } + .title { grid-area: title; } @@ -91,6 +116,10 @@ grid-area: seo_meta; } + .pub-status { + grid-area: pub_status; + } + .propagation { grid-area: propagation; } @@ -98,6 +127,15 @@ .actions { grid-area: actions; } + + .imported-course-actions { + border-bottom: 1px solid $grey; + + p { + margin-block-start: 2em; + margin-block-end: 0; + } + } } .attachment-upload-fields { diff --git a/app/assets/stylesheets/components/_lesson.scss b/app/assets/stylesheets/components/_lesson.scss index 3a923207..44336754 100644 --- a/app/assets/stylesheets/components/_lesson.scss +++ b/app/assets/stylesheets/components/_lesson.scss @@ -1,4 +1,6 @@ .story_line { - width: 1024px; - height: 716px; + width: 100%; + height: 80vw; + max-height: 820px; + border: none; } diff --git a/app/assets/stylesheets/components/_preview_notice.scss b/app/assets/stylesheets/components/_preview_notice.scss new file mode 100644 index 00000000..4fa3da0e --- /dev/null +++ b/app/assets/stylesheets/components/_preview_notice.scss @@ -0,0 +1,8 @@ +.preview-notice { + padding: 1em 0; + background-color: lightgoldenrodyellow; + + a { + padding: 0 1em; + } +} diff --git a/app/assets/stylesheets/components/_sortable_list.scss b/app/assets/stylesheets/components/_sortable_list.scss index 7b50ffc5..7174257d 100644 --- a/app/assets/stylesheets/components/_sortable_list.scss +++ b/app/assets/stylesheets/components/_sortable_list.scss @@ -5,6 +5,8 @@ .list-titles { font-size: 1em; font-weight: 400; + display: table; + width: 100%; } .table-row { diff --git a/app/assets/stylesheets/mixins/_banner.scss b/app/assets/stylesheets/mixins/_banner.scss index ff5e9abd..00e7e220 100644 --- a/app/assets/stylesheets/mixins/_banner.scss +++ b/app/assets/stylesheets/mixins/_banner.scss @@ -8,23 +8,29 @@ text-align: $slogan_alignment; } + .callout { + flex-grow: 1; + } + .banner { background-color: $background_color; - margin-bottom: 2em; padding: 1em 0 2em 0; min-height: 2em; + .banner-content { + display: flex; + justify-content: space-between; + align-content: center; + flex-wrap: wrap-reverse; + } + h1 { font-family: $font-secondary; color: $text_color; - font-size: 2em; + font-size: 3.3em; font-weight: 100; margin-bottom: 0; - margin-top: 13px; - - @media (min-width: $breakpoint-tablet) { - font-size: 3.3em; - } + margin-top: 0.25em; &.slogan { @media (min-width: $breakpoint-tablet) { diff --git a/app/assets/stylesheets/mixins/_color_scheme.scss b/app/assets/stylesheets/mixins/_color_scheme.scss index 958c1b64..69f95af8 100644 --- a/app/assets/stylesheets/mixins/_color_scheme.scss +++ b/app/assets/stylesheets/mixins/_color_scheme.scss @@ -20,6 +20,14 @@ label { color: $primary_color; + + &.disabled { + color: $grey; + + .required:after { + color: $grey; + } + } } table { diff --git a/app/assets/stylesheets/mixins/_course_widget.scss b/app/assets/stylesheets/mixins/_course_widget.scss index 752f1904..84035815 100644 --- a/app/assets/stylesheets/mixins/_course_widget.scss +++ b/app/assets/stylesheets/mixins/_course_widget.scss @@ -4,10 +4,10 @@ ) { .course-widget { display: block; - width: 329px; + width: 310px; border: 1px solid $medium-grey; margin-bottom: 2em; - margin-right: 1.15em; + margin-right: 1em; min-height: 175px; overflow: hidden; border-top-left-radius: 20px; diff --git a/app/assets/stylesheets/partials/_forms.scss b/app/assets/stylesheets/partials/_forms.scss index f550e936..fc343aef 100644 --- a/app/assets/stylesheets/partials/_forms.scss +++ b/app/assets/stylesheets/partials/_forms.scss @@ -3,18 +3,22 @@ label { font-size: 1.5em; margin-bottom: 0.5em; display: block; -} -legend { - margin-bottom: 0.5em; + &.plain { + color: $dark-grey; + font-size: 1em; + margin-bottom: 0.5em; + display: inline-block; + padding-right: 1em; + } + + &.disabled { + color: $grey; + } } -label.plain { - color: $dark-grey; - font-size: 1em; +legend { margin-bottom: 0.5em; - display: inline-block; - padding-right: 1em; } .required:after { @@ -61,6 +65,7 @@ input[type="url"] { &.topic-box { width: 60%; font-size: 14px; + display: none; } } @@ -213,19 +218,6 @@ select { outline: 0; } -.inline-checkbox-row { - padding-top: 15px; - - .plain-label { - font-size: 16px; - color: black; - - span { - padding-left: 10px; - } - } -} - .inline-radio-group { padding-top: 10px; padding-left: 20px; @@ -285,3 +277,8 @@ select { .character-limit { margin-bottom: -14px; } + +input:disabled, +select:disabled { + color: darken($medium-grey, 20%); +} diff --git a/app/assets/stylesheets/partials/_layout.scss b/app/assets/stylesheets/partials/_layout.scss index e257ac99..95385cdc 100644 --- a/app/assets/stylesheets/partials/_layout.scss +++ b/app/assets/stylesheets/partials/_layout.scss @@ -1,3 +1,7 @@ +main { + padding-top: 2em; +} + .content-grid { display: grid; grid-template-columns: 100%; @@ -10,10 +14,6 @@ grid-template-areas: "sidebar main-content"; } -.main_content { - grid-area: main-content; -} - .sidebar { grid-area: sidebar; } diff --git a/app/controllers/admin/attachments_controller.rb b/app/controllers/admin/attachments_controller.rb index e5a89a79..12bfbfbe 100644 --- a/app/controllers/admin/attachments_controller.rb +++ b/app/controllers/admin/attachments_controller.rb @@ -6,7 +6,7 @@ def destroy @attachment = Attachment.find(params[:id]) authorize @attachment @attachment.destroy - redirect_back(fallback_location: root_path) + redirect_to edit_admin_course_path(@attachment.course) end end end diff --git a/app/controllers/admin/cms_pages_controller.rb b/app/controllers/admin/cms_pages_controller.rb index 53434f85..4df2c5b4 100644 --- a/app/controllers/admin/cms_pages_controller.rb +++ b/app/controllers/admin/cms_pages_controller.rb @@ -3,7 +3,6 @@ module Admin class CmsPagesController < BaseController before_action :set_page, only: %i[edit update destroy] - before_action :set_maximums, only: %i[new edit] def index @cms_pages = policy_scope(CmsPage) @@ -95,12 +94,6 @@ def set_page @cms_page = CmsPage.friendly.find(params[:id]) end - def set_maximums - @max_title = CmsPage.validators_on(:title).first.options[:maximum] - @max_seo = CmsPage.validators_on(:seo_page_title).first.options[:maximum] - @max_meta = CmsPage.validators_on(:meta_desc).first.options[:maximum] - end - def unescaped_cms_content @cms_page.body.html_safe end diff --git a/app/controllers/admin/courses_controller.rb b/app/controllers/admin/courses_controller.rb index 156f5b10..521acaf3 100644 --- a/app/controllers/admin/courses_controller.rb +++ b/app/controllers/admin/courses_controller.rb @@ -2,9 +2,7 @@ module Admin class CoursesController < BaseController - - before_action :set_course, only: %i[show edit update destroy] - before_action :set_maximums, only: %i[new edit] + before_action :set_course, only: %i[preview edit update destroy] before_action :set_category_options, only: %i[new edit create update] def index @@ -16,8 +14,9 @@ def index enable_sidebar end - def show + def preview authorize @course + @preview = true render 'courses/show' end @@ -30,25 +29,21 @@ def new def edit authorize @course + @imported_course = @course.parent.present? end def create - @course = current_organization.courses.new(new_course_params) + @course = current_organization.courses.new authorize @course - if params[:course][:pub_status] == 'P' - @course.set_pub_date - end - - @course.org_id = current_user.organization_id + @course.assign_attributes(new_course_params) if @course.save - @course.topics_list(build_topics_list(params)) - if params[:commit] == 'Save Course' - redirect_to edit_admin_course_path(@course), notice: 'Course was successfully created.' - else + if params[:commit] == 'Save & Edit Lessons' redirect_to new_admin_course_lesson_path(@course), notice: 'Course was successfully created. Now add some lessons.' + else + redirect_to edit_admin_course_path(@course), notice: 'Course was successfully created.' end else @course.errors.delete(:"attachments.document_content_type") @@ -64,7 +59,6 @@ def update_pub_status course.pub_status = params[:value] course.update_pub_date(params[:value]) - course.update_lesson_pub_stats(params[:value]) if course.save render status: :ok, json: course.pub_status.to_s @@ -76,25 +70,26 @@ def update_pub_status def update authorize @course - # The slug must be set to nil for the friendly_id to update on title change @course.slug = nil if @course.title != params[:course][:title] - @course.update_pub_date(params[:course][:pub_status]) if params[:course][:pub_status] != @course.pub_status - if @course.update(new_course_params) - @course.topics_list(build_topics_list(params)) + if @course.parent.blank? + CoursePropagationService.new(course: @course).propagate_course_changes(attributes_to_propagate) + end - changed = propagate_changes? ? propagate_course_changes.count : 0 success_message = 'Course was successfully updated.' - success_message += " Changes propagated to courses for #{changed} #{'subsite'.pluralize(changed)}." if propagate_changes? case params[:commit] when 'Save Course' redirect_to edit_admin_course_path(@course), notice: success_message - when 'Save Course and Edit Lessons' - redirect_to edit_admin_course_lesson_path(@course, @course.lessons.first), notice: success_message + when 'Save & Edit Lessons' + if @course.lessons.blank? + redirect_to new_admin_course_lesson_path(@course), notice: success_message + else + redirect_to edit_admin_course_lesson_path(@course, @course.lessons.first), notice: success_message + end else - redirect_to new_admin_course_lesson_path(@course), notice: success_message + render :edit, alert: 'Unknown Action' end else @course.errors.delete(:"attachments.document_content_type") @@ -127,73 +122,25 @@ def set_category_options @category_options << ['Create new category', 0] end - def set_maximums - @max_title = Course.validators_on(:title).first.options[:maximum] - @max_seo = Course.validators_on(:seo_page_title).first.options[:maximum] - @max_summary = Course.validators_on(:summary).first.options[:maximum] - @max_meta = Course.validators_on(:meta_desc).first.options[:maximum] - end - def set_course - @course = Course.friendly.find(params[:id]) + id_param = params[:id] || params[:course_id] + @course = Course.friendly.find(id_param) end def course_params - permitted_attributes = [ - :title, - :seo_page_title, - :meta_desc, - :summary, - :description, - :contributor, - :pub_status, - :language_id, - :level, - :topics, - :notes, - :delete_document, - :other_topic, - :other_topic_text, - :course_order, - :pub_date, - :format, - :access_level, - :category_id, - propagation_org_ids: [], - category_attributes: %i[name organization_id], - attachments_attributes: %i[course_id document title doc_type file_description _destroy] - ] - - params.require(:course).permit(permitted_attributes) + params.require(:course).permit(policy(@course).permitted_attributes) end def new_course_params - if course_params[:category_id].present? && course_params[:category_id] == '0' - course_params - else - course_params.except(:category_attributes) - end - end - - def build_topics_list(params) - topics_list = params[:course][:topics] || [] - other_topic = params[:course][:other_topic] == '1' ? [params[:course][:other_topic_text]] : [] - topics_list | other_topic - end - - def propagate_changes? - @course.propagation_org_ids.delete_if(&:blank?).any? && attributes_to_propagate.any? + @new_course_params ||= if course_params[:category_id].present? && course_params[:category_id] == '0' + course_params + else + course_params.except(:category_attributes) + end end def attributes_to_propagate - category_name = @course.reload.category.name - course_params.except(:category_id, :category_attributes, :propagation_org_ids).merge(category_name: category_name).to_h - end - - def propagate_course_changes - Course.copied_from_course(@course).each do |course| - course.update(attributes_to_propagate) - end + course_params.except(:category_id, :category_attributes, :access_level, :course_topics_attributes, :attachments_attributes, :pub_status, :notes) end end end diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 3878e875..3e8d9a6c 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -43,7 +43,9 @@ def add_imported_course import_service = CourseImportService.new(organization: current_organization, course_id: params['course_id'].to_i) new_course = import_service.import! - redirect_to edit_admin_course_path(new_course) + success_message = 'Congrats! You have just imported a PLA course.' + + redirect_to edit_admin_course_path(new_course), notice: success_message rescue ActiveRecord::RecordInvalid => e redirect_to admin_import_courses_path, alert: e.record.errors.full_messages end diff --git a/app/controllers/admin/lessons_controller.rb b/app/controllers/admin/lessons_controller.rb index 2b28a992..1c372f25 100644 --- a/app/controllers/admin/lessons_controller.rb +++ b/app/controllers/admin/lessons_controller.rb @@ -4,9 +4,9 @@ module Admin class LessonsController < BaseController before_action :set_course, except: [:sort] - before_action :set_maximums, only: %i[new edit] def new + @course_lessons = Lesson.where(course: @course) @lesson = @course.lessons.new authorize @lesson end @@ -28,6 +28,7 @@ def create end if @lesson.save + add_lesson_to_child_courses! redirect_to edit_admin_course_lesson_path(@course, @lesson), notice: 'Lesson was successfully created.' else render :new @@ -44,9 +45,8 @@ def update @lesson_params[:duration] = @lesson.duration_to_int(lesson_params[:duration]) if @lesson.update(@lesson_params) - changed = propagate_changes? ? propagate_lesson_changes : 0 + LessonPropagationService.new(lesson: @lesson).update_children! success_message = 'Lesson successfully updated.' - success_message += "Changes propagated to lessons for #{changed} #{'subsite'.pluralize(changed)}." if propagate_changes? redirect_to edit_admin_course_lesson_path, notice: success_message else render :edit, notice: 'Lesson failed to update.' @@ -68,6 +68,10 @@ def sort lessons = policy_scope(Lesson) SortService.sort(model: lessons, order_params: params[:order], attribute_key: :lesson_order, user: current_user) + lessons.each do |lesson| + LessonPropagationService.new(lesson: lesson).update_children! + end + head :ok end @@ -86,16 +90,7 @@ def lesson_params :meta_desc, :is_assessment, :lesson_order, - :pub_status, - :subdomain, - propagation_org_ids: []) - end - - def set_maximums - @max_title = Lesson.validators_on(:title).first.options[:maximum] - @max_summary = Lesson.validators_on(:summary).first.options[:maximum] - @max_seo_page_title = Lesson.validators_on(:seo_page_title).first.options[:maximum] - @max_meta_desc = Lesson.validators_on(:meta_desc).first.options[:maximum] + :subdomain) end def validate_assessment @@ -111,22 +106,12 @@ def validate_assessment end end - def propagate_changes? - @lesson.propagation_org_ids.delete_if(&:blank?).any? && (attributes_to_change.to_h.any? || lesson_params[:story_line].present?) - end + def add_lesson_to_child_courses! + courses = Course.copied_from_course(@lesson.course) - def attributes_to_change - lesson_params.delete_if { |k, _| !@lesson.previous_changes.keys.include?(k.to_s) } - end - - def propagate_lesson_changes - lessons = Lesson.copied_from_lesson(@lesson) - - lessons.find_each do |lesson| - lesson.update(attributes_to_change) + courses.each do |course| + LessonPropagationService.new(lesson: @lesson).add_to_course!(course) end - - lessons.size end end end diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb new file mode 100644 index 00000000..1db01c7f --- /dev/null +++ b/app/controllers/attachments_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class AttachmentsController < ApplicationController + def show + @attachment = Attachment.find(params[:id]) + authorize @attachment, :show? + + extension = File.extname(@attachment.document_file_name) + file_options = if extension == '.pdf' + { disposition: 'inline', type: 'application/pdf', x_sendfile: true } + else + { disposition: 'attachment', type: ['application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], + x_sendfile: true } + end + send_file @attachment.document.path, file_options + end +end diff --git a/app/controllers/concerns/user_courses.rb b/app/controllers/concerns/user_courses.rb deleted file mode 100644 index a392b379..00000000 --- a/app/controllers/concerns/user_courses.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module UserCourses - extend ActiveSupport::Concern - - def authorized_courses - courses = Course.includes(:lessons) - .where(pub_status: 'P', language_id: current_language_id, organization: current_organization) - courses = courses.everyone unless user_signed_in? - courses - end - - def current_language_id - english_id = Language.find_by(name: 'English').id || 1 - spanish_id = Language.find_by(name: 'Spanish').id || 2 - - I18n.locale == :es ? spanish_id : english_id - end -end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 25f9093b..a38251f0 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -48,28 +48,8 @@ def show end end - def view_attachment - @course = Course.friendly.find(params[:course_id]) - authorize @course, :show? - - extension = File.extname(@course.attachments.find(params[:attachment_id]).document_file_name) - file_options = if extension == '.pdf' - { disposition: 'inline', type: 'application/pdf', x_sendfile: true } - else - { disposition: 'attachment', type: ['application/msword', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], - x_sendfile: true } - end - send_file @course.attachments.find(params[:attachment_id]).document.path, file_options - end - def skills @course = Course.friendly.find(params[:course_id]) authorize @course, :show? end - - def designing_courses_1; end - - def designing_courses_2; end end diff --git a/app/controllers/lessons_controller.rb b/app/controllers/lessons_controller.rb index fb9d1d6d..1f91b1d8 100644 --- a/app/controllers/lessons_controller.rb +++ b/app/controllers/lessons_controller.rb @@ -6,64 +6,60 @@ class LessonsController < ApplicationController def show @lesson = @course.lessons.friendly.find(params[:id]) - authorize @lesson - - case @lesson.pub_status - when 'D' - flash[:notice] = 'That lesson is not available at this time.' - redirect_to root_path - when 'A' - flash[:notice] = 'That lesson is no longer available.' - redirect_to root_path - when 'P' - @next_lesson = @course.lesson_after(@lesson) - - if current_user - @course_progress = CourseProgress.where(user_id: current_user.id, course_id: @course.id).first_or_create - @course_progress.update(tracked: true) - else - session[:course_id] = @course.id if session[:course_id].blank? - @course_progress = CourseProgress.new(course_id: session[:course_id], tracked: true) - end + @preview = params[:preview] + + authorize_lesson + + @next_lesson = @course.lesson_after(@lesson) + + if current_user + @course_progress = CourseProgress.where(user_id: current_user.id, course_id: @course.id).first_or_create + @course_progress.update(tracked: true) + else + session[:course_id] = @course.id if session[:course_id].blank? + @course_progress = CourseProgress.new(course_id: session[:course_id], tracked: true) + end - respond_to do |format| - format.html do - # The change of course slug should 301 redirect. - if request.path != course_lesson_path(@course, @lesson) - redirect_to course_lesson_path(@course, @lesson), status: :moved_permanently - else - render :show - end + respond_to do |format| + format.html do + # The change of course slug should 301 redirect. + if request.path != course_lesson_path(@course, @lesson) + redirect_to course_lesson_path(@course, @lesson, preview: @preview), status: :moved_permanently + else + render :show end - format.json { render json: @lesson } end + format.json { render json: @lesson } end end def lesson_complete - authorize @course, :show? + @preview = params[:preview] + + if @preview + authorize @course, :preview? + else + authorize @course, :show? + end + @current_lesson = @course.lessons.friendly.find(params[:lesson_id]) @next_lesson = @course.lesson_after(@current_lesson) end def complete - lesson = @course.lessons.friendly.find(params[:lesson_id]) - authorize lesson, :show? + @lesson = @course.lessons.friendly.find(params[:lesson_id]) + @preview = params[:preview] - if current_user - course_progress = CourseProgress.find_or_create_by!(user: current_user, course: @course) - LessonCompletion.find_or_create_by!(course_progress: course_progress, lesson: lesson) - else - session[:completed_lessons] ||= [] - session[:completed_lessons] << lesson.id unless session[:completed_lessons].include?(lesson.id) - end + authorize_lesson + update_course_progress respond_to do |format| format.json do - if lesson.is_assessment - render status: :ok, json: { redirect_path: course_completion_path(@course) } + if @lesson.is_assessment + redirect_path = @preview ? admin_course_preview_path(@course) : course_completion_path(@course) + render status: :ok, json: { redirect_path: redirect_path } else - render status: :ok, json: { redirect_path: course_lesson_lesson_complete_path(@course, lesson) } + render status: :ok, json: { redirect_path: course_lesson_lesson_complete_path(@course, @lesson, preview: @preview) } end end end @@ -80,4 +76,22 @@ def auth_subsites authenticate_user! end end + + def authorize_lesson + if @preview + authorize @course, :preview? + else + authorize @lesson, :show? + end + end + + def update_course_progress + if current_user + course_progress = CourseProgress.find_or_create_by!(user: current_user, course: @course) + LessonCompletion.find_or_create_by!(course_progress: course_progress, lesson: @lesson) + else + session[:completed_lessons] ||= [] + session[:completed_lessons] << @lesson.id unless session[:completed_lessons].include?(@lesson.id) + end + end end diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 6cd2e645..00d2a46c 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -28,7 +28,7 @@ def percent_complete(course) def percent_complete_without_user(course, _lesson_id) session[:completed_lessons] ||= [] - total_lessons = course.lessons.published.count + total_lessons = course.lessons.count completed = (session[:completed_lessons] & course.lessons.pluck(:id)).count return 0 if total_lessons.zero? @@ -51,15 +51,15 @@ def categorized_courses(courses) end end - def start_or_resume_course_link(course) + def start_or_resume_course_link(course, preview = nil) return if course.lessons.empty? course_progress = current_user&.course_progresses&.find_by(course_id: course.id) lesson_path = if course_progress - course_lesson_path(course, course_progress.next_lesson) + course_lesson_path(course, course_progress.next_lesson, preview: preview) else - course_lesson_path(course, course.lessons.first) + course_lesson_path(course, course.lessons.first, preview: preview) end link_to t('course_page.start_course').to_s, lesson_path, class: 'btn button-color', data: { cpl_ga_event: 'on', cpl_ga_value: 'user-start-course' } diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 71fbba5b..4c8b86a2 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -2,4 +2,8 @@ class ApplicationRecord < ActiveRecord::Base self.abstract_class = true + + def self.max_length_for(attr) + self.validators_on(attr).first.options[:maximum] + end end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 61c56c0a..fa61a349 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -15,6 +15,6 @@ class Attachment < ApplicationRecord message: 'is invalid. Only PDF, Word, PowerPoint, or Excel files are allowed.' validates :doc_type, allow_blank: true, - inclusion: { in: %w[supplemental post-course], + inclusion: { in: %w[text-copy additional-resource], message: '%s is not a doc_type' } end diff --git a/app/models/course.rb b/app/models/course.rb index 193ac060..f9ba048b 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -28,14 +28,13 @@ def subdomain_for_slug enum access_level: { everyone: 0, authenticated_users: 1 } # Attributes not saved to db, but still needed for validation - attr_accessor :other_topic, :other_topic_text, :org_id, :subdomain - attr_writer :propagation_org_ids + attr_accessor :other_topic, :org_id, :subdomain belongs_to :parent, class_name: 'Course', optional: true # has_one :assessment has_one :course_progress, dependent: :restrict_with_exception - has_many :course_topics, dependent: :destroy + has_many :course_topics, dependent: :destroy, inverse_of: :course has_many :topics, through: :course_topics has_many :lessons, -> { order(:lesson_order) }, dependent: :destroy, inverse_of: :course belongs_to :organization, optional: false @@ -47,6 +46,7 @@ def subdomain_for_slug belongs_to :category, optional: true accepts_nested_attributes_for :category, reject_if: :all_blank + accepts_nested_attributes_for :course_topics, reject_if: proc { |ct| ct[:topic_attributes][:title].blank? } validates :description, :contributor, :language_id, presence: true validates :title, length: { maximum: 50 }, presence: true @@ -62,22 +62,17 @@ def subdomain_for_slug validates :level, presence: true, inclusion: { in: %w[Beginner Intermediate Advanced], message: '%s is not a valid level' } - validates :other_topic_text, presence: true, if: proc { |a| a.other_topic == '1' } default_scope { order('course_order ASC') } scope :with_category, ->(category_id) { where(category_id: category_id) } - scope :copied_from_course, ->(course) { joins(:organization).where(parent_id: course.id, organizations: { id: course.propagation_org_ids }) } + scope :copied_from_course, ->(course) { joins(:organization).where(parent_id: course.id) } scope :org, ->(org) { where(organization: org) } scope :pla, -> { where(organization: Organization.find_by(subdomain: 'www')) } scope :published, -> { where(pub_status: 'P') } before_save :find_or_create_category - def propagation_org_ids - @propagation_org_ids ||= [] - end - def topics_list(topic_list) if topic_list.present? valid_topics = topic_list.reject(&:blank?) @@ -93,15 +88,15 @@ def topics_str end def lesson_after(lesson = nil) - raise StandardError, 'There are no available lessons for this course.' if lessons.published.count.zero? + raise StandardError, 'There are no available lessons for this course.' if lessons.count.zero? begin lesson_order = lesson.lesson_order - return lessons.published.last if lesson_order >= last_lesson_order + return lessons.last if lesson_order >= last_lesson_order - lessons.published.find_by('lesson_order > ?', lesson_order) + lessons.find_by('lesson_order > ?', lesson_order) rescue StandardError - lessons.published.first + lessons.first end end @@ -113,7 +108,7 @@ def last_lesson_order def duration(format = 'mins') total = 0 - lessons.published.each { |l| total += l.duration } + lessons.each { |l| total += l.duration } Duration.minutes_str(total, format) end @@ -127,19 +122,12 @@ def update_pub_date(new_pub_status) end end - def update_lesson_pub_stats(new_pub_status) - lessons.each do |l| - l.pub_status = new_pub_status - l.save - end - end - - def post_course_attachments - self.attachments.where(doc_type: 'post-course') + def additional_resource_attachments + self.attachments.where(doc_type: 'additional-resource') end - def supplemental_attachments - self.attachments.where(doc_type: 'supplemental') + def text_copy_attachments + (parent || self).attachments.where(doc_type: 'text-copy') end def published? @@ -147,9 +135,9 @@ def published? end def find_or_create_category - return true unless category_name.present? + return true if category_name.blank? - existing_category = self.organization.categories.where('lower(name) = ?', category_name.downcase).first + existing_category = self.organization.categories.find_by('lower(name) = ?', category_name.downcase) self.category = existing_category || self.organization.categories.find_or_create_by(name: category_name) end end diff --git a/app/models/course_progress.rb b/app/models/course_progress.rb index 7b68b1c3..1d221c22 100644 --- a/app/models/course_progress.rb +++ b/app/models/course_progress.rb @@ -19,7 +19,7 @@ def complete? end def percent_complete - total = course.lessons.published.count + total = course.lessons.count completed = lessons_completed return 0 if total.zero? diff --git a/app/models/course_topic.rb b/app/models/course_topic.rb index 7b1b9fda..b46f7b5f 100644 --- a/app/models/course_topic.rb +++ b/app/models/course_topic.rb @@ -3,4 +3,6 @@ class CourseTopic < ApplicationRecord belongs_to :topic belongs_to :course, touch: true + + accepts_nested_attributes_for :topic, reject_if: :all_blank end diff --git a/app/models/lesson.rb b/app/models/lesson.rb index 67f8dda6..21af8714 100644 --- a/app/models/lesson.rb +++ b/app/models/lesson.rb @@ -18,7 +18,6 @@ def subdomain_for_slug end attr_accessor :subdomain - attr_writer :propagation_org_ids belongs_to :course belongs_to :parent, class_name: 'Lesson', optional: true @@ -31,8 +30,6 @@ def subdomain_for_slug validates :lesson_order, presence: true, numericality: { only_integer: true, greater_than: 0, allow_blank: true } validates :seo_page_title, length: { maximum: 90 } validates :meta_desc, length: { maximum: 156 } - validates :pub_status, presence: true, - inclusion: { in: %w[P D A], message: '%s is not a valid status', allow_blank: true } has_attached_file :story_line, Rails.configuration.storyline_paperclip_opts before_post_process :skip_for_zip @@ -42,15 +39,7 @@ def subdomain_for_slug before_destroy :delete_associated_asl_files default_scope { order(:lesson_order) } - scope :published, -> { where(pub_status: 'P') } - scope :copied_from_lesson, lambda { |lesson| - joins(course: :organization) - .where(parent_id: lesson.id, organizations: { id: lesson.propagation_org_ids }) - } - - def propagation_org_ids - @propagation_org_ids ||= [] - end + scope :copied_from_lesson, ->(lesson) { joins(course: :organization).where(parent_id: lesson.id) } def skip_for_zip %w[application/zip application/x-zip].include?(story_line_content_type) @@ -72,14 +61,4 @@ def duration_to_int(duration_param) end end - def published? - pub_status == 'P' - end - - def published_lesson_order - return 0 unless self.published? - - self.course.lessons.published.map(&:id).index(self.id) + 1 - end - end diff --git a/app/models/organization.rb b/app/models/organization.rb index 842358d4..18a65978 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -78,4 +78,8 @@ def clean_up_paperclip_errors errors.delete(:footer_logo_content_type) errors.delete(:footer_logo_file_size) end + + def self.pla + find_by(subdomain: 'www') + end end diff --git a/app/policies/attachment_policy.rb b/app/policies/attachment_policy.rb index 615904b0..91a90cb0 100644 --- a/app/policies/attachment_policy.rb +++ b/app/policies/attachment_policy.rb @@ -1,9 +1,28 @@ # frozen_string_literal: true class AttachmentPolicy < AdminOnlyPolicy + + def show? + course_to_authorize = child_course || record.course + + CoursePolicy.new(user, course_to_authorize).show? + end + private def organization record.course.organization end + + def child_courses + Course.copied_from_course(record.course) + end + + def child_course + child_courses.where(organization_id: user.organization.id).first + end + + def attachment_current_course + child_course || record.course + end end diff --git a/app/policies/course_policy.rb b/app/policies/course_policy.rb index 407a9a24..d792102d 100644 --- a/app/policies/course_policy.rb +++ b/app/policies/course_policy.rb @@ -18,6 +18,46 @@ def track? record.organization == user.organization && record.published? end + def preview? + return false unless user.admin? + + record.organization == Organization.pla + end + + def permitted_attributes + return [] unless user.admin? + + if record.parent.present? + [:category_id, + :access_level, + :pub_status, + :notes, + category_attributes: %i[name organization_id], + attachments_attributes: %i[document title doc_type file_description _destroy]] + else + [:title, + :seo_page_title, + :meta_desc, + :summary, + :description, + :contributor, + :pub_status, + :language_id, + :level, + :notes, + :delete_document, + :course_order, + :pub_date, + :format, + :access_level, + :category_id, + topic_ids: [], + course_topics_attributes: [topic_attributes: [:title]], + category_attributes: %i[name organization_id], + attachments_attributes: %i[document title doc_type file_description _destroy]] + end + end + class Scope < Scope def resolve courses = scope.includes(:lessons).where(organization: user.organization) diff --git a/app/services/course_import_service.rb b/app/services/course_import_service.rb index 6fc0bde9..3195a499 100644 --- a/app/services/course_import_service.rb +++ b/app/services/course_import_service.rb @@ -11,8 +11,8 @@ def import! ActiveRecord::Base.transaction do save_new_course! copy_parent_lessons! - copy_attachments! copy_topics! + copy_attachments! end @new_course @@ -42,23 +42,8 @@ def new_or_existing_subsite_category_id(category) end def copy_parent_lessons! - # Create copies of the lessons and ASLs - @parent_course.lessons.each do |imported_lesson| - new_lesson = imported_lesson.dup - new_lesson.parent_id = imported_lesson.id - new_lesson.course_id = @new_course.id - new_lesson.story_line = nil - new_lesson.save! - end - end - - def copy_attachments! - # Create copies of the attachments - @parent_course.attachments.each do |attachment| - new_attachment = attachment.dup - new_attachment.document = attachment.document - new_attachment.course_id = @new_course.id - new_attachment.save! + @parent_course.lessons.each do |lesson| + LessonPropagationService.new(lesson: lesson).add_to_course!(@new_course) end end @@ -70,4 +55,14 @@ def copy_topics! new_topic.save! end end + + def copy_attachments! + # Create copies of the attachments + @parent_course.additional_resource_attachments.each do |attachment| + new_attachment = attachment.dup + new_attachment.document = attachment.document + new_attachment.course_id = @new_course.id + new_attachment.save! + end + end end diff --git a/app/services/course_propagation_service.rb b/app/services/course_propagation_service.rb new file mode 100644 index 00000000..a3ec36c9 --- /dev/null +++ b/app/services/course_propagation_service.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class CoursePropagationService + + def initialize(course:) + @course = course + end + + def propagate_course_changes(attributes_to_propagate) + child_courses.each do |child| + child.update(attributes_to_propagate.merge(topics: topics)) + end + end + + private + + def child_courses + Course.copied_from_course(@course) + end + + def topics + @course.topics + end +end diff --git a/app/services/lesson_propagation_service.rb b/app/services/lesson_propagation_service.rb new file mode 100644 index 00000000..86113492 --- /dev/null +++ b/app/services/lesson_propagation_service.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class LessonPropagationService + def initialize(lesson:) + @lesson = lesson + end + + def add_to_course!(course) + new_lesson = @lesson.dup + new_lesson.parent_id = @lesson.id + new_lesson.course_id = course.id + new_lesson.story_line = nil + new_lesson.save! + end + + def update_children! + Lesson.copied_from_lesson(@lesson).each do |child| + child.update!(@lesson.attributes.except('id', 'parent_id', 'course_id')) + end + end +end diff --git a/app/views/admin/cms_pages/_form.html.erb b/app/views/admin/cms_pages/_form.html.erb index cf7b1633..3bc703f0 100644 --- a/app/views/admin/cms_pages/_form.html.erb +++ b/app/views/admin/cms_pages/_form.html.erb @@ -38,7 +38,7 @@ <%= f.label :title, class: "text-color" do %> Title <% end %> - <%= f.text_field :title, maxlength: 90 %> + <%= f.text_field :title, maxlength: CmsPage.max_length_for(:title) %>
 
@@ -80,7 +80,7 @@
<%= f.label "SEO page title", class: "text-color" %> - <%= f.text_field :seo_page_title, maxlength: 90 %> + <%= f.text_field :seo_page_title, maxlength: CmsPage.max_length_for(:seo_page_title) %>
 
@@ -88,7 +88,7 @@
<%= f.label :meta_desc, class: "text-color" %> - <%= f.text_field :meta_desc, maxlength: 156 %> + <%= f.text_field :meta_desc, maxlength: CmsPage.max_length_for(:meta_desc) %>
 
diff --git a/app/views/admin/courses/_form.html.erb b/app/views/admin/courses/_form.html.erb new file mode 100644 index 00000000..5f2bae34 --- /dev/null +++ b/app/views/admin/courses/_form.html.erb @@ -0,0 +1,111 @@ +<%= form_for([:admin, @course], html: { multipart: true, class: "course-form #{'restricted' if @imported_course}" } ) do |f| %> + <% if @course.errors.any? %> +
+

<%= pluralize(@course.errors.count, "error") %> prohibited this course from being saved:

+
    + <% @course.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+ <% end %> + + <% if @imported_course %> + <%= render 'admin/courses/forms/imported_course_actions', f: f %> + <% end %> + +
+ <%= f.label :title, class: "#{'disabled' if @imported_course}" do %> + Title + <% end %> + <%= f.text_field :title, maxlength: Course.max_length_for(:title), disabled: @imported_course %> +
 
+
+ +
+ <%= f.label :contributor, class: "#{'disabled' if @imported_course}" do %> + Contributor + <% end %> + <%= f.text_field :contributor, disabled: @imported_course %> +
+ +
+ <%= f.label :summary, class: "#{'disabled' if @imported_course}" do %> + Course Summary + <% end %> + <%= f.text_field :summary, maxlength: Course.max_length_for(:summary), disabled: @imported_course %> +
 
+
+ +
+ <%= f.label :description, class: "#{'disabled' if @imported_course}" do %> + Course Description + <% end %> + <%= f.cktext_area :description, disabled: @imported_course %> +
+ + <%= render partial: 'admin/courses/forms/text_copy_fields', locals: { f: f } %> + <%= render partial: 'admin/courses/forms/additional_resource_fields', locals: { f: f } %> + +
+ <%= f.label :notes, "Content for Further Learning", class: "" %> +

This content is available to users after completing the course.

+ <%= f.cktext_area :notes %> +
+ + <%= render 'admin/courses/forms/topics', f: f %> + <%= render 'admin/courses/forms/categories', f: f %> + +
+ <%= f.label :language_id, class: "#{'disabled' if @imported_course}" do %> + Course Language + <% end %> + <%= f.collection_select(:language_id, Language.all, :id, "name", { include_blank: "Select..." }, { disabled: @imported_course } ) %> +
+ +
+ <%= f.label :format, class: "#{'disabled' if @imported_course}" do %> + Course Format + <% end %> + <%= f.select(:format, options_for_select([["Desktop", "D"],["Mobile", "M"]], @course.format), { include_blank: "Select..." }, { disabled: @imported_course } ) %> +
+ +
+ <%= f.label :level, class: "#{'disabled' if @imported_course}" do %> + Course Level + <% end %> + <%= f.select(:level, options_for_select(["Beginner", "Intermediate", "Advanced"], @course.level), { include_blank: "Select..." }, { disabled: @imported_course } ) %> +
+ + <%= render 'admin/courses/forms/access_level', f: f %> + +
+ <%= f.label :seo_page_title, class: "#{'disabled' if @imported_course}" do %> + SEO Page Title + <% end %> + <%= f.text_field :seo_page_title, maxlength: Course.max_length_for(:seo_page_title), disabled: @imported_course %> +
 
+
+ +
+ <%= f.label :meta_desc, class: "#{'disabled' if @imported_course}" do %> + SEO Meta Description + <% end %> + <%= f.text_field :meta_desc, maxlength: Course.max_length_for(:meta_desc), disabled: @imported_course %> +
 
+
+ +
+ <%= f.label :pub_status do %> + Publication Status + <% end %> + <%= f.select(:pub_status, options_for_select([["Draft", "D"], ["Published", "P"], ["Archived", "A"]], @course.pub_status), data: { status: @course.pub_status }) %> +
+ + <%= f.hidden_field :subdomain, value: current_organization.subdomain %> + <%= f.hidden_field :organization_id, value: current_organization.id %> + + <% unless @imported_course %> + <%= render 'admin/courses/forms/course_owner_actions', f: f %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/courses/_sortable_import_list.html.erb b/app/views/admin/courses/_import_list.html.erb similarity index 77% rename from app/views/admin/courses/_sortable_import_list.html.erb rename to app/views/admin/courses/_import_list.html.erb index 2df39445..07ab7fd0 100644 --- a/app/views/admin/courses/_sortable_import_list.html.erb +++ b/app/views/admin/courses/_import_list.html.erb @@ -3,16 +3,17 @@ <% if courses.empty? %> No courses in this category <% else %> -
+
Course
Topic
Language
-
Publication Status
+
+
-
    +
      <% courses.each do |course| %> -
    • +
    • <%= course.title %>
      <%= course.topics_str %>
      <%= course.language.name %>
      @@ -20,6 +21,9 @@ <%= link_to "Import Course", admin_dashboard_add_imported_course_path(course_id: course.id), method: :post, class: "load-on-click" %> <%= render 'shared/loader' %>
+
+ <%= link_to "Preview Course", admin_course_preview_path(course) %> +
<% end %> diff --git a/app/views/admin/courses/_sortable_list.html.erb b/app/views/admin/courses/_sortable_list.html.erb index aed2d9da..424eac23 100644 --- a/app/views/admin/courses/_sortable_list.html.erb +++ b/app/views/admin/courses/_sortable_list.html.erb @@ -16,7 +16,7 @@
<%= link_to course.title, edit_admin_course_path(course), class: "no_drag_link" %>
<%= course.topics_str %>
<%= course.language.name %>
-
<%= select_tag "course_#{course.id}", options_for_select([["Publish", "P"], ["Draft", "D"], ["Archive", "A"]], course.pub_status), data: { course_id: course.id, status: course.pub_status }, class:"course_pub small narrow", method: :patch %> +
<%= select_tag "course_#{course.id}", options_for_select([["Published", "P"], ["Draft", "D"], ["Archive", "A"]], course.pub_status), data: { course_id: course.id, status: course.pub_status }, class:"course_pub small narrow", method: :patch %> <% unless course.pub_date.blank? %> (<%= course.pub_date.strftime("%m/%d/%Y") %>) <% end %> diff --git a/app/views/admin/courses/edit.html.erb b/app/views/admin/courses/edit.html.erb index 117e7a8b..28f4a952 100644 --- a/app/views/admin/courses/edit.html.erb +++ b/app/views/admin/courses/edit.html.erb @@ -1,3 +1,5 @@ <%= content_for(:callout) { %>

Edit This Course

<% } %> -<%= render partial: 'admin/courses/forms/form', locals: { breadcrumb: "Edit Course" } %> +<%= "Admin >> Courses >> Edit Course" %> + +<%= render 'admin/courses/form' %> diff --git a/app/views/admin/courses/forms/_access_level.html.erb b/app/views/admin/courses/forms/_access_level.html.erb index b309cc09..94931f24 100644 --- a/app/views/admin/courses/forms/_access_level.html.erb +++ b/app/views/admin/courses/forms/_access_level.html.erb @@ -1,5 +1,5 @@
- <%= f.label :access_level, class: "text-color" do %> + <%= f.label :access_level do %> Access Level <% end %> <% options = [['Everyone', 'everyone'], ['Authenticated Users', 'authenticated_users']]%> diff --git a/app/views/admin/courses/forms/_additional_resource_fields.html.erb b/app/views/admin/courses/forms/_additional_resource_fields.html.erb index 8c259325..6555059c 100644 --- a/app/views/admin/courses/forms/_additional_resource_fields.html.erb +++ b/app/views/admin/courses/forms/_additional_resource_fields.html.erb @@ -1,12 +1,15 @@
<%= f.fields_for :attachments, @course.attachments.build do |a| %> - <%= a.label :document, "Additional Resources", class: "text-color" %> -

Upload any supplemental materials for further learning. These files are available to users after completing the course.

+ <%= a.label :document, "Additional Resources" %> +

+ <%= 'Upload any supplemental materials for further learning. These files are available to users after completing the course.' %> +

+
- <%= render partial: 'admin/courses/forms/attachment_list', locals: { type: 'post-course' } %> - <%= render partial: 'admin/courses/forms/attachment_upload', locals: { attachment_form: a, attachment_type: 'post-course', removable: false } %> - <%= link_to_add_fields "Add Attachment", f, :attachments, "post-course" %> + <%= render partial: 'admin/courses/forms/attachment_list', locals: { type: 'additional-resource', allow_delete: true } %> + <%= render partial: 'admin/courses/forms/attachment_upload', locals: { attachment_form: a, attachment_type: 'additional-resource', removable: false } %> + <%= link_to_add_fields "Add Attachment", f, :attachments, "additional-resource" %>
<% end %>
\ No newline at end of file diff --git a/app/views/admin/courses/forms/_attachment_list.html.erb b/app/views/admin/courses/forms/_attachment_list.html.erb index 9abf1b8d..bce372dd 100644 --- a/app/views/admin/courses/forms/_attachment_list.html.erb +++ b/app/views/admin/courses/forms/_attachment_list.html.erb @@ -4,9 +4,11 @@
<%= a.document_file_name %>
-
- <%= link_to "Delete", admin_attachment_path(a), method: :delete, data: { confirm: "Are you sure?" } %> -
+ <% if allow_delete %> +
+ <%= link_to "Delete", admin_attachment_path(a), method: :delete, data: { confirm: "Are you sure?" } %> +
+ <% end %>
<% end %>
\ No newline at end of file diff --git a/app/views/admin/courses/forms/_categories.html.erb b/app/views/admin/courses/forms/_categories.html.erb new file mode 100644 index 00000000..8a05dc4a --- /dev/null +++ b/app/views/admin/courses/forms/_categories.html.erb @@ -0,0 +1,16 @@ +
+
+ <%= f.label :category_id do %> + Course Category + <% end %> + <%= f.select(:category_id, options_for_select(@category_options, @course.category_id || ("0" if @custom)),{ include_blank: "Uncategorized" } ) %> +
+
+ <%= f.fields_for :category_attributes do |c| %> + <%= c.hidden_field :organization_id, value: current_organization.id %> +
> + <%= c.text_field :name, value: (@category.name if @category.present?) || (@custom_category), placeholder: "Enter new category name", class: "#{'hideUntilActive' unless @category_name.present?}" %> +
+ <% end %> +
+
\ No newline at end of file diff --git a/app/views/admin/courses/forms/_course_owner_actions.html.erb b/app/views/admin/courses/forms/_course_owner_actions.html.erb new file mode 100644 index 00000000..7b5c4f4a --- /dev/null +++ b/app/views/admin/courses/forms/_course_owner_actions.html.erb @@ -0,0 +1,4 @@ +
+ <%= f.submit "Save Course", class: "button-color" %> + <%= f.submit "Save & Edit Lessons", class: "button-color" %> +
\ No newline at end of file diff --git a/app/views/admin/courses/forms/_form.html.erb b/app/views/admin/courses/forms/_form.html.erb deleted file mode 100644 index 916b9b88..00000000 --- a/app/views/admin/courses/forms/_form.html.erb +++ /dev/null @@ -1,148 +0,0 @@ -<%= "Admin >> Courses >> #{breadcrumb}" %> - -

Course Information

- -<%= form_for([:admin, @course], html: { multipart: true, class: 'course-form' } ) do |f| %> - <% if @course.errors.any? %> -
-

<%= pluralize(@course.errors.count, "error") %> prohibited this course from being saved:

-
    - <% @course.errors.full_messages.each do |message| %> -
  • <%= message %>
  • - <% end %> -
-
- <% end %> - -
- <%= f.label :title, class: "text-color" do %> - Title - <% end %> - <%= f.text_field :title, maxlength: 50 %> -
 
-
- -
- <%= f.label :contributor, class: "text-color" do %> - Contributor - <% end %> - <%= f.text_field :contributor %> -
- -
- <%= f.label :summary, class: "text-color" do %> - Course Summary - <% end %> - <%= f.text_field :summary, maxlength: 74 %> -
 
-
- -
- <%= f.label :description, class: "text-color" do %> - Course Description - <% end %> - <%= f.cktext_area :description %> -
- - <%= render partial: 'admin/courses/forms/text_copy_fields', locals: { f: f } %> - <%= render partial: 'admin/courses/forms/additional_resource_fields', locals: { f: f } %> - -
- <%= f.label :notes, "Content for Further Learning", class: "text-color" %> -

This content is available to users after completing the course.

- <%= f.cktext_area :notes %> -
- -
- <%= f.label :topics, class: "text-color" do %> - Course Topics - <% end %> - - <%= f.collection_check_boxes(:topics, Topic.all, :title, :title) do |b| %> -
- <%= b.check_box(checked: current_topics(@course, b.object)) %> - <%= b.label class: "plain" %> -
- <% end %> - -
- <%= f.check_box :other_topic %> - <%= f.label :other_topic, "Other Topic", class: "plain" %> - <%= f.text_field :other_topic_text, placeholder: "(Enter to create new topic)", class: "topic-box" %> -
-
- -
-
- <%= f.label :category_id, class: "text-color" do %> - Course Category - <% end %> - <%= f.select(:category_id, options_for_select(@category_options, @course.category_id || ("0" if @custom)),{ include_blank: "Uncategorized" } ) %> -
-
- <%= f.fields_for :category_attributes do |c| %> - <%= c.hidden_field :organization_id, value: current_organization.id %> -
> - <%= c.text_field :name, value: (@category.name if @category.present?) || (@custom_category), placeholder: "Enter new category name", class: "#{'hideUntilActive' unless @category_name.present?}" %> -
- <% end %> -
-
- -
- <%= f.label :language_id, class: "text-color" do %> - Course Language - <% end %> - <%= f.collection_select(:language_id, Language.all, :id, "name", { include_blank: "Select..." } ) %> -
- -
- <%= f.label :format, class: "text-color" do %> - Course Format - <% end %> - <%= f.select(:format, options_for_select([["Desktop", "D"],["Mobile", "M"]], @course.format), { include_blank: "Select..." } ) %> -
- - <%= render("admin/courses/forms/level_pub_section", f: f) %> - <%= render("admin/courses/forms/access_level", f: f) %> - -
- <%= f.label "SEO page title", class: "text-color" %> - <%= f.text_field :seo_page_title, maxlength: 90 %> -
 
-
- -
- <%= f.label :meta_desc, class: "text-color" %> - <%= f.text_field :meta_desc, maxlength: 156 %> -
 
-
- - <% if top_level_domain? && !@course.new_record? %> -
- <%= f.label :propagation_org_ids, 'Propagate these changes to subsite courses for:', class: "text-color" %> - <% if Organization.using_course(@course.id).exists? %> - <%= f.collection_check_boxes :propagation_org_ids, Organization.using_course(@course.id), :id, :name do |b| %> -
- <%= b.check_box(checked: @course.propagation_org_ids.include?(b.object)) %> - <%= b.label class: "plain" %> -
- <% end %> - <% else %> -

There's no subsite imported this course yet.

- <% end %> -
- <% end %> - - <%= f.hidden_field :subdomain, value: current_organization.subdomain %> - <%= f.hidden_field :organization_id, value: current_organization.id %> - -
- <%= f.submit "Save Course", params: { commit: "Save Course" }, class: "button-color" %> - <% if @course.lessons.blank? %> - <%= f.submit "Save Course and Add Lessons", class: "button-color" %> - <% else %> - <%= f.submit "Save Course and Edit Lessons", class: "button-color" %> - <% end %> -
-<% end %> \ No newline at end of file diff --git a/app/views/admin/courses/forms/_imported_course_actions.html.erb b/app/views/admin/courses/forms/_imported_course_actions.html.erb new file mode 100644 index 00000000..0442aaeb --- /dev/null +++ b/app/views/admin/courses/forms/_imported_course_actions.html.erb @@ -0,0 +1,6 @@ +
+ <%= f.submit "Save Course", class: "button-color" %> +

+ If you wish to edit additional details of this course and use the PLA-created Storyline files, please <%= mail_to "support@digitallearn.org", "contact a PLA Administrator" %>. +

+
\ No newline at end of file diff --git a/app/views/admin/courses/forms/_level_pub_section.html.erb b/app/views/admin/courses/forms/_level_pub_section.html.erb deleted file mode 100644 index 1f74a521..00000000 --- a/app/views/admin/courses/forms/_level_pub_section.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -
- <%= f.label :level, class: "text-color" do %> - Course Level - <% end %> - <%= f.select(:level, options_for_select(["Beginner", "Intermediate", "Advanced"], @course.level), { include_blank: "Select..." } ) %> -
-
- <%= f.label :pub_status, class: "text-color" do %> - Publication Status - <% end %> - <%= f.select(:pub_status, options_for_select([["Draft", "D"], ["Published", "P"], ["Archived", "A"]], @course.pub_status), { include_blank: "Select..." }, data: { status: @course.pub_status }) %> -
diff --git a/app/views/admin/courses/forms/_text_copy_fields.html.erb b/app/views/admin/courses/forms/_text_copy_fields.html.erb index 2d674b53..d8f9e3de 100644 --- a/app/views/admin/courses/forms/_text_copy_fields.html.erb +++ b/app/views/admin/courses/forms/_text_copy_fields.html.erb @@ -1,12 +1,16 @@
<%= f.fields_for :attachments, @course.attachments.build do |a| %> - <%= a.label :document, "Text Copies of Course", class: "text-color" %> -

Upload text copies of the course to allow users to download content and view offline or follow along with the online course.

+ <%= a.label :document, "Text Copies of Course", class: "#{'disabled' if @imported_course}" %> +

+ <%= "#{@imported_course ? 'Text' : 'Upload text'} copies of the course to allow users to download content and view offline or follow along with the online course." %> +

- <%= render partial: 'admin/courses/forms/attachment_list', locals: { type: 'supplemental' } %> - <%= render partial: 'admin/courses/forms/attachment_upload', locals: { attachment_form: a, attachment_type: 'supplemental', removable: false } %> - <%= link_to_add_fields "Add Attachment", f, :attachments, "supplemental" %> + <%= render partial: 'admin/courses/forms/attachment_list', locals: { type: 'text-copy', allow_delete: !@imported_course } %> + <% unless @imported_course %> + <%= render partial: 'admin/courses/forms/attachment_upload', locals: { attachment_form: a, attachment_type: 'text-copy', removable: false } %> + <%= link_to_add_fields "Add Attachment", f, :attachments, 'text-copy' %> + <% end %>
<% end %>
\ No newline at end of file diff --git a/app/views/admin/courses/forms/_topics.html.erb b/app/views/admin/courses/forms/_topics.html.erb new file mode 100644 index 00000000..1685f5f2 --- /dev/null +++ b/app/views/admin/courses/forms/_topics.html.erb @@ -0,0 +1,24 @@ +
+ <%= f.label :topic_ids, class: "#{'disabled' if @imported_course}" do %> + Course Topics + <% end %> + + <%= f.collection_check_boxes(:topic_ids, Topic.all, :id, :title, {}, disabled: @imported_course) do |b| %> +
+ <%= b.check_box %> + <%= b.label class: "plain #{'disabled' if @imported_course}" %> +
+ <% end %> + + <% unless @imported_course %> +
+ <%= f.check_box :other_topic %> + <%= f.label :other_topic, "Other Topic", class: "plain #{'disabled' if @imported_course}" %> + <%= f.fields_for :course_topics, [CourseTopic.new] do |ct| %> + <%= ct.fields_for :topic_attributes do |topic_form| %> + <%= topic_form.text_field :title, placeholder: "(Enter to create new topic)", class: "topic-box" %> + <% end %> + <% end %> +
+ <% end %> +
\ No newline at end of file diff --git a/app/views/admin/courses/import_courses.html.erb b/app/views/admin/courses/import_courses.html.erb index 7edb8472..9759da0a 100644 --- a/app/views/admin/courses/import_courses.html.erb +++ b/app/views/admin/courses/import_courses.html.erb @@ -14,9 +14,9 @@ <% (@category_ids || []).each do |category_id| %> - <%= render partial: "admin/courses/sortable_import_list", locals: { courses: @importable_courses.with_category(category_id), category: Category.find_by_id(category_id) } %> + <%= render partial: "admin/courses/import_list", locals: { courses: @importable_courses.with_category(category_id), category: Category.find_by_id(category_id) } %> <% end %> <% if @uncategorized_courses.present? %> - <%= render partial: "admin/courses/sortable_import_list", locals: { courses: @uncategorized_courses, category: nil } %> + <%= render partial: "admin/courses/import_list", locals: { courses: @uncategorized_courses, category: nil } %> <% end %> diff --git a/app/views/admin/courses/new.html.erb b/app/views/admin/courses/new.html.erb index 3fcb03cb..b151b189 100644 --- a/app/views/admin/courses/new.html.erb +++ b/app/views/admin/courses/new.html.erb @@ -1,2 +1,5 @@ <%= content_for(:callout) { %>

Add a New Course

<% } %> -<%= render partial: "admin/courses/forms/form", locals: { breadcrumb: "Add a New Course "} %> + +<%= "Admin >> Courses >> Edit Course" %> + +<%= render "admin/courses/form" %> diff --git a/app/views/admin/lessons/_form.html.erb b/app/views/admin/lessons/_form.html.erb index 261b4aa4..72c9a565 100644 --- a/app/views/admin/lessons/_form.html.erb +++ b/app/views/admin/lessons/_form.html.erb @@ -19,7 +19,7 @@ <%= f.label :title, class: "text-color" do %> Lesson Title <% end %> - <%= f.text_field :title, maxlength: 90 %> + <%= f.text_field :title, maxlength: Lesson.max_length_for(:title) %>
 
@@ -29,7 +29,7 @@ <%= f.label :summary, class: "text-color" do %> Lesson Summary <% end %> - <%= f.text_field :summary, maxlength: 156 %> + <%= f.text_field :summary, maxlength: Lesson.max_length_for(:summary) %>
 
@@ -77,7 +77,7 @@ <%= f.label :seo_page_title, class: "text-color" do %> Page Title <% end %> - <%= f.text_field :seo_page_title, maxlength: 90 %> + <%= f.text_field :seo_page_title, maxlength: Lesson.max_length_for(:seo_page_title) %>
 
@@ -85,19 +85,12 @@
<%= f.label :meta_desc, class: "text-color" %> - <%= f.text_field :meta_desc, maxlength: 156 %> + <%= f.text_field :meta_desc, maxlength: Lesson.max_length_for(:meta_desc) %>
 
-
- <%= f.label :pub_status, class: "text-color" do %> - Publication Status - <% end %> - <%= f.select(:pub_status, options_for_select([["Draft", "D"], ["Published", "P"]], @lesson.pub_status), { include_blank: "Select..." } ) %> -
-
<%= f.label :is_assessment, class: "text-color" do %> Assessment @@ -110,21 +103,6 @@
- <% if top_level_domain? %> -
-
- <%= f.label :propagation_org_ids, 'Propagate these changes to subsite lessons for:', class: "text-color" %> - - <%= f.collection_check_boxes :propagation_org_ids, Organization.using_lesson(@lesson.id), :id, :name do |b| %> -
- <%= b.check_box(checked: @lesson.propagation_org_ids.include?(b.object)) %> - <%= b.label class: "plain" %> -
- <% end %> -
-
- <% end %> - <%= f.hidden_field :subdomain, value: current_organization.subdomain %> <%= f.button :submit, class: "btn button-color loading-button" do %> diff --git a/app/views/admin/lessons/edit.html.erb b/app/views/admin/lessons/edit.html.erb index 078b4f1c..baeae388 100644 --- a/app/views/admin/lessons/edit.html.erb +++ b/app/views/admin/lessons/edit.html.erb @@ -8,7 +8,7 @@

- <% @course.lessons.where.not(pub_status: "A").each do |lesson| %> + <% @course.lessons.each do |lesson| %> <%= render partial: "shared/lessons/admin_lesson_tile_link", locals: { course: @course, lesson: lesson } %> <% end %>
diff --git a/app/views/admin/lessons/new.html.erb b/app/views/admin/lessons/new.html.erb index 6b449d7b..40fc6a6d 100644 --- a/app/views/admin/lessons/new.html.erb +++ b/app/views/admin/lessons/new.html.erb @@ -1,6 +1,6 @@ <%= render "form" %> -<% unless @course.lessons.blank? %> +<% unless @course_lessons.blank? %>

Lessons

@@ -10,7 +10,7 @@

- <% @course.lessons.where.not(pub_status: "A").each do |lesson| %> + <% @course_lessons.each do |lesson| %> <%= render partial: "shared/lessons/admin_lesson_tile_link", locals: { course: @course, lesson: lesson } %> <% end %>
diff --git a/app/views/contacts/new.html.erb b/app/views/contacts/new.html.erb index 79185c01..fe4f9b86 100644 --- a/app/views/contacts/new.html.erb +++ b/app/views/contacts/new.html.erb @@ -27,26 +27,26 @@
<%= f.label :first_name, class: "screen-reader-text" %> - <%= f.text_field :first_name, placeholder: "First *", maxlength: 30 %> + <%= f.text_field :first_name, placeholder: "First *", maxlength: Contact.max_length_for(:first_name) %>
<%= f.label :last_name, class: "screen-reader-text" %> - <%= f.text_field :last_name, placeholder: "Last *", maxlength: 30 %> + <%= f.text_field :last_name, placeholder: "Last *", maxlength: Contact.max_length_for(:last_name) %>
<%= f.label :organization, class: "screen-reader-text" %> - <%= f.text_field :organization, placeholder: "Organization *", maxlength: 50 %> + <%= f.text_field :organization, placeholder: "Organization *", maxlength: Contact.max_length_for(:organization) %>
<%= f.label :city, class: "screen-reader-text" %> - <%= f.text_field :city, placeholder: "City *", maxlength: 30 %> + <%= f.text_field :city, placeholder: "City *", maxlength: Contact.max_length_for(:city) %>
@@ -58,18 +58,18 @@
<%= f.label :email, class: "screen-reader-text" %> - <%= f.text_field :email, placeholder: "Email *", maxlength: 30 %> + <%= f.text_field :email, placeholder: "Email *", maxlength: Contact.max_length_for(:email) %>
<%= f.label :phone, class: "screen-reader-text" %> - <%= f.text_field :phone, placeholder: "Phone", maxlength: 20 %> + <%= f.text_field :phone, placeholder: "Phone", maxlength: Contact.max_length_for(:phone) %>
<%= f.label :comments, class: "screen-reader-text" %> - <%= f.text_area :comments, placeholder: "Comments *", maxlength: 2048 %> + <%= f.text_area :comments, placeholder: "Comments *", maxlength: Contact.max_length_for(:comments) %>
diff --git a/app/views/course_completions/show.html.erb b/app/views/course_completions/show.html.erb index 5ae3aa65..7943718f 100644 --- a/app/views/course_completions/show.html.erb +++ b/app/views/course_completions/show.html.erb @@ -17,7 +17,7 @@ <% end %> <% end %> - <% if @course.notes.present? || !@course.post_course_attachments.empty? %> + <% if @course.notes.present? || !@course.additional_resource_attachments.empty? %> <%= link_to(course_skills_path(@course)) do %> <%= button_tag(type: 'button', class: "congrats-button button-color") do %> <%= t('course_completion_page.practice_skills') %> diff --git a/app/views/courses/designing_courses_1.html.erb b/app/views/courses/designing_courses_1.html.erb deleted file mode 100644 index 560baaaf..00000000 --- a/app/views/courses/designing_courses_1.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -

Designing DigitalLearn Courses - Part 1

- - -
-
-
We also have additional resources for your use, such as the DigitalLearn style sheet, Storyboard Template, and more.
-
-
- diff --git a/app/views/courses/designing_courses_2.html.erb b/app/views/courses/designing_courses_2.html.erb deleted file mode 100644 index 6cc986af..00000000 --- a/app/views/courses/designing_courses_2.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -

Designing DigitalLearn Courses - Part 2

- - -
-
-
We also have additional resources for your use, such as the DigitalLearn style sheet, Storyboard Template, and more.
-
-
- diff --git a/app/views/courses/show.html.erb b/app/views/courses/show.html.erb index eac46b20..287c11a3 100644 --- a/app/views/courses/show.html.erb +++ b/app/views/courses/show.html.erb @@ -1,11 +1,11 @@ -<%= render partial: "shared/courses/metas" %> +<%= render "shared/courses/metas" %> <%= link_to "Courses", courses_path %> >> <%= @course.title %>
-
<%= @course.lessons.published.count %> <%= t('course_page.lessons') %>
+
<%= @course.lessons.count %> <%= t('course_page.lessons') %>
<%= @course.duration("#{t('course_page.minutes')}") %>
<%= t("course_page.#{@course.level.downcase}") %>
@@ -14,13 +14,15 @@
- <% if user_signed_in? && current_user.has_role?(:admin, current_organization) %> + <% if org_admin? && policy(@course).edit? %>

<%= link_to "Edit Course >>", edit_admin_course_path(@course) %>

- <% else %> + <% end %> + + <% unless @preview %> <%= render 'courses/course_progress_actions' %> <% end %> - <%= start_or_resume_course_link(@course) %> + <%= start_or_resume_course_link(@course, @preview) %>
diff --git a/app/views/courses/skills.html.erb b/app/views/courses/skills.html.erb index 33af2d65..8162ce37 100644 --- a/app/views/courses/skills.html.erb +++ b/app/views/courses/skills.html.erb @@ -2,10 +2,5 @@ <%= link_to "Courses", courses_path %> >> <%= @course.title %> -<% content_for :left do %> - <%= render "shared/courses/course_notes" %> -<% end %> - -<% content_for :right do %> - <%= render "shared/courses/supplemental_materials" %> -<% end %> +<%= render "shared/courses/course_notes" %> +<%= render "shared/courses/supplemental_materials" %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 206494b7..3f61bfeb 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -7,6 +7,7 @@ <%= current_organization.subdomain %>"> <%= render "shared/layout/header" %> <%= render "shared/layout/banner" %> + <%= render "shared/courses/preview_notice" %>
<%= render "shared/flashes" %>
> diff --git a/app/views/lessons/lesson_complete.html.erb b/app/views/lessons/lesson_complete.html.erb index a2af8a38..afbba244 100644 --- a/app/views/lessons/lesson_complete.html.erb +++ b/app/views/lessons/lesson_complete.html.erb @@ -1,16 +1,16 @@

<%= t("completed_lesson_page.congratulations") %>

- <%= t("completed_lesson_page.youve_completed_activity") %> <%= @current_lesson.published_lesson_order %>: <%= @current_lesson.title %> + <%= t("completed_lesson_page.youve_completed_activity") %> <%= @current_lesson.lesson_order %>: <%= @current_lesson.title %>

<%= t("completed_lesson_page.up_next") %>:

<%= "#{@next_lesson.title} - " %> <%= t("completed_lesson_page.activity") %> - <%= @next_lesson.published_lesson_order %> + <%= @next_lesson.lesson_order %>

- <%= link_to t("completed_lesson_page.continue"), course_lesson_path(@course, @next_lesson), class: "btn small button-color" %> + <%= link_to t("completed_lesson_page.continue"), course_lesson_path(@course, @next_lesson, preview: @preview), class: "btn small button-color" %>   - <%= link_to t("completed_lesson_page.repeat_activity"), course_lesson_path(@course, @current_lesson), class: "grey" %> + <%= link_to t("completed_lesson_page.repeat_activity"), course_lesson_path(@course, @current_lesson, preview: @preview), class: "grey" %>
diff --git a/app/views/lessons/playlist/_grid.html.erb b/app/views/lessons/playlist/_grid.html.erb index 46bddb14..8744c19f 100644 --- a/app/views/lessons/playlist/_grid.html.erb +++ b/app/views/lessons/playlist/_grid.html.erb @@ -1,5 +1,5 @@
- <% @course.lessons.published.each_with_index do |lesson, i| %> + <% @course.lessons.each_with_index do |lesson, i| %> <%= render partial: "lessons/playlist/lesson_listing", locals: { lesson: lesson, lesson_number: i} %> <% end %>
\ No newline at end of file diff --git a/app/views/lessons/playlist/_header.html.erb b/app/views/lessons/playlist/_header.html.erb index bccb55e2..76492ed2 100644 --- a/app/views/lessons/playlist/_header.html.erb +++ b/app/views/lessons/playlist/_header.html.erb @@ -3,7 +3,7 @@
- <%= @course.lessons.published.count %> <%= t("course_page.lessons") %> + <%= @course.lessons.count %> <%= t("course_page.lessons") %>
diff --git a/app/views/lessons/playlist/_lesson_listing.html.erb b/app/views/lessons/playlist/_lesson_listing.html.erb index 6154fea4..3a933136 100644 --- a/app/views/lessons/playlist/_lesson_listing.html.erb +++ b/app/views/lessons/playlist/_lesson_listing.html.erb @@ -1,4 +1,4 @@ -<%= link_to course_lesson_path(@course, lesson), data: { cpl_ga_event: "on", cpl_ga_value: "user-click-lesson" }, class: "block_link lesson-listing_link" do %> +<%= link_to course_lesson_path(@course, lesson, preview: @preview), data: { cpl_ga_event: "on", cpl_ga_value: "user-click-lesson" }, class: "block_link lesson-listing_link" do %>
<% if lesson.id == @lesson.id %> diff --git a/app/views/lessons/show.html.erb b/app/views/lessons/show.html.erb index f40cc037..7d4a5810 100644 --- a/app/views/lessons/show.html.erb +++ b/app/views/lessons/show.html.erb @@ -5,7 +5,7 @@ <%= @lesson.summary %> <% end %> <%= content_for :callout, flush: true do %> -

<%="#{@lesson.published_lesson_order}. #{@lesson.title}" %>

+

<%="#{@lesson.lesson_order}. #{@lesson.title}" %>

<%= @lesson.duration_str %> <% end %> <%= content_for :course_progress do %> diff --git a/app/views/shared/courses/_course_progress.html.erb b/app/views/shared/courses/_course_progress.html.erb index a9971b8c..2e3ffb09 100644 --- a/app/views/shared/courses/_course_progress.html.erb +++ b/app/views/shared/courses/_course_progress.html.erb @@ -6,9 +6,9 @@ <% else %> <% end %> - <% lesson_count = course.lessons.published.count %> + <% lesson_count = course.lessons.count %> <% spacing = 100.0 / lesson_count %> - <% arrow_position = lesson.published_lesson_order * spacing - (spacing / 2) - 6 %> + <% arrow_position = lesson.lesson_order * spacing - (spacing / 2) - 6 %> <% lesson_count.times do |i| %> <% if i >= 1 %> @@ -24,7 +24,7 @@ <% end %> <% unless lesson.is_assessment %> - <%= link_to t('lesson_page.skip_to_next_lesson'), course_lesson_path(course, course.lesson_after(lesson)), class: "inverted" %> + <%= link_to t('lesson_page.skip_to_next_lesson'), course_lesson_path(course, course.lesson_after(lesson), preview: @preview), class: "inverted" %> <% end %> diff --git a/app/views/shared/courses/_preview_notice.html.erb b/app/views/shared/courses/_preview_notice.html.erb new file mode 100644 index 00000000..712a0229 --- /dev/null +++ b/app/views/shared/courses/_preview_notice.html.erb @@ -0,0 +1,9 @@ +<% if org_admin? && @preview %> +
+
+ You are previewing this course. + <%= link_to 'Import Course', admin_dashboard_add_imported_course_path(course_id: @course.id), method: :post %> + <%= link_to 'Return to Admin Dashboard', admin_import_courses_path %> +
+
+<% end %> \ No newline at end of file diff --git a/app/views/shared/courses/_supplemental_materials.html.erb b/app/views/shared/courses/_supplemental_materials.html.erb index 8f356009..b59d7ac1 100644 --- a/app/views/shared/courses/_supplemental_materials.html.erb +++ b/app/views/shared/courses/_supplemental_materials.html.erb @@ -1,8 +1,8 @@

<%= t('course_page.additional_resources') %>

-<% if @course.post_course_attachments.count > 0 %> +<% if @course.additional_resource_attachments.count > 0 %>
    - <% @course.post_course_attachments.each do |a| %> - <%= link_to course_attachment_path(@course, a), target: "_blank", class: "block_link" do %> + <% @course.additional_resource_attachments.each do |a| %> + <%= link_to attachment_path(a), target: "_blank", class: "block_link" do %>
  • <%= a.document_file_name %> diff --git a/app/views/shared/courses/_text_copies.html.erb b/app/views/shared/courses/_text_copies.html.erb index f8362048..d1421683 100644 --- a/app/views/shared/courses/_text_copies.html.erb +++ b/app/views/shared/courses/_text_copies.html.erb @@ -1,8 +1,8 @@

    <%= t('course_page.click_here_for_text_copy_course') %>

    -<% if @course.supplemental_attachments.count > 0 %> +<% if @course.text_copy_attachments.count > 0 %>
      - <% @course.supplemental_attachments.each do |a| %> - <%= link_to course_attachment_path(@course, a), target: "_blank", class: "block_link" do %> + <% @course.text_copy_attachments.each do |a| %> + <%= link_to attachment_path(a), target: "_blank", class: "block_link" do %>
    • <%= a.document_file_name %> diff --git a/app/views/shared/layout/_banner.html.erb b/app/views/shared/layout/_banner.html.erb index baecf3df..98a379d3 100644 --- a/app/views/shared/layout/_banner.html.erb +++ b/app/views/shared/layout/_banner.html.erb @@ -1,5 +1,5 @@