203 lines
5.9 KiB
Ruby
203 lines
5.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2011 - 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/>.
|
|
#
|
|
|
|
class UserProfile < ActiveRecord::Base
|
|
belongs_to :user
|
|
|
|
delegate :short_name, :name, :asset_string, :opaque_identifier, to: :user
|
|
|
|
has_many :links, inverse_of: :user_profile, class_name: "UserProfileLink", dependent: :destroy
|
|
|
|
validates :title,
|
|
length: {
|
|
maximum: maximum_string_length, too_long: "%{count} characters is the maximum allowed"
|
|
},
|
|
allow_blank: true
|
|
validates :bio,
|
|
length: {
|
|
maximum: maximum_text_length, too_long: "%{count} characters is the maximum allowed"
|
|
},
|
|
allow_blank: true
|
|
|
|
TAB_PROFILE,
|
|
TAB_COMMUNICATION_PREFERENCES,
|
|
TAB_FILES,
|
|
TAB_EPORTFOLIOS,
|
|
TAB_PROFILE_SETTINGS,
|
|
TAB_OBSERVEES,
|
|
TAB_QR_MOBILE_LOGIN,
|
|
TAB_PAST_GLOBAL_ANNOUNCEMENTS,
|
|
TAB_CONTENT_SHARES =
|
|
*0..10
|
|
|
|
BASE_TABS = [
|
|
{
|
|
id: TAB_COMMUNICATION_PREFERENCES,
|
|
label: -> { I18n.t("#user_profile.tabs.notifications", "Notifications") },
|
|
css_class: "notifications",
|
|
href: :communication_profile_path,
|
|
no_args: true
|
|
}.freeze,
|
|
{
|
|
id: TAB_FILES,
|
|
label: -> { I18n.t("#tabs.files", "Files") },
|
|
css_class: "files",
|
|
href: :files_path,
|
|
no_args: true
|
|
}.freeze,
|
|
{
|
|
id: TAB_PROFILE_SETTINGS,
|
|
label: -> { I18n.t("#user_profile.tabs.settings", "Settings") },
|
|
css_class: "profile_settings",
|
|
href: :settings_profile_path,
|
|
no_args: true
|
|
}.freeze
|
|
].freeze
|
|
|
|
set_policy do
|
|
given do |user, account|
|
|
return unless user
|
|
|
|
user_roles = Lti::SubstitutionsHelper.new(account, account.root_account, user).all_roles
|
|
user_roles.include?("urn:lti:instrole:ims/lis/Administrator")
|
|
end
|
|
can :view_lti_tool
|
|
end
|
|
|
|
def tabs_available(user = nil, opts = {})
|
|
@tabs ||=
|
|
begin
|
|
tabs =
|
|
BASE_TABS.map do |tab|
|
|
new_tab = tab.dup
|
|
new_tab[:label] = tab[:label].call
|
|
new_tab
|
|
end
|
|
insert_profile_tab(tabs, user, opts)
|
|
insert_eportfolios_tab(tabs, user)
|
|
insert_content_shares_tab(tabs, user, opts)
|
|
insert_lti_tool_tabs(tabs, user, opts) if user && opts[:root_account]
|
|
tabs = tabs.slice(0, 2) if user&.fake_student?
|
|
insert_observer_tabs(tabs, user)
|
|
insert_qr_mobile_login_tab(tabs, user, opts)
|
|
insert_past_global_announcements(tabs, user, opts)
|
|
tabs
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def insert_profile_tab(tabs, user, opts)
|
|
if user && opts[:root_account] && opts[:root_account].enable_profiles?
|
|
tabs.insert 1,
|
|
{
|
|
id: TAB_PROFILE,
|
|
label: I18n.t("#user_profile.tabs.profile", "Profile"),
|
|
css_class: "profile",
|
|
href: :profile_path,
|
|
no_args: true
|
|
}
|
|
end
|
|
end
|
|
|
|
def insert_eportfolios_tab(tabs, user)
|
|
if user.eportfolios_enabled?
|
|
tabs <<
|
|
{
|
|
id: TAB_EPORTFOLIOS,
|
|
label: I18n.t("#tabs.eportfolios", "ePortfolios"),
|
|
css_class: "eportfolios",
|
|
href: :dashboard_eportfolios_path,
|
|
no_args: true
|
|
}
|
|
end
|
|
end
|
|
|
|
def insert_content_shares_tab(tabs, user, _opts)
|
|
if user&.can_view_content_shares?
|
|
tabs <<
|
|
{
|
|
id: TAB_CONTENT_SHARES,
|
|
label: I18n.t("Shared Content"),
|
|
css_class: "content_shares",
|
|
href: :content_shares_profile_path,
|
|
no_args: true
|
|
}
|
|
end
|
|
end
|
|
|
|
def insert_lti_tool_tabs(tabs, user, opts)
|
|
tools = Lti::ContextToolFinder.new(opts[:root_account], type: :user_navigation).all_tools_scope_union.to_unsorted_array
|
|
.select { |t| t.permission_given?(:user_navigation, user, opts[:root_account]) }
|
|
tabs.concat(
|
|
Lti::ExternalToolTab.new(user, :user_navigation, tools, opts[:language]).tabs
|
|
.find_all { |tab| show_lti_tab?(tab, user, opts[:root_account]) }
|
|
)
|
|
end
|
|
|
|
def show_lti_tab?(tab, user, account)
|
|
tab[:visibility] != "admins" || grants_right?(user, account, :view_lti_tool)
|
|
end
|
|
|
|
def insert_observer_tabs(tabs, user)
|
|
if user&.as_observer_observation_links&.active&.exists?
|
|
tabs <<
|
|
{
|
|
id: TAB_OBSERVEES,
|
|
label: I18n.t("#tabs.observees", "Observing"),
|
|
css_class: "observees",
|
|
href: :observees_profile_path,
|
|
no_args: true
|
|
}
|
|
end
|
|
end
|
|
|
|
def insert_qr_mobile_login_tab(tabs, user, opts)
|
|
if user && instructure_misc_plugin_available? && opts[:root_account]&.mobile_qr_login_is_enabled?
|
|
tabs <<
|
|
{
|
|
id: TAB_QR_MOBILE_LOGIN,
|
|
label: I18n.t("#tabs.qr_mobile_login", "QR for Mobile Login"),
|
|
css_class: "qr_mobile_login",
|
|
href: :qr_mobile_login_path,
|
|
no_args: true
|
|
}
|
|
end
|
|
end
|
|
|
|
def insert_past_global_announcements(tabs, user, _opts)
|
|
if user
|
|
tabs <<
|
|
{
|
|
id: TAB_PAST_GLOBAL_ANNOUNCEMENTS,
|
|
label: I18n.t("#tabs.past_global_announcements", "Global Announcements"),
|
|
css_class: "past_global_announcements",
|
|
href: :account_notifications_path,
|
|
no_args: { include_past: true }
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def instructure_misc_plugin_available?
|
|
Object.const_defined?(:InstructureMiscPlugin)
|
|
end
|
|
private :instructure_misc_plugin_available?
|