diff --git a/lms/djangoapps/teams/static/teams/js/models/team.js b/lms/djangoapps/teams/static/teams/js/models/team.js index 010116e3717e..fdab4fb7d48f 100644 --- a/lms/djangoapps/teams/static/teams/js/models/team.js +++ b/lms/djangoapps/teams/static/teams/js/models/team.js @@ -16,7 +16,9 @@ country: '', language: '', membership: [], - last_activity_at: '' + last_activity_at: '', + professor: '', + content_group: '', }, initialize: function(options) { diff --git a/lms/djangoapps/teams/static/teams/js/views/edit_team.js b/lms/djangoapps/teams/static/teams/js/views/edit_team.js index 4413faf5de33..a6e4568ab5fb 100644 --- a/lms/djangoapps/teams/static/teams/js/views/edit_team.js +++ b/lms/djangoapps/teams/static/teams/js/views/edit_team.js @@ -27,6 +27,9 @@ this.topic = options.topic; this.collection = options.collection; this.action = options.action; + this.contentGroupsNameMap = _.map(this.context.contentGroups, function(group) { + return [group.id, group.name] + }); if (this.action === 'create') { this.teamModel = new TeamModel({}); @@ -57,6 +60,27 @@ + 'goals or direction of the team (maximum 300 characters).') }); + this.teamProfessorField = new FieldViews.TextareaFieldView({ + model: this.teamModel, + title: gettext('Professor in charge (Required) *'), + valueAttribute: 'professor', + editable: 'always', + showMessages: false, + helpMessage: gettext( + 'The name of the professor in charge of the team (maximum 300 characters).') + }); + + this.teamContentGroupsField = new FieldViews.DropdownFieldView({ + model: this.teamModel, + title: gettext('Content Groups'), + valueAttribute: 'content_group', + required: false, + showMessages: false, + options: this.contentGroupsNameMap, + helpMessage: gettext( + 'The content groups that the team is associated with.') + }); + this.teamLanguageField = new FieldViews.DropdownFieldView({ model: this.teamModel, title: gettext('Language'), @@ -92,6 +116,8 @@ ); this.set(this.teamNameField, '.team-required-fields'); this.set(this.teamDescriptionField, '.team-required-fields'); + this.set(this.teamProfessorField, '.team-required-fields'); + this.set(this.teamContentGroupsField, '.team-optional-fields'); this.set(this.teamLanguageField, '.team-optional-fields'); this.set(this.teamCountryField, '.team-optional-fields'); return this; @@ -105,17 +131,20 @@ this.$(selector).append(view.render().$el); } }, - createOrUpdateTeam: function(event) { event.preventDefault(); var view = this, // eslint-disable-line vars-on-top teamLanguage = this.teamLanguageField.fieldValue(), teamCountry = this.teamCountryField.fieldValue(), + teamContentGroup = this.teamContentGroupsField.fieldValue(), data = { name: this.teamNameField.fieldValue(), description: this.teamDescriptionField.fieldValue(), + professor: this.teamProfessorField.fieldValue(), language: _.isNull(teamLanguage) ? '' : teamLanguage, - country: _.isNull(teamCountry) ? '' : teamCountry + country: _.isNull(teamCountry) ? '' : teamCountry, + content_group: _.isNull(teamContentGroup) ? '' : teamContentGroup, + user_partition_id: this.context.partitionID }, saveOptions = { wait: true diff --git a/lms/djangoapps/teams/templates/teams/teams.html b/lms/djangoapps/teams/templates/teams/teams.html index 3dfa5b51aeb6..ce64a5b159ee 100644 --- a/lms/djangoapps/teams/templates/teams/teams.html +++ b/lms/djangoapps/teams/templates/teams/teams.html @@ -24,6 +24,10 @@ <%include file="/courseware/course_navigation.html" args="active_page='teams'" /> +<%! +from openedx.core.djangoapps.course_groups.partition_scheme import get_grouped_user_partition +%> +
@@ -38,7 +42,21 @@ <%include file="../discussion/_js_body_dependencies.html" /> <%static:require_module module_name="teams/js/teams_tab_factory" class_name="TeamsTabFactory"> - TeamsTabFactory({ + <% + grouped_user_partition = get_grouped_user_partition(course) + content_groups = grouped_user_partition.groups if grouped_user_partition else [] + %> + var groupUserPartitionId = ${grouped_user_partition.id if grouped_user_partition else None | n, dump_js_escaped_json}, + contentGroups = [ + % for content_group in content_groups: + { + id: ${content_group.id | n, dump_js_escaped_json}, + name: "${content_group.name | n, js_escaped_string}", + user_partition_id: groupUserPartitionId + }, + % endfor + ]; + TeamsTabFactory({ courseID: '${str(course.id) | n, js_escaped_string}', topics: ${topics | n, dump_js_escaped_json}, hasManagedTopic: ${has_managed_teamset | n, dump_js_escaped_json}, @@ -59,7 +77,9 @@ courseMaxTeamSize: ${course.teams_configuration.default_max_team_size | n, dump_js_escaped_json}, languages: ${languages | n, dump_js_escaped_json}, countries: ${countries | n, dump_js_escaped_json}, - teamsBaseUrl: '${teams_base_url | n, js_escaped_string}' + teamsBaseUrl: '${teams_base_url | n, js_escaped_string}', + contentGroups: contentGroups, + partitionID: groupUserPartitionId, }); diff --git a/lms/djangoapps/teams/views.py b/lms/djangoapps/teams/views.py index a5370ffa937f..fea8dc311eed 100644 --- a/lms/djangoapps/teams/views.py +++ b/lms/djangoapps/teams/views.py @@ -71,6 +71,8 @@ from .toggles import are_team_submissions_enabled from .utils import emit_team_event +from openedx.core.djangoapps.course_groups.api import * + TEAM_MEMBERSHIPS_PER_PAGE = 5 TOPICS_PER_PAGE = 12 MAXIMUM_SEARCH_SIZE = 10000 @@ -637,6 +639,13 @@ def post(self, request): ) data = CourseTeamSerializer(team, context={"request": request}).data + professor = User.objects.get(username='professor') + group = add_group_to_course( + team.name, + course_key, + professor=professor, + ) + link_group_to_partition_group(group, data["user_partition_id"], data["content_group"]) return Response(data) def get_page(self): @@ -838,6 +847,27 @@ def delete(self, request, team_id): }) return Response(status=status.HTTP_204_NO_CONTENT) + def patch(self, request, team_id): + course_team = get_object_or_404(CourseTeam, team_id=team_id) + data = request.data + + content_group_id = data["content_group"] + if not content_group_id: + return super().patch(request, team_id) + + group = get_course_groups_qs(course_team.course_id).filter(name=course_team.name).first() + partitioned_group_info = get_group_info_for_group(group) + if not partitioned_group_info: + link_group_to_partition_group(group, data["user_partition_id"], data["content_group"]) + return super().patch(request, team_id) + + existing_content_group_id, existing_partition_id = get_group_info_for_group(group) + if content_group_id != existing_content_group_id or data["user_partition_id"] != existing_partition_id: + unlink_group_partition_group(group) + link_group_to_partition_group(group, data["user_partition_id"], data["content_group"]) + + return super().patch(request, team_id) + class TeamsAssignmentsView(GenericAPIView): """ @@ -1479,6 +1509,8 @@ def post(self, request): try: membership = team.add_user(user) + group = get_course_groups_qs(team.course_id).get(name=team.name) + add_user_to_group(group, user.username) emit_team_event( 'edx.team.learner_added', team.course_id,