Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
1319602a
Commit
1319602a
authored
Aug 13, 2015
by
Muhammad Ammar
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9211 from edx/ammar/tnl-1909-support-joining-a-team
support joining a team
parents
a56e6bf7
853f97af
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
477 additions
and
39 deletions
+477
-39
common/test/acceptance/pages/lms/teams.py
+22
-0
common/test/acceptance/tests/lms/test_teams.py
+58
-0
lms/djangoapps/teams/static/teams/js/spec/views/team_join_spec.js
+175
-0
lms/djangoapps/teams/static/teams/js/views/team_join.js
+123
-0
lms/djangoapps/teams/static/teams/js/views/team_profile.js
+8
-7
lms/djangoapps/teams/static/teams/js/views/teams_tab.js
+38
-11
lms/djangoapps/teams/static/teams/templates/team-join.underscore
+9
-0
lms/static/js/components/header/views/header.js
+4
-0
lms/static/js/spec/main.js
+2
-1
lms/static/sass/views/_teams.scss
+37
-20
lms/templates/components/header/header.underscore
+1
-0
No files found.
common/test/acceptance/pages/lms/teams.py
View file @
1319602a
...
...
@@ -312,3 +312,25 @@ class TeamPage(CoursePage, PaginatedUIMixin):
def
team_invite_url
(
self
):
"""Returns the url of invite link box"""
return
self
.
q
(
css
=
'.page-content-secondary .invite-link-input'
)
.
attrs
(
'value'
)[
0
]
def
click_join_team_button
(
self
):
""" Click on Join Team button"""
self
.
q
(
css
=
'.join-team .action-primary'
)
.
first
.
click
()
self
.
wait_for_ajax
()
@property
def
join_team_message
(
self
):
""" Returns join team message """
self
.
wait_for_ajax
()
return
self
.
q
(
css
=
'.join-team .join-team-message'
)
.
text
[
0
]
@property
def
join_team_button_present
(
self
):
""" Returns True if Join Team button is present else False """
self
.
wait_for_ajax
()
return
self
.
q
(
css
=
'.join-team .action-primary'
)
.
present
@property
def
join_team_message_present
(
self
):
""" Returns True if Join Team message is present else False """
return
self
.
q
(
css
=
'.join-team .join-team-message'
)
.
present
common/test/acceptance/tests/lms/test_teams.py
View file @
1319602a
...
...
@@ -997,3 +997,61 @@ class TeamPageTest(TeamsTabBase):
invite_text
=
'Send this link to friends so that they can join too.'
)
self
.
assertEqual
(
self
.
team_page
.
team_invite_url
,
'{0}?invite=true'
.
format
(
self
.
team_page
.
url
))
def
test_join_team
(
self
):
"""
Scenario: User can join a Team if not a member already..
Given I am enrolled in a course with a team configuration, a topic,
and a team belonging to that topic
And I visit the Team page for that team
Then I should see Join Team button
When I click on Join Team button
Then there should be no Join Team button and no message
And I should see the updated information under Team Details
"""
self
.
_set_team_configuration_and_membership
(
create_membership
=
False
)
self
.
team_page
.
visit
()
self
.
assertTrue
(
self
.
team_page
.
join_team_button_present
)
self
.
team_page
.
click_join_team_button
()
self
.
assertFalse
(
self
.
team_page
.
join_team_button_present
)
self
.
assertFalse
(
self
.
team_page
.
join_team_message_present
)
self
.
assert_team_details
(
num_members
=
1
,
invite_text
=
'Send this link to friends so that they can join too.'
)
def
test_already_member_message
(
self
):
"""
Scenario: User should see `You are already in a team` if user is a
member of other team.
Given I am enrolled in a course with a team configuration, a topic,
and a team belonging to that topic
And I am already a member of a team
And I visit a team other than mine
Then I should see `You are already in a team` message
"""
self
.
_set_team_configuration_and_membership
(
membership_team_index
=
0
,
visit_team_index
=
1
)
self
.
team_page
.
visit
()
self
.
assertEqual
(
self
.
team_page
.
join_team_message
,
'You already belong to another team.'
)
self
.
assert_team_details
(
num_members
=
0
,
is_member
=
False
)
def
test_team_full_message
(
self
):
"""
Scenario: User should see `Team is full` message when team is full.
Given I am enrolled in a course with a team configuration, a topic,
and a team belonging to that topic
And team has no space left
And I am not a member of any team
And I visit the team
Then I should see `Team is full` message
"""
self
.
_set_team_configuration_and_membership
(
create_membership
=
True
,
max_team_size
=
1
,
membership_team_index
=
0
,
visit_team_index
=
0
,
another_user
=
True
)
self
.
team_page
.
visit
()
self
.
assertEqual
(
self
.
team_page
.
join_team_message
,
'This team is full.'
)
self
.
assert_team_details
(
num_members
=
1
,
is_member
=
False
,
max_size
=
1
)
lms/djangoapps/teams/static/teams/js/spec/views/team_join_spec.js
0 → 100644
View file @
1319602a
define
([
'underscore'
,
'common/js/spec_helpers/ajax_helpers'
,
'teams/js/models/team'
,
'teams/js/views/team_join'
,
'teams/js/views/team_profile'
],
function
(
_
,
AjaxHelpers
,
TeamModel
,
TeamJoinView
,
TeamProfileView
)
{
'use strict'
;
describe
(
'TeamJoinView'
,
function
()
{
var
createTeamsUrl
,
createTeamModelData
,
createMembershipData
,
createJoinView
,
ACCOUNTS_API_URL
=
'/api/user/v1/accounts/'
,
TEAMS_URL
=
'/api/team/v0/teams/'
,
TEAMS_MEMBERSHIP_URL
=
'/api/team/v0/team_membership/'
;
beforeEach
(
function
()
{
setFixtures
(
'<div class="msg-content"><div class="copy"></div></div><div class="header-action-view"></div>'
);
});
createTeamsUrl
=
function
(
teamId
)
{
return
TEAMS_URL
+
teamId
+
'?expand=user'
;
};
createTeamModelData
=
function
(
teamId
,
teamName
,
membership
)
{
return
{
id
:
teamId
,
name
:
teamName
,
membership
:
membership
};
};
createMembershipData
=
function
(
username
)
{
return
[
{
"user"
:
{
"username"
:
username
,
"url"
:
ACCOUNTS_API_URL
+
username
}
}
];
};
createJoinView
=
function
(
maxTeamSize
,
currentUsername
,
teamModelData
,
teamId
)
{
teamId
=
teamId
||
'teamA'
;
var
model
=
new
TeamModel
(
teamModelData
,
{
parse
:
true
});
model
.
url
=
createTeamsUrl
(
teamId
);
var
teamJoinView
=
new
TeamJoinView
(
{
model
:
model
,
teamsUrl
:
createTeamsUrl
(
teamId
),
maxTeamSize
:
maxTeamSize
,
currentUsername
:
currentUsername
,
teamMembershipsUrl
:
TEAMS_MEMBERSHIP_URL
}
);
return
teamJoinView
.
render
();
};
it
(
'can render itself'
,
function
()
{
var
teamModelData
=
createTeamModelData
(
'teamA'
,
'teamAlpha'
,
createMembershipData
(
'ma'
));
var
view
=
createJoinView
(
1
,
'ma'
,
teamModelData
);
expect
(
view
.
$
(
'.join-team'
).
length
).
toEqual
(
1
);
});
it
(
'can join team successfully'
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
currentUsername
=
'ma1'
;
var
teamId
=
'teamA'
;
var
teamName
=
'teamAlpha'
;
var
teamModelData
=
createTeamModelData
(
teamId
,
teamName
,
[]);
var
view
=
createJoinView
(
1
,
currentUsername
,
teamModelData
);
// a get request will be sent to get user membership info
// because current user is not member of current team
AjaxHelpers
.
expectRequest
(
requests
,
'GET'
,
TEAMS_MEMBERSHIP_URL
+
'?'
+
$
.
param
({
"username"
:
currentUsername
})
);
// current user is not a member of any team so we should see the Join Team button
AjaxHelpers
.
respondWithJson
(
requests
,
{
"count"
:
0
});
expect
(
view
.
$
(
'.action.action-primary'
).
length
).
toEqual
(
1
);
// a post request will be sent to add current user to current team
view
.
$
(
'.action.action-primary'
).
click
();
AjaxHelpers
.
expectRequest
(
requests
,
'POST'
,
TEAMS_MEMBERSHIP_URL
,
$
.
param
({
'username'
:
currentUsername
,
'team_id'
:
teamId
})
);
AjaxHelpers
.
respondWithJson
(
requests
,
{});
// on success, team model will be fetched and
// join team view and team profile will be re-rendered
AjaxHelpers
.
expectRequest
(
requests
,
'GET'
,
createTeamsUrl
(
teamId
)
);
AjaxHelpers
.
respondWithJson
(
requests
,
createTeamModelData
(
teamId
,
teamName
,
createMembershipData
(
currentUsername
))
);
// current user is now member of the current team then there should be no button and no message
expect
(
view
.
$
(
'.action.action-primary'
).
length
).
toEqual
(
0
);
expect
(
view
.
$
(
'.join-team-message'
).
length
).
toEqual
(
0
);
});
it
(
'shows already member message'
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
currentUsername
=
'ma1'
;
var
view
=
createJoinView
(
1
,
currentUsername
,
createTeamModelData
(
'teamA'
,
'teamAlpha'
,
[]));
// a get request will be sent to get user membership info
// because current user is not member of current team
AjaxHelpers
.
expectRequest
(
requests
,
'GET'
,
TEAMS_MEMBERSHIP_URL
+
'?'
+
$
.
param
({
"username"
:
currentUsername
})
);
// current user is a member of another team so we should see the correct message
AjaxHelpers
.
respondWithJson
(
requests
,
{
"count"
:
1
});
expect
(
view
.
$
(
'.action.action-primary'
).
length
).
toEqual
(
0
);
expect
(
view
.
$
(
'.join-team-message'
).
text
().
trim
()).
toBe
(
view
.
alreadyMemberMessage
);
});
it
(
'shows team full message'
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
view
=
createJoinView
(
1
,
'ma1'
,
createTeamModelData
(
'teamA'
,
'teamAlpha'
,
createMembershipData
(
'ma'
))
);
// team has no space and current user is a not member of
// current team so we should see the correct message
expect
(
view
.
$
(
'.action.action-primary'
).
length
).
toEqual
(
0
);
expect
(
view
.
$
(
'.join-team-message'
).
text
().
trim
()).
toBe
(
view
.
teamFullMessage
);
// there should be no request made
expect
(
requests
.
length
).
toBe
(
0
);
});
it
(
'shows correct error messages'
,
function
()
{
var
requests
=
AjaxHelpers
.
requests
(
this
);
var
verifyErrorMessage
=
function
(
requests
,
errorMessage
,
expectedMessage
)
{
createJoinView
(
1
,
'ma'
,
createTeamModelData
(
'teamA'
,
'teamAlpha'
,
[]));
AjaxHelpers
.
respondWithTextError
(
requests
,
400
,
errorMessage
);
expect
(
$
(
'.msg-content .copy'
).
text
().
trim
()).
toBe
(
expectedMessage
);
};
// verify user_message
verifyErrorMessage
(
requests
,
JSON
.
stringify
({
'user_message'
:
'Awesome! You got an error.'
}),
'Awesome! You got an error.'
);
// verify generic error message
verifyErrorMessage
(
requests
,
''
,
'An error occurred. Try again.'
);
});
});
});
lms/djangoapps/teams/static/teams/js/views/team_join.js
0 → 100644
View file @
1319602a
;(
function
(
define
)
{
'use strict'
;
define
([
'backbone'
,
'underscore'
,
'gettext'
,
'teams/js/views/team_utils'
,
'text!teams/templates/team-join.underscore'
],
function
(
Backbone
,
_
,
gettext
,
TeamUtils
,
teamJoinTemplate
)
{
return
Backbone
.
View
.
extend
({
errorMessage
:
gettext
(
"An error occurred. Try again."
),
alreadyMemberMessage
:
gettext
(
"You already belong to another team."
),
teamFullMessage
:
gettext
(
"This team is full."
),
events
:
{
"click .action-primary"
:
"joinTeam"
},
initialize
:
function
(
options
)
{
this
.
template
=
_
.
template
(
teamJoinTemplate
);
this
.
maxTeamSize
=
options
.
maxTeamSize
;
this
.
currentUsername
=
options
.
currentUsername
;
this
.
teamMembershipsUrl
=
options
.
teamMembershipsUrl
;
_
.
bindAll
(
this
,
'render'
,
'joinTeam'
,
'getUserTeamInfo'
);
this
.
listenTo
(
this
.
model
,
"change"
,
this
.
render
);
},
render
:
function
()
{
var
message
,
showButton
,
teamHasSpace
;
var
view
=
this
;
this
.
getUserTeamInfo
(
this
.
currentUsername
,
view
.
maxTeamSize
).
done
(
function
(
info
)
{
teamHasSpace
=
info
.
teamHasSpace
;
// if user is the member of current team then we wouldn't show anything
if
(
!
info
.
memberOfCurrentTeam
)
{
showButton
=
!
info
.
alreadyMember
&&
teamHasSpace
;
if
(
info
.
alreadyMember
)
{
message
=
info
.
memberOfCurrentTeam
?
''
:
view
.
alreadyMemberMessage
;
}
else
if
(
!
teamHasSpace
)
{
message
=
view
.
teamFullMessage
;
}
}
view
.
$el
.
html
(
view
.
template
({
showButton
:
showButton
,
message
:
message
}));
});
return
view
;
},
joinTeam
:
function
()
{
var
view
=
this
;
$
.
ajax
({
type
:
'POST'
,
url
:
view
.
teamMembershipsUrl
,
data
:
{
'username'
:
view
.
currentUsername
,
'team_id'
:
view
.
model
.
get
(
'id'
)}
}).
done
(
function
(
data
)
{
view
.
model
.
fetch
({});
}).
fail
(
function
(
data
)
{
try
{
var
errors
=
JSON
.
parse
(
data
.
responseText
);
view
.
showMessage
(
errors
.
user_message
);
}
catch
(
error
)
{
view
.
showMessage
(
view
.
errorMessage
);
}
});
},
getUserTeamInfo
:
function
(
username
,
maxTeamSize
)
{
var
deferred
=
$
.
Deferred
();
var
info
=
{
alreadyMember
:
false
,
memberOfCurrentTeam
:
false
,
teamHasSpace
:
false
};
info
.
memberOfCurrentTeam
=
TeamUtils
.
isUserMemberOfTeam
(
this
.
model
.
get
(
'membership'
),
username
);
var
teamHasSpace
=
this
.
model
.
get
(
'membership'
).
length
<
maxTeamSize
;
if
(
info
.
memberOfCurrentTeam
)
{
info
.
alreadyMember
=
true
;
info
.
memberOfCurrentTeam
=
true
;
deferred
.
resolve
(
info
);
}
else
{
if
(
teamHasSpace
)
{
var
view
=
this
;
$
.
ajax
({
type
:
'GET'
,
url
:
view
.
teamMembershipsUrl
,
data
:
{
'username'
:
username
}
}).
done
(
function
(
data
)
{
info
.
alreadyMember
=
(
data
.
count
>
0
);
info
.
memberOfCurrentTeam
=
false
;
info
.
teamHasSpace
=
teamHasSpace
;
deferred
.
resolve
(
info
);
}).
fail
(
function
(
data
)
{
try
{
var
errors
=
JSON
.
parse
(
data
.
responseText
);
view
.
showMessage
(
errors
.
user_message
);
}
catch
(
error
)
{
view
.
showMessage
(
view
.
errorMessage
);
}
deferred
.
reject
();
});
}
else
{
deferred
.
resolve
(
info
);
}
}
return
deferred
.
promise
();
},
showMessage
:
function
(
message
)
{
$
(
'.wrapper-msg'
).
removeClass
(
'is-hidden'
);
$
(
'.msg-content .copy'
).
text
(
message
);
$
(
'.wrapper-msg'
).
focus
();
}
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
lms/djangoapps/teams/static/teams/js/views/team_profile.js
View file @
1319602a
...
...
@@ -15,10 +15,9 @@
'click .invite-link-input'
:
'selectText'
},
initialize
:
function
(
options
)
{
this
.
listenTo
(
this
.
model
,
"change"
,
this
.
render
);
this
.
courseID
=
options
.
courseID
;
this
.
discussionTopicID
=
this
.
model
.
get
(
'discussion_topic_id'
);
this
.
maxTeamSize
=
options
.
maxTeamSize
;
this
.
memberships
=
this
.
model
.
get
(
'membership'
);
this
.
readOnly
=
options
.
readOnly
;
this
.
requestUsername
=
options
.
requestUsername
;
this
.
teamInviteUrl
=
options
.
teamInviteUrl
;
...
...
@@ -29,15 +28,17 @@
},
render
:
function
()
{
var
memberships
=
this
.
model
.
get
(
'membership'
);
var
discussionTopicID
=
this
.
model
.
get
(
'discussion_topic_id'
);
this
.
$el
.
html
(
_
.
template
(
teamTemplate
,
{
courseID
:
this
.
courseID
,
discussionTopicID
:
this
.
discussionTopicID
,
discussionTopicID
:
discussionTopicID
,
readOnly
:
this
.
readOnly
,
country
:
this
.
countries
[
this
.
model
.
get
(
'country'
)],
language
:
this
.
languages
[
this
.
model
.
get
(
'language'
)],
membershipText
:
TeamUtils
.
teamCapacityText
(
this
.
memberships
.
length
,
this
.
maxTeamSize
),
isMember
:
TeamUtils
.
isUserMemberOfTeam
(
this
.
memberships
,
this
.
requestUsername
),
hasCapacity
:
this
.
memberships
.
length
<
this
.
maxTeamSize
,
membershipText
:
TeamUtils
.
teamCapacityText
(
memberships
.
length
,
this
.
maxTeamSize
),
isMember
:
TeamUtils
.
isUserMemberOfTeam
(
memberships
,
this
.
requestUsername
),
hasCapacity
:
memberships
.
length
<
this
.
maxTeamSize
,
inviteLink
:
this
.
teamInviteUrl
}));
...
...
@@ -52,7 +53,7 @@
renderTeamMembers
:
function
()
{
var
view
=
this
;
_
.
each
(
this
.
m
emberships
,
function
(
membership
)
{
_
.
each
(
this
.
m
odel
.
get
(
'membership'
)
,
function
(
membership
)
{
view
.
$
(
'.members-info'
).
append
(
_
.
template
(
teamMemberTemplate
,
{
imageUrl
:
membership
.
user
.
profile_image
.
image_url_medium
,
username
:
membership
.
user
.
username
,
...
...
lms/djangoapps/teams/static/teams/js/views/teams_tab.js
View file @
1319602a
...
...
@@ -17,11 +17,12 @@
'teams/js/views/my_teams'
,
'teams/js/views/topic_teams'
,
'teams/js/views/edit_team'
,
'teams/js/views/team_join'
,
'text!teams/templates/teams_tab.underscore'
],
function
(
Backbone
,
_
,
gettext
,
HeaderView
,
HeaderModel
,
TabbedView
,
TopicModel
,
TopicCollection
,
TeamModel
,
TeamCollection
,
TeamMembershipCollection
,
TopicsView
,
TeamProfileView
,
MyTeamsView
,
TopicTeamsView
,
TeamEditView
,
teamsTemplate
)
{
TeamJoinView
,
teamsTemplate
)
{
var
TeamsHeaderModel
=
HeaderModel
.
extend
({
initialize
:
function
(
attributes
)
{
_
.
extend
(
this
.
defaults
,
{
nav_aria_label
:
gettext
(
'teams'
)});
...
...
@@ -241,7 +242,14 @@
countries
:
self
.
countries
}
});
deferred
.
resolve
(
self
.
createViewWithHeader
(
teamsView
,
topic
));
deferred
.
resolve
(
self
.
createViewWithHeader
(
{
mainView
:
teamsView
,
subject
:
topic
}
)
);
});
});
}
...
...
@@ -277,33 +285,52 @@
requestUsername
:
self
.
userInfo
.
username
,
countries
:
self
.
countries
,
languages
:
self
.
languages
,
teamInviteUrl
:
self
.
teamsBaseUrl
+
'#teams/'
+
topicID
+
'/'
+
teamID
+
'?invite=true'
teamInviteUrl
:
self
.
teamsBaseUrl
+
'#teams/'
+
topicID
+
'/'
+
teamID
+
'?invite=true'
});
deferred
.
resolve
(
self
.
createViewWithHeader
(
view
,
team
,
topic
));
var
teamJoinView
=
new
TeamJoinView
(
{
model
:
team
,
teamsUrl
:
self
.
teamsUrl
,
maxTeamSize
:
self
.
maxTeamSize
,
currentUsername
:
self
.
userInfo
.
username
,
teamMembershipsUrl
:
self
.
teamMembershipsUrl
}
);
deferred
.
resolve
(
self
.
createViewWithHeader
(
{
mainView
:
view
,
subject
:
team
,
parentTopic
:
topic
,
headerActionsView
:
teamJoinView
}
)
);
});
});
return
deferred
.
promise
();
},
createViewWithHeader
:
function
(
mainView
,
subject
,
parentTopic
)
{
createViewWithHeader
:
function
(
options
)
{
var
router
=
this
.
router
,
breadcrumbs
,
headerView
;
breadcrumbs
=
[{
title
:
gettext
(
'All Topics'
),
url
:
'#browse'
}];
if
(
parentTopic
)
{
if
(
options
.
parentTopic
)
{
breadcrumbs
.
push
({
title
:
parentTopic
.
get
(
'name'
),
url
:
'#topics/'
+
parentTopic
.
id
title
:
options
.
parentTopic
.
get
(
'name'
),
url
:
'#topics/'
+
options
.
parentTopic
.
id
});
}
headerView
=
new
HeaderView
({
model
:
new
TeamsHeaderModel
({
description
:
subject
.
get
(
'description'
),
title
:
subject
.
get
(
'name'
),
description
:
options
.
subject
.
get
(
'description'
),
title
:
options
.
subject
.
get
(
'name'
),
breadcrumbs
:
breadcrumbs
}),
headerActionsView
:
options
.
headerActionsView
,
events
:
{
'click nav.breadcrumbs a.nav-item'
:
function
(
event
)
{
var
url
=
$
(
event
.
currentTarget
).
attr
(
'href'
);
...
...
@@ -314,7 +341,7 @@
});
return
new
ViewWithHeader
({
header
:
headerView
,
main
:
mainView
main
:
options
.
mainView
});
},
...
...
lms/djangoapps/teams/static/teams/templates/team-join.underscore
0 → 100644
View file @
1319602a
<div class="join-team form-actions">
<% if (showButton) {%>
<button class="action action-primary">
<%- gettext("Join Team") %>
</button>
<% } else if (message) { %>
<p class="join-team-message"><%- message %></p>
<% } %>
</div>
lms/static/js/components/header/views/header.js
View file @
1319602a
...
...
@@ -8,6 +8,7 @@
var
HeaderView
=
Backbone
.
View
.
extend
({
initialize
:
function
(
options
)
{
this
.
template
=
_
.
template
(
headerTemplate
);
this
.
headerActionsView
=
options
.
headerActionsView
;
this
.
listenTo
(
this
.
model
,
'change'
,
this
.
render
);
this
.
render
();
},
...
...
@@ -15,6 +16,9 @@
render
:
function
()
{
var
json
=
this
.
model
.
attributes
;
this
.
$el
.
html
(
this
.
template
(
json
));
if
(
this
.
headerActionsView
)
{
this
.
headerActionsView
.
setElement
(
this
.
$
(
'.header-action-view'
)).
render
();
}
return
this
;
}
});
...
...
lms/static/js/spec/main.js
View file @
1319602a
...
...
@@ -800,7 +800,8 @@
'lms/include/teams/js/spec/views/teams_tab_spec.js'
,
'lms/include/teams/js/spec/views/topic_card_spec.js'
,
'lms/include/teams/js/spec/views/topic_teams_spec.js'
,
'lms/include/teams/js/spec/views/topics_spec.js'
'lms/include/teams/js/spec/views/topics_spec.js'
,
'lms/include/teams/js/spec/views/team_join_spec.js'
]);
}).
call
(
this
,
requirejs
,
define
);
lms/static/sass/views/_teams.scss
View file @
1319602a
...
...
@@ -228,7 +228,7 @@
.action-view
{
@extend
%btn-pl-default-base
;
float
:
right
;
@include
float
(
right
)
;
margin
:
(
$baseline
/
4
)
0
;
}
}
...
...
@@ -242,11 +242,11 @@
.meta-detail
{
margin-top
:
(
$baseline
/
4
);
margin-right
:
(
$baseline
*.
75
);
@include
margin-right
(
$baseline
*.
75
);
color
:
$gray
;
.icon
{
margin-right
:
(
$baseline
/
4
);
@include
margin-right
(
$baseline
/
4
);
}
}
...
...
@@ -306,7 +306,7 @@
}
.team-activity
{
float
:
right
;
@include
float
(
right
)
;
}
.card-actions
{
...
...
@@ -328,7 +328,7 @@
display
:
block
;
position
:
absolute
;
top
:
(
$baseline
/
2
);
left
:
-
(
$baseline
/
4
);
@include
left
(
-
(
$baseline
/
4
)
);
box-shadow
:
1px
1px
1px
0
$blue-d1
;
background-color
:
$m-blue-l2
;
padding
:
(
$baseline
/
10
)
(
$baseline
*.
75
);
...
...
@@ -400,8 +400,8 @@
display
:
inline-block
;
@include
tooltip-hover-style
(
-
(
$baseline
*
2
));
}
}
}
}
.create-team
{
...
...
@@ -484,7 +484,23 @@
}
}
.form-actions
{
.required-wrapper
{
display
:
inline-block
;
vertical-align
:
top
;
width
:
60%
;
// TODO: susy grid
}
.optional-wrapper
{
display
:
inline-block
;
vertical-align
:
top
;
width
:
35%
;
// TODO: susy grid
@include
margin-left
(
2%
);
border-left
:
2px
solid
$gray-l4
;
padding-left
:
2%
;
}
}
.form-actions
{
margin-top
:
$baseline
;
}
...
...
@@ -512,25 +528,24 @@
&
:focus
{
border
:
1px
solid
$link-color
;
color
:
$link-color
;
}
}
}
.required-wrapper
{
display
:
inline-block
;
vertical-align
:
top
;
width
:
60%
;
// TODO: susy grid
}
.header-action-view
{
display
:
inline-block
;
width
:
33%
;
vertical-align
:
text-bottom
;
.optional-wrapper
{
display
:
inline-block
;
vertical-align
:
top
;
width
:
35%
;
// TODO: susy grid
margin-left
:
2%
;
border-left
:
2px
solid
$gray-l4
;
padding-left
:
2%
;
.join-team.form-actions
,
.join-team-message
{
@include
text-align
(
right
);
}
}
.join-team-message
{
@extend
%t-copy-sub1
;
color
:
$gray-l1
;
}
.team-actions
{
@extend
%ui-well
;
margin
:
20px
1
.2%
;
...
...
@@ -687,3 +702,5 @@
.create-team.form-actions
{
margin-top
:
$baseline
;
}
lms/templates/components/header/header.underscore
View file @
1319602a
...
...
@@ -11,4 +11,5 @@
<h2 class="page-title"><%- title %></h2>
<p class="page-description"><%- description %></p>
</div>
<div class="header-action-view"></div>
</header>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment