rewrite content_notices to use InstUI Alert
test plan: - enable redis - in the rails console, for a given course, do course.add_content_notice :import_in_progress, 1.hour - navigate to a page in that course as a user who has manage_content permission - the "One ore more items are currently being imported" message should appear at the top of the page and should be read to screenreaders fixes ADMIN-2208 Change-Id: I39f2efe231c27e009aee0b13bbe26dc8fa37bad5 Reviewed-on: https://gerrit.instructure.com/175149 Tested-by: Jenkins Reviewed-by: Ed Schiebel <eschiebel@instructure.com> QA-Review: Daniel Sasaki <dsasaki@instructure.com> Product-Review: Daniel Sasaki <dsasaki@instructure.com>
This commit is contained in:
parent
61d771b12c
commit
c12de7d5f8
|
@ -332,6 +332,27 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
helper_method :load_blueprint_courses_ui
|
||||
|
||||
def load_content_notices
|
||||
if @context && @context.respond_to?(:content_notices)
|
||||
notices = @context.content_notices(@current_user)
|
||||
if notices.any?
|
||||
js_env :CONTENT_NOTICES => notices.map { |notice|
|
||||
{
|
||||
tag: notice.tag,
|
||||
variant: notice.variant || 'info',
|
||||
text: notice.text.is_a?(Proc) ? notice.text.call : notice.text,
|
||||
link_text: notice.link_text.is_a?(Proc) ? notice.link_text.call : notice.link_text,
|
||||
link_target: notice.link_target.is_a?(Proc) ? notice.link_target.call(@context) : notice.link_target
|
||||
}
|
||||
}
|
||||
js_bundle :content_notices
|
||||
return true
|
||||
end
|
||||
end
|
||||
false
|
||||
end
|
||||
helper_method :load_content_notices
|
||||
|
||||
def editing_restricted?(content, edit_type=:any)
|
||||
return false unless content.respond_to?(:editing_restricted?)
|
||||
content.editing_restricted?(edit_type)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2018 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import Alert from '@instructure/ui-alerts/lib/components/Alert'
|
||||
import Link from '@instructure/ui-elements/lib/components/Link'
|
||||
import Text from '@instructure/ui-elements/lib/components/Text'
|
||||
|
||||
const container = document.getElementById('content_notice_container')
|
||||
if (container && ENV.CONTENT_NOTICES.length > 0) {
|
||||
const alerts = ENV.CONTENT_NOTICES.map(notice => {
|
||||
let link = null
|
||||
if (notice.link_text && notice.link_target) {
|
||||
link = <Link href={notice.link_target}>{notice.link_text}</Link>
|
||||
}
|
||||
return <Alert key={notice.tag} variant={notice.variant} liveRegion={() => document.getElementById('flash_screenreader_holder')}>
|
||||
<Text>{notice.text}</Text> {link}
|
||||
</Alert>
|
||||
})
|
||||
ReactDOM.render(alerts, container)
|
||||
}
|
|
@ -240,9 +240,9 @@ class Course < ActiveRecord::Base
|
|||
|
||||
include ContentNotices
|
||||
define_content_notice :import_in_progress,
|
||||
icon_class: 'icon-import-content',
|
||||
alert_class: 'alert-info import-in-progress-notice',
|
||||
template: 'courses/import_in_progress_notice',
|
||||
text: -> { t('One or more items are currently being imported. They will be shown in the course below once they are available.') },
|
||||
link_text: -> { t('Import Status') },
|
||||
link_target: ->(course) { "/courses/#{course.to_param}/content_migrations" },
|
||||
should_show: ->(course, user) do
|
||||
course.grants_right?(user, :manage_content)
|
||||
end
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
<%
|
||||
# Copyright (C) 2014 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<span><%= t('course_import_notice.text', 'One or more items are currently being imported. They will be shown in the course below once they are available.') %></span>
|
||||
 <%= link_to t('course_import_notice.status_link', 'Import Status'), context_url(@context, :context_content_migrations_url) %>
