conversations: support messages to account-level groups

fixes CNVS-10776

test plan:
  * log in as a user in an account-level group
  * open conversations
  * compose a message
  * verify that you can address the message to the group

Change-Id: Icb3d840e1d17cabb94394cc564f6d3c5b5f606e0
Reviewed-on: https://gerrit.instructure.com/35309
QA-Review: Braden Anderson <banderson@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Ethan Vizitei <evizitei@instructure.com>
This commit is contained in:
Braden Anderson 2014-05-21 18:02:28 -06:00
parent 36eed6f01c
commit 6fd0c9fe0e
7 changed files with 58 additions and 13 deletions

View File

@ -13,9 +13,10 @@ require [
'compiled/util/deparam'
'compiled/collections/CourseCollection'
'compiled/collections/FavoriteCourseCollection'
'compiled/collections/GroupCollection'
'jquery.disableWhileLoading'
], (I18n, $, _, Backbone, Message, MessageCollection, MessageView, MessageListView, MessageDetailView, MessageFormDialog,
InboxHeaderView, deparam, CourseCollection, FavoriteCourseCollection) ->
InboxHeaderView, deparam, CourseCollection, FavoriteCourseCollection, GroupCollection) ->
class ConversationsRouter extends Backbone.Router
@ -194,9 +195,10 @@ require [
remoteLaunch: true
_initCollections: () ->
@courses =
@courses =
favorites: new FavoriteCourseCollection()
all: new CourseCollection()
groups: new GroupCollection()
@courses.favorites.fetch()
_initViews: ->

View File

@ -29,6 +29,8 @@ define [
@optionProperty 'category'
@optionProperty 'loadAll'
_defaultUrl: -> '/api/v1/users/self/groups'
url: ->
if @category?
@url = "/api/v1/group_categories/#{@category.id}/groups?per_page=50"

View File

@ -24,6 +24,8 @@ define [
@options.courses.favorites.on('reset', @render)
@options.courses.all.on('reset', @render)
@options.courses.all.on('add', @render)
@options.courses.groups.on('reset', @render)
@options.courses.groups.on('add', @render)
@render()
render: () =>
@ -43,7 +45,8 @@ define [
defaultOption: @options.defaultOption,
favorites: @options.courses.favorites.toJSON(),
more: more,
concluded: concluded
concluded: concluded,
groups: @options.courses.groups.toJSON()
@truncate_course_name_data(data)
@$el.html(template(data))
@$el.selectpicker('refresh')
@ -63,6 +66,7 @@ define [
if all._loading then return
all.fetch()
all._loading = true
@options.courses.groups.fetch()
@$picker.find('> .dropdown-menu').append($('<div />').attr('class', 'paginatedLoadingIndicator').css('clear', 'both'))
_value: ''
@ -84,20 +88,25 @@ define [
@searchViews.forEach (view) ->
view.clearSearch()
getCurrentCourse: ->
course_id = @_value.replace('course_', '')
course = @options.courses.favorites.get(course_id)
course = @options.courses.all.get(course_id) if !course
return if course then {name: course.get('name'), id: @_value} else {}
getCurrentContext: ->
matches = @_value.match(/(\w+)_(\d+)/)
return {} unless matches
[match, type, id] = matches
context = if type == 'course'
course = @options.courses.favorites.get(id) ||
@options.courses.all.get(id)
else
@options.courses.groups.get(id)
return if context then {name: context.get('name'), id: @_value} else {}
triggerEvent: ->
@trigger('course', @getCurrentCourse())
@trigger('course', @getCurrentContext())
focus: ->
@$el.next().find('.dropdown-toggle').focus()
truncate_course_name_data: (course_data) ->
_.each(['favorites', 'more', 'concluded'], (key) =>
_.each(['favorites', 'more', 'concluded', 'groups'], (key) =>
@truncate_course_names(course_data[key])
)

View File

@ -140,13 +140,13 @@ define [
filterObj: (obj) -> _.object(_.filter(_.pairs(obj), (x) -> !!x[1]))
onFilterChange: (e) =>
@searchView?.autocompleteView.setContext(@courseView.getCurrentCourse())
@searchView?.autocompleteView.setContext(@courseView.getCurrentContext())
@trigger('filter', @filterObj({type: @$typeFilter.val(), course: @$courseFilter.val()}))
displayState: (state) ->
@$typeFilter.selectpicker('val', state.type)
@courseView.setValue(state.course)
@trigger('course', @courseView.getCurrentCourse())
@trigger('course', @courseView.getCurrentContext())
toggleMessageBtns: (value) ->
@toggleReplyBtn(value)

View File

@ -0,0 +1,10 @@
<option value="group_{{id}}"
{{#if truncated_name}}
aria-label="{{name}}" data-content="<abbr class='text' data-value='{{id}}' title='{{name}}'>{{truncated_name}}</abbr>"
>
{{truncated_name}}
{{else}}
>
{{name}}
{{/if}}
</option>

View File

@ -12,3 +12,8 @@
{{>[conversations/courseOption]}}
{{/concluded}}
</optgroup>
<optgroup label="{{#t "course_options.groups"}}Groups{{/t}}">
{{#groups}}
{{>[conversations/groupOption]}}
{{/groups}}
</optgroup>

View File

@ -91,9 +91,13 @@ describe "conversations new" do
end
end
def select_message_course(new_course)
def select_message_course(new_course, is_group = false)
new_course = new_course.name if new_course.respond_to? :name
fj('.dropdown-toggle', get_message_course).click
if is_group
wait_for_ajaximations
fj("a:contains('Groups')", get_message_course).click
end
fj("a:contains('#{new_course}')", get_message_course).click
end
@ -177,6 +181,19 @@ describe "conversations new" do
fj('#compose-new-message .ac-input').should have_attribute(:disabled, 'true')
end
it "should allow non-admins to send a message to an account-level group" do
@group = Account.default.groups.create(:name => "the group")
@group.add_user(@s1)
@group.add_user(@s2)
@group.save
user_logged_in({:user => @s1})
get_conversations
fj('#compose-btn').click
wait_for_ajaximations
select_message_course(@group, true)
add_message_recipient @s2
end
it "should allow admins to message users from their profiles" do
user = account_admin_user
user_logged_in({:user => user})