add api for listing visible navigation tabs
test plan: - fetch tab list using some command like: curl -H 'Authorization: Bearer <token>' \ https://<canvas>/api/v1/courses/<course_id>/tabs\?include\="external" - ensure that the returned list corresponds to the left-hand tab list on the web interface fixes #10891 Change-Id: If3371472b58f849a9736ab6747f69551178e99a4 Reviewed-on: https://gerrit.instructure.com/14615 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Zach Pendleton <zachp@instructure.com>
This commit is contained in:
parent
181d300e2d
commit
7b93ba46f0
|
@ -1328,4 +1328,53 @@ class CoursesController < ApplicationController
|
|||
:nothing
|
||||
end
|
||||
end
|
||||
|
||||
include Api::V1::Tab
|
||||
# @API List available tabs
|
||||
# Returns a list of navigation tabs available in the current context.
|
||||
#
|
||||
# @argument include[] ["external"] Optionally include external tool tabs in the returned list of tabs
|
||||
#
|
||||
# @example_request
|
||||
# curl -H 'Authorization: Bearer <token>' \
|
||||
# https://<canvas>/api/v1/courses/<course_id>/tabs\?include\="external"
|
||||
#
|
||||
# @example_response
|
||||
# [
|
||||
# {
|
||||
# "html_url": "/courses/1",
|
||||
# "id": "home",
|
||||
# "label": "Home",
|
||||
# "type": "internal"
|
||||
# },
|
||||
# {
|
||||
# "html_url": "/courses/1/external_tools/4",
|
||||
# "id": "context_external_tool_4",
|
||||
# "label": "WordPress",
|
||||
# "type": "external"
|
||||
# },
|
||||
# {
|
||||
# "html_url": "/courses/1/grades",
|
||||
# "id": "grades",
|
||||
# "label": "Grades",
|
||||
# "type": "internal"
|
||||
# }
|
||||
# ]
|
||||
def tabs
|
||||
get_context
|
||||
includes = Array(params[:include])
|
||||
tabs = @context.tabs_available(@current_user, :include_external => includes.include?('external'))
|
||||
tabs = tabs.select do |tab|
|
||||
if (tab[:id] == @context.class::TAB_CHAT rescue false)
|
||||
tab[:href] && tab[:label] && feature_enabled?(:tinychat)
|
||||
elsif (tab[:id] == @context.class::TAB_COLLABORATIONS rescue false)
|
||||
tab[:href] && tab[:label] && Collaboration.any_collaborations_configured?
|
||||
elsif (tab[:id] == @context.class::TAB_CONFERENCES rescue false)
|
||||
tab[:href] && tab[:label] && feature_enabled?(:web_conferences)
|
||||
else
|
||||
tab[:href] && tab[:label]
|
||||
end
|
||||
end
|
||||
render :json => tabs_available_json(tabs, @current_user, session)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2556,12 +2556,13 @@ class Course < ActiveRecord::Base
|
|||
def tabs_available(user=nil, opts={})
|
||||
# make sure t() is called before we switch to the slave, in case we update the user's selected locale in the process
|
||||
default_tabs = Course.default_tabs
|
||||
opts.reverse_merge!(:include_external => true)
|
||||
|
||||
ActiveRecord::Base::ConnectionSpecification.with_environment(:slave) do
|
||||
# We will by default show everything in default_tabs, unless the teacher has configured otherwise.
|
||||
tabs = self.tab_configuration.compact
|
||||
settings_tab = default_tabs[-1]
|
||||
external_tabs = external_tool_tabs(opts)
|
||||
external_tabs = (opts[:include_external] && external_tool_tabs(opts)) || []
|
||||
tabs = tabs.map do |tab|
|
||||
default_tab = default_tabs.find {|t| t[:id] == tab[:id] } || external_tabs.find{|t| t[:id] == tab[:id] }
|
||||
if default_tab
|
||||
|
|
|
@ -661,6 +661,7 @@ ActionController::Routing::Routes.draw do |map|
|
|||
courses.post 'courses/:course_id/files', :action => :create_file
|
||||
courses.post 'courses/:course_id/folders', :controller => :folders, :action => :create
|
||||
courses.get 'courses/:course_id/folders/:id', :controller => :folders, :action => :show, :path_name => 'course_folder'
|
||||
courses.get 'courses/:course_id/tabs', :action => :tabs, :path_name => "course_tabs"
|
||||
end
|
||||
|
||||
api.with_options(:controller => :sections) do |sections|
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# Copyright (C) 2012 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/>.
|
||||
#
|
||||
|
||||
module Api::V1::Tab
|
||||
include Api::V1::Json
|
||||
|
||||
def tabs_available_json(tabs, user, session)
|
||||
tabs.map do |tab|
|
||||
tab_json(tab, user, session)
|
||||
end
|
||||
end
|
||||
|
||||
def tab_json(tab, user, session)
|
||||
hash = {}
|
||||
if tab[:args]
|
||||
hash[:html_url] = send(tab[:href], *tab[:args])
|
||||
elsif tab[:no_args]
|
||||
hash[:html_url] = send(tab[:href])
|
||||
else
|
||||
hash[:html_url] = send(tab[:href], @context)
|
||||
end
|
||||
hash[:label] = tab[:label]
|
||||
hash[:id] = tab[:css_class]
|
||||
hash[:type] = (tab[:external] && 'external') || 'internal'
|
||||
api_json(hash, user, session)
|
||||
end
|
||||
end
|
|
@ -951,6 +951,95 @@ describe CoursesController, :type => :integration do
|
|||
json.map{ |el| el['id'] }.should == [@student2.id, @student3.id, @student1.id]
|
||||
end
|
||||
end
|
||||
|
||||
describe '/tabs' do
|
||||
it 'should list navigation tabs' do
|
||||
@user = @course1.teachers.first
|
||||
json = api_call(:get, "/api/v1/courses/#{@course1.id}/tabs",
|
||||
{ :controller => 'courses', :action => 'tabs', :course_id => @course1.to_param, :format => 'json'},
|
||||
{ :include => ['external']})
|
||||
json.should == [
|
||||
{
|
||||
"id" => "home",
|
||||
"html_url" => "/courses/#{@course1.id}",
|
||||
"type" => "internal",
|
||||
"label" => "Home"
|
||||
},
|
||||
{
|
||||
"id" => "announcements",
|
||||
"label" => "Announcements",
|
||||
"html_url" => "/courses/#{@course1.id}/announcements",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "assignments",
|
||||
"html_url" => "/courses/#{@course1.id}/assignments",
|
||||
"label" => "Assignments",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "discussions",
|
||||
"html_url" => "/courses/#{@course1.id}/discussion_topics",
|
||||
"label" => "Discussions",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "grades",
|
||||
"html_url" => "/courses/#{@course1.id}/grades",
|
||||
"label" => "Grades",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "people",
|
||||
"html_url" => "/courses/#{@course1.id}/users",
|
||||
"label" => "People",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "pages",
|
||||
"html_url" => "/courses/#{@course1.id}/wiki",
|
||||
"label" => "Pages",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "files",
|
||||
"html_url" => "/courses/#{@course1.id}/files",
|
||||
"label" => "Files",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "syllabus",
|
||||
"html_url" => "/courses/#{@course1.id}/assignments/syllabus",
|
||||
"label" => "Syllabus",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "outcomes",
|
||||
"html_url" => "/courses/#{@course1.id}/outcomes",
|
||||
"label" => "Outcomes",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "quizzes",
|
||||
"html_url" => "/courses/#{@course1.id}/quizzes",
|
||||
"label" => "Quizzes",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "modules",
|
||||
"html_url" => "/courses/#{@course1.id}/modules",
|
||||
"label" => "Modules",
|
||||
"type" => "internal"
|
||||
},
|
||||
{
|
||||
"id" => "settings",
|
||||
"html_url" => "/courses/#{@course1.id}/settings",
|
||||
"label" => "Settings",
|
||||
"type" => "internal"
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def each_copy_option
|
||||
|
|
|
@ -922,6 +922,26 @@ describe Course, "tabs_available" do
|
|||
tabs.should be_include(t1.asset_string)
|
||||
tabs.should_not be_include(t2.asset_string)
|
||||
end
|
||||
|
||||
it "should not include tabs for external tools if opt[:include_external] is false" do
|
||||
course_with_student(:active_all => true)
|
||||
|
||||
t1 = @course.context_external_tools.create!(
|
||||
:url => "http://example.com/ims/lti",
|
||||
:consumer_key => "asdf",
|
||||
:shared_secret => "hjkl",
|
||||
:name => "external tool 1",
|
||||
:course_navigation => {
|
||||
:text => "blah",
|
||||
:url => "http://example.com/ims/lti",
|
||||
:default => false,
|
||||
}
|
||||
)
|
||||
|
||||
tabs = @course.tabs_available(nil, :include_external => false).map { |tab| tab[:id] }
|
||||
|
||||
tabs.should_not be_include(t1.asset_string)
|
||||
end
|
||||
end
|
||||
|
||||
describe Course, "backup" do
|
||||
|
|
Loading…
Reference in New Issue