|
|
@ -75,6 +75,7 @@
|
|||
content_for :head, include_common_stylesheets
|
||||
|
||||
load_blueprint_courses_ui
|
||||
@has_content_notices = load_content_notices
|
||||
-%>
|
||||
<%= render :partial => "layouts/head" %>
|
||||
<body class="<%= (@body_classes).uniq.join(" ") %> lato-font-not-loaded-yet">
|
||||
|
@ -151,7 +152,7 @@
|
|||
<% end %>
|
||||
<div id="not_right_side" class="ic-app-main-content">
|
||||
<div id="content-wrapper" class="ic-Layout-contentWrapper">
|
||||
<%= render :partial => 'shared/content_notices' if @show_left_side && @context && @context.respond_to?(:content_notices) %>
|
||||
<%= render :partial => 'shared/content_notices' if @has_content_notices && @show_left_side %>
|
||||
<div id="content" class="ic-Layout-contentMain" role="main">
|
||||
<%= yield %>
|
||||
</div>
|
||||
|
|
|
@ -16,15 +16,4 @@
|
|||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
%>
|
||||
|
||||
<% @context.content_notices(@current_user).each do |notice| %>
|
||||
<div class="content_notice alert <%= notice.alert_class %>">
|
||||
<% if notice.icon_class %>
|
||||
<i class="<%= notice.icon_class %>"></i>
|
||||
<% end %>
|
||||
<% if notice.template %>
|
||||
<%= render partial: notice.template %>
|
||||
<% else %>
|
||||
<%= notice.text.is_a?(Proc) ? notice.call : notice %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="content_notice_container"></div>
|
||||
|
|
|
@ -17,20 +17,20 @@
|
|||
#
|
||||
|
||||
module ContentNotices
|
||||
NOTICE_ATTRIBUTES = [:tag, :text, :template, :alert_class, :icon_class, :should_show]
|
||||
NOTICE_ATTRIBUTES = [:tag, :text, :variant, :link_text, :link_target, :should_show]
|
||||
|
||||
class ContentNotice
|
||||
attr_accessor *NOTICE_ATTRIBUTES
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# opts must include exactly one of:
|
||||
# text: string (or Proc that returns string) containing text for the notice
|
||||
# template: erb partial containing html content for the notice
|
||||
# opts must include:
|
||||
# text: string (or Proc that returns string): text for the notice
|
||||
# opts may optionally contain:
|
||||
# alert_class: CSS class(es) for the notice box (suggestions: 'alert-info', 'alert-success', 'alert-error')
|
||||
# icon_class: CSS class(es) for the icon (suggestions: 'icon-info', 'icon-check', 'icon-warning')
|
||||
# should_show: callback that receives the context and user, and returns whether the notice should be displayed
|
||||
# variant: string: InstUI alert variant ('info', 'success', 'error', 'warning'; default is 'info')
|
||||
# link_text: string (or Proc that returns string): text for a link that follows the notice
|
||||
# link_target: string (or Proc that takes the context and returns a string): the target for said link
|
||||
# should_show: Proc: callback that receives the context and user, and returns whether the notice should be displayed
|
||||
# see course.rb for example usage
|
||||
def define_content_notice(tag, opts)
|
||||
notice = ContentNotice.new
|
||||
|
|
|
@ -49,14 +49,12 @@ describe "course" do
|
|||
migration.update_attribute(:workflow_state, 'importing')
|
||||
get "/courses/#{@course.id}"
|
||||
expect(response).to be_successful
|
||||
body = Nokogiri::HTML(response.body)
|
||||
expect(body.css('div.import-in-progress-notice')).not_to be_empty
|
||||
expect(controller.js_env[:CONTENT_NOTICES].map { |cn| cn[:tag] }).to include :import_in_progress
|
||||
|
||||
migration.update_attribute(:workflow_state, 'imported')
|
||||
get "/courses/#{@course.id}"
|
||||
expect(response).to be_successful
|
||||
body = Nokogiri::HTML(response.body)
|
||||
expect(body.css('div.import-in-progress-notice')).to be_empty
|
||||
expect((controller.js_env[:CONTENT_NOTICES] || []).map { |cn| cn[:tag] }).not_to include :import_in_progress
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,8 +70,7 @@ describe "course" do
|
|||
migration.update_attribute(:workflow_state, 'importing')
|
||||
get "/courses/#{@course.id}"
|
||||
expect(response).to be_successful
|
||||
body = Nokogiri::HTML(response.body)
|
||||
expect(body.css('div.import-in-progress-notice')).to be_empty
|
||||
expect((controller.js_env[:CONTENT_NOTICES] || []).map { |cn| cn[:tag] }).not_to include :import_in_progress
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ describe ContentNotices do
|
|||
def asset_string; "thing_1"; end
|
||||
include ContentNotices
|
||||
define_content_notice :foo, text: 'foo!'
|
||||
define_content_notice :bar, template: 'some_template', should_show: ->(thing, user) { user == 'bob' }
|
||||
define_content_notice :bar, text: 'baz', should_show: ->(thing, user) { user == 'bob' }
|
||||
end
|
||||
|
||||
describe "content_notices" do
|
||||
|
|
Loading…
Reference in New Issue