1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-15 07:52:14 +00:00

Merge pull request #942 from haiwen/redesign

Redesign
This commit is contained in:
xiez 2015-12-15 11:59:52 +08:00
commit 922b4411ba
36 changed files with 794 additions and 687 deletions

View File

@ -128,6 +128,8 @@
.sf2-icon-x1:before { content:"\e01d"; }
.sf2-icon-tick:before { content:"\e01e"; }
.sf2-icon-x2:before { content:"\e01f"; }
.sf2-icon-user2:before { content:"\e020"; }
.sf2-icon-msgs2:before { content:"\e021"; }
/******* tags **********/
html { background:#fff; }
@ -584,30 +586,6 @@ textarea:-moz-placeholder {/* for FF */
top:-11px;
left:-10px;
}
/**** info-item *****/
.info-item {
border: 1px solid #eee;
border-radius: 2px;
margin-bottom: 12px;
}
.info-item h3,
.info-item p {
margin:0;
}
.info-item h3 {
font-size:1.15em;
}
.info-item-top {
padding: 4px 10px;
background: #f8f8f8;
border-bottom: 1px solid #eee;
}
.info-item-bottom {
padding: 8px 10px;
}
.info-item p.not-last {
margin-bottom:0.4em;
}
/**** tabnav *****/
.tabnav-tabs,
.tabnav-tab {
@ -690,6 +668,18 @@ textarea:-moz-placeholder {/* for FF */
color:#333;
font-weight:normal;
}
.side-tabnav-tabs .tab .grp-list a {
font-size:14px;
line-height:24px;
padding:0;
}
#group-nav .sharp {
display:inline-block;
width:42px;
margin-right:5px;
text-align:right;
color:#aaa;
}
.side-tabnav-tabs .tab a:hover {
background-color:#feefb8;
text-decoration:none;
@ -704,12 +694,16 @@ textarea:-moz-placeholder {/* for FF */
line-height:1;
color:#999;
}
#group-nav .toggle-icon {
color:#999;
}
.side-tabnav-tabs .tab-cur a,
.side-tabnav-tabs .tab-cur a:hover {
background-color:#feac74;
}
.side-tabnav-tabs .tab-cur [class^="sf2-icon-"],
.side-tabnav-tabs .tab-cur a {
.side-tabnav-tabs .tab-cur a,
#group-nav .tab-cur .sharp {
color:#fff;
}
.side-tabnav-tabs .tab-cur a {
@ -1146,6 +1140,45 @@ textarea:-moz-placeholder {/* for FF */
color:#fff;
text-decoration:none;
}
/**** popover ****/ /* e.g. top notice popup, group members popup */
.popover {
width:240px;
background:#fff;
border:1px solid #c9c9c9;
border-radius:3px;
box-shadow:0 0 1px #f3f3f3;
}
.popover-hd {
padding:5px 0 3px;
border-bottom:1px solid #dfdfe1;
margin:0 10px;
}
.popover-title {
text-align:center;
margin:0;
}
.popover-close {
font-size:16px;
color:#b9b9b9;
margin:4px 0 0;
}
.popover-con {
padding:0 10px;
overflow:auto;
}
/**** user-item ****/ /* e.g. group member in 'group members' panel */
.user-item {
margin:5px 0;
}
.user-item .avatar {
border-radius:1000px;
}
.user-item .txt {
margin-left:40px;
}
.user-item .txt-item {
margin:0;
}
/********** container ***********/
#main, #footer {
width:950px;
@ -1209,6 +1242,11 @@ textarea:-moz-placeholder {/* for FF */
#organization-repos .hd {
position:relative;
}
#group-top .op-icon {
display:inline-block;
font-size:22px;
margin:4px 15px 0 0;
}
.commit-list-topbar,
.file-audit-list-topbar,
.repo-file-list-topbar {
@ -1439,14 +1477,6 @@ textarea:-moz-placeholder {/* for FF */
#user-info-popup {
width:220px;
}
#top-nav-grp-info {
width:235px;
top:40px;
font-size:14px;
}
#top-nav-grp-info .outer-caret {
left:38px;
}
#notice-popup .outer-caret {
left:143px;
}
@ -1463,35 +1493,10 @@ textarea:-moz-placeholder {/* for FF */
color:#333;
font-weight:normal;
}
#top-nav-grp-list .item {
padding:5px 10px;
border:none;
}
#top-nav-grp-list .item.hl {
background:#fafafa;
cursor:pointer;
}
#top-nav-grp-list .name {
display:inline-block;
width:142px;
}
.top-info-popup a.item:hover {
background:#fafafa;
text-decoration:none;
}
#top-nav-grp-info .avatar {
border-radius:1000px;
margin-right:5px;
vertical-align:middle;
}
#top-nav-grp-info .op-icon {
font-size:24px;
color:#999;
margin:0;
}
#top-nav-grp-info .all-grp {
padding-left:50px;
}
#msg-file-share {
margin-top:8px;
position:relative;
@ -1529,34 +1534,6 @@ textarea:-moz-placeholder {/* for FF */
#logo {
margin-right:30px;
}
#header .nav {
float:left;
padding-top:8px;
font-size:15px;
}
#header .nav-item {
float: left;
height:21px;
padding-bottom:19px;
margin:0 14px;
}
.ru #header .nav-item {
margin:0 11px;
}
#header .nav .a,
#header .nav .a:visited {
color:#8A948F;
font-weight:bold;
text-decoration:none;
white-space:nowrap;/* for ipad */
}
#header .nav .a.cur {
color:#000;
}
#header .nav .a:hover {
color: #ff9933;
text-decoration: underline;
}
/* footer */
#footer {
@ -1835,6 +1812,7 @@ textarea:-moz-placeholder {/* for FF */
line-height:25px;
margin:0;
}
#group-top .path,
#dir-view .path {
font-size:16px;
line-height:1.5;
@ -3757,6 +3735,7 @@ img.thumbnail {
border-radius:3px;
margin:0;
}
/**** #groups ****/ /* groups page */
#groups .group-name {
font-size:16px;
margin:15px 0 10px;
@ -3767,3 +3746,15 @@ img.thumbnail {
#groups .empty-tips {
margin:10px 0 40px;
}
/**** #group ****/ /* group page */
#group {
position:relative;
}
#group-members {
position:absolute;
top:77px;
right:0;
}
#group-members .outer-caret {
right:66px;
}

Binary file not shown.

Binary file not shown.

View File

@ -20,9 +20,10 @@ from seahub.api2.throttling import UserRateThrottle
from seahub.avatar.settings import GROUP_AVATAR_DEFAULT_SIZE
from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \
get_default_group_avatar_url
from seahub.utils import is_org_context
from seahub.utils import is_org_context, is_valid_username
from seahub.utils.timeutils import dt, utc_to_local
from seahub.group.utils import validate_group_name, check_group_name_conflict
from seahub.group.views import remove_group_common
from seahub.base.templatetags.seahub_tags import email2nickname, \
translate_seahub_time
@ -167,3 +168,131 @@ class Groups(APIView):
"admins": self._get_group_admins(g.id),
}
return Response(new_group, status=status.HTTP_201_CREATED)
def put(self, request, group_id):
""" Rename, transfer a group
"""
group_id = int(group_id)
try:
group = seaserv.get_group(group_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not group:
error_msg = _(u'Group does not exist.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# only group staff can rename or transfer a group
username = request.user.username
if not seaserv.check_group_staff(group_id, username):
error_msg = _(u'Permission denied')
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
operation = request.DATA.get('operation', '')
if operation.lower() == 'rename':
new_group_name = request.DATA.get('new_group_name', None)
if not new_group_name:
error_msg = _(u'Argument missing')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# Check whether group name is validate.
if not validate_group_name(new_group_name):
error_msg = _(u'Group name can only contain letters, numbers, blank, hyphen or underscore')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# Check whether group name is duplicated.
if check_group_name_conflict(request, new_group_name):
error_msg = _(u'There is already a group with that name.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try:
seaserv.ccnet_threaded_rpc.set_group_name(group_id, new_group_name)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
elif operation.lower() == 'transfer':
email = request.DATA.get('email')
if not email:
error_msg = _(u'Argument missing')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not is_valid_username(email):
error_msg = _('Email %s is not valid.') % email
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if email == group.creator_name:
error_msg = _('%s is already group owner') % email
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try:
if not seaserv.is_group_user(group_id, email):
seaserv.ccnet_threaded_rpc.group_add_member(group_id, username, email)
if not seaserv.check_group_staff(group_id, email):
seaserv.ccnet_threaded_rpc.group_set_admin(group_id, email)
seaserv.ccnet_threaded_rpc.set_group_creator(group_id, email)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
error_msg = _(u'Operation can only be rename or transfer.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
g = seaserv.get_group(group_id)
val = utc_to_local(dt(g.timestamp))
avatar_url, is_default, date_uploaded = api_grp_avatar_url(group_id,
GROUP_AVATAR_DEFAULT_SIZE)
group_info = {
"id": g.id,
"name": g.group_name,
"creator": g.creator_name,
"created_at": val.strftime("%Y-%m-%dT%H:%M:%S") + DateFormat(val).format('O'),
"avatar_url": request.build_absolute_uri(avatar_url),
"admins": self._get_group_admins(g.id),
}
return Response(group_info, status=status.HTTP_200_OK)
def delete(self, request, group_id):
""" Delete a group
"""
group_id = int(group_id)
try:
group = seaserv.get_group(group_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not group:
error_msg = _(u'Group does not exist.')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# only group staff can delete a group
username = request.user.username
if not seaserv.check_group_staff(group_id, username):
error_msg = _(u'Permission denied')
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
org_id = None
if is_org_context(request):
org_id = request.user.org.org_id
try:
remove_group_common(group_id, username, org_id=org_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
return Response({'success': True}, status=status.HTTP_200_OK)

View File

@ -38,6 +38,8 @@ from .utils import is_repo_writable, is_repo_accessible, \
get_person_msgs, api_group_check, get_email, get_timestamp, \
get_group_message_json, get_group_msgs, get_group_msgs_json, get_diff_details, \
json_response, to_python_boolean, is_seafile_pro
from seahub.avatar.settings import AVATAR_DEFAULT_SIZE
from seahub.avatar.templatetags.avatar_tags import api_avatar_url, avatar
from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \
grp_avatar
@ -3468,10 +3470,64 @@ class Groups(APIView):
"Operation can only be rename.")
class GroupMembers(APIView):
authentication_classes = (TokenAuthentication, )
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
def get(self, request, group_id, format=None):
"""
Get group members.
"""
try:
group_id_int = int(group_id)
except ValueError:
return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid group ID')
try:
avatar_size = int(request.GET.get('avatar_size',
AVATAR_DEFAULT_SIZE))
except ValueError:
avatar_size = AVATAR_DEFAULT_SIZE
try:
group = seaserv.get_group(group_id_int)
except SearpcError as e:
logger.error(e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
'Failed to get group.')
if not group:
return api_error(status.HTTP_404_NOT_FOUND, 'Group not found')
try:
is_group_user = seaserv.is_group_user(group_id_int,
request.user.username)
except SearpcError as e:
logger.error(e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
'Failed to check if is group user.')
if not is_group_user:
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
try:
members = seaserv.get_group_members(group.id)
except SearpcError as e:
logger.error(e)
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
'Failed to get group members.')
members_json = []
for m in members:
avatar_url, is_default, date_uploaded = api_avatar_url(m.user_name,
avatar_size)
members_json.append({
'username': m.user_name,
"fullname": email2nickname(m.user_name),
"avatar_url": request.build_absolute_uri(avatar_url),
})
return HttpResponse(json.dumps(members_json),
content_type=json_content_type)
def put(self, request, group_id, format=None):
"""
Add group members.

View File

@ -50,9 +50,9 @@ def base(request):
except AttributeError:
base_template = 'myhome_base.html'
# get 8 user groups
try:
grps = request.user.joined_groups[:8]
grps = request.user.joined_groups
grps.sort(lambda x, y: cmp(x.group_name.lower(), y.group_name.lower()))
except AttributeError: # anonymous user
grps = None

View File

@ -1,37 +0,0 @@
{% extends 'group/group_base.html' %}
{% load seahub_tags avatar_tags i18n %}
{% block cur_members %}tab-cur{%endblock%}
{% block right_panel %}
<div class="hd">
<h3 class="fleft">{% trans "Members" %}</h3>
{% if group.view_perm != 'pub' and not is_staff %}
<button id="quit-group" data-url="{% url 'group_quit' group.id %}" class="fright">{% trans "Leave group" %}</button>
{% endif %}
</div>
<ul class="user-list">
{% for m in members %}
{% with e=m.user_name id=m.user_name %}
<li class="user ovhd">
<a href="{% url 'user_profile' id %}" class="pic fleft">{% avatar e 48 %}</a>
<div class="txt fright">
<a class="name" href="{% url 'user_profile' id %}">{{ e|email2nickname }}</a>
<p>{{ e }}</p>
</div>
</li>
{% endwith %}
{% endfor %}
</ul>
{% endblock %}
{% block extra_script %}{{block.super}}
<script type="text/javascript">
addConfirmTo($('#quit-group'), {
'title': "{% trans "Quit Group" %}",
'con': "{% trans "Are you sure you want to quit this group?" %}",
'post': true
});
</script>
{% endblock %}

View File

@ -1,6 +1,6 @@
from django.conf.urls import patterns, url
from views import group_info, group_members, group_member_operations, group_add_admin, \
from views import group_info, group_member_operations, group_add_admin, \
group_manage, msg_reply, msg_reply_new, group_recommend, \
create_group_repo, attention, group_message_remove, \
group_remove_admin, group_discuss, group_wiki, group_wiki_create, \
@ -32,7 +32,6 @@ urlpatterns = patterns('',
url(r'^(?P<group_id>\d+)/revoke_pub/$', group_revoke_public, name='group_revoke_pub'),
url(r'^(?P<group_id>\d+)/quit/$', group_quit, name='group_quit'),
url(r'^(?P<group_id>[\d]+)/create-repo/$', create_group_repo, name='create_group_repo'),
url(r'^(?P<group_id>[\d]+)/members/$', group_members, name='group_members'),
(r'^(?P<group_id>[\d]+)/member/(?P<user_name>[^/]+)/$', group_member_operations),
url(r'^(?P<group_id>\d+)/msgdel/(?P<msg_id>\d+)/$', group_message_remove, name='group_message_remove'),
url(r'^(?P<group_id>\d+)/admin/add/$', group_add_admin, name='group_add_admin'),

View File

@ -592,26 +592,6 @@ def group_info(request, group):
'repo_password_min_length': config.REPO_PASSWORD_MIN_LENGTH,
}, context_instance=RequestContext(request))
@group_check
def group_members(request, group):
if group.view_perm == 'pub':
raise Http404
# Get all group members.
members = get_group_members(group.id)
# get available modules(wiki, etc)
mods_available = get_available_mods_by_group(group.id)
mods_enabled = get_enabled_mods_by_group(group.id)
return render_to_response("group/group_members.html", {
"members": members,
"group" : group,
"is_staff": group.is_staff,
"mods_enabled": mods_enabled,
"mods_available": mods_available,
}, context_instance=RequestContext(request))
def send_group_member_add_mail(request, group, from_user, to_user):
c = {
'email': from_user,

View File

@ -287,7 +287,7 @@ AVATAR_DEFAULT_URL = '/avatars/default.png'
AVATAR_DEFAULT_NON_REGISTERED_URL = '/avatars/default-non-register.jpg'
AVATAR_MAX_AVATARS_PER_USER = 1
AVATAR_CACHE_TIMEOUT = 14 * 24 * 60 * 60
AUTO_GENERATE_AVATAR_SIZES = (16, 20, 24, 28, 32, 36, 40, 48, 60, 80, 290)
AUTO_GENERATE_AVATAR_SIZES = (16, 20, 24, 28, 32, 36, 40, 48, 60, 64, 80, 290)
# Group avatar
GROUP_AVATAR_STORAGE_DIR = 'avatars/groups'
GROUP_AVATAR_DEFAULT_URL = 'avatars/groups/default.png'

View File

@ -180,42 +180,6 @@ $('#info-bar .close').click(function() {
});
{% endif %}
{% if grps %}
$(function() {
var grp_nav = $('#top-nav-grp');
grp_nav.after('<div id="top-nav-grp-info" class="top-info-popup hide"></div>');
var popup = $('#top-nav-grp-info');
var popup_con = '<div class="outer-caret up-outer-caret"><div class="inner-caret"></div></div><ul id="top-nav-grp-list">';
{% for grp in grps %}
popup_con += '<li class="item" data-url="{{SITE_ROOT}}#group/{{ grp.id }}/" title="{{ grp.group_name }}"> {% grp_avatar grp.id 36 %} <span class="name ellipsis vam">{{ grp.group_name }}</span> <a href="{% url 'group_discuss' grp.id %}" title="{% trans "Discussion" %}" class="op-icon sf2-icon-msgs vh"></a></li>';
{% endfor %}
popup_con += '</ul>';
popup_con += '<a href="{% url 'group_list' %}" class="item all-grp">{% trans "All Groups" %}</a>';
popup.html(popup_con);
$('.item', popup).hover(
function() {
$(this).addClass('hl').children('a').removeClass('vh');
},
function() {
$(this).removeClass('hl').children('a').addClass('vh');
}
)
.click(function() {
location.href = $(this).data('url');
});
popup.css({'right': (grp_nav.outerWidth() - popup.outerWidth())/6 * 5});
grp_nav.parent('.nav-item').hover(
function() {
popup.removeClass('hide');
},
function() {
popup.addClass('hide');
}
);
});
{% endif %}
{% if has_file_search %}
{% include 'snippets/search_js.html' %}
{% endif %}

View File

@ -47,33 +47,7 @@
<img src="{{ MEDIA_URL }}{{ logo_path }}" title="Seafile" alt="logo" width="{{logo_width}}" height="{{logo_height}}" />
{% endif %}
</a>
{% block nav %}
<ul class="nav">
<li class="nav-item">
<a href="{{ SITE_ROOT }}#" class="a">{% trans "My Home" %}</a>
</li>
{% if grps %}
<li class="nav-item nav-item-group" style="position:relative;">
<a href="{% url 'group_list' %}" class="a" id="top-nav-grp">{% trans "Groups" %} <span class="icon-caret-down"></span></a>
</li>
{% else %}
<li class="nav-item">
<a href="{% url 'group_list' %}" class="a">{% trans "Groups" %}</a>
</li>
{% endif %}
{% if user.permissions.can_view_org %}
<li class="nav-item">
<a href="{{ SITE_ROOT }}#org/" class="a">{% trans "Organization" %}</a>
</li>
{% endif %}
<li class="nav-item">
<a href="{{ SITE_ROOT }}help/" class="a">{% trans "Help" %}</a>
</li>
</ul>
{% endblock %}
{% block nav %}{% endblock %}
{% block header_right %}
{% if request.user.is_authenticated %}

View File

@ -4,14 +4,43 @@
{% block left_panel %}
<div class="side-tabnav">
<h3 class="hd">{% trans "Files" %}</h3>
<ul class="side-tabnav-tabs">
{% if user.permissions.can_add_repo %}
<li class="tab {% block cur_my_lib %}{% endblock %}"><a href="{{ SITE_ROOT }}#my-libs/"><span class="sf2-icon-user"></span>{% trans "Mine" %}</a></li>
{% comment %}
{% if sub_lib_enabled %}
<li class="tab"><a href="#my-sub-libs/">{% trans "Sub-libraries" %}</a></li>
{% endif %}
{% endcomment %}
{% endif %}
<li class="tab"><a href="{{ SITE_ROOT }}#shared-libs/"><span class="sf2-icon-share"></span>{% trans "Shared" %}</a></li>
{% if user.permissions.can_view_org %}
<li class="tab"><a href="{{ SITE_ROOT }}#org/"><span class="sf2-icon-organization"></span>{% trans "Organization" %}</a></li>
{% endif %}
<li class="tab" id="group-nav">
<a href="#"><span class="sf2-icon-group"></span>{% trans "Groups" %}<span class="toggle-icon icon-caret-left fright"></span></a>
<ul class="grp-list hide">
<li>
<a href="{% url 'group_list' %}"><span class="sharp">#</span>{% trans "All Groups" %}</a>
</li>
{% for grp in grps %}
<li>
<a class="ellipsis" href="{{SITE_ROOT}}#group/{{ grp.id }}/" title="{{ grp.group_name }}"><span class="sharp">#</span>{{ grp.group_name }}</a>
</li>
{% endfor %}
</ul>
</li>
</ul>
<div class="hd w100 ovhd">
<h3 class="fleft">{% trans "Personal" %}</h3>
<h3 class="fleft">{% trans "Tools" %}</h3>
{% if user.permissions.can_add_repo %}
<span id="enable-mods" class="sf2-icon-cog2 op-icon fright" title="{% trans "Enable Modules" %}"></span>
{% endif %}
</div>
<ul class="side-tabnav-tabs">
<li class="tab {% block cur_my_lib %}{% endblock %}"><a href="{{ SITE_ROOT }}"><span class="sf2-icon-library"></span>{% trans "Libraries" %}</a></li>
<li class="tab {% block cur_stars %}{% endblock %}"><a href="{{ SITE_ROOT }}#starred/"><span class="sf2-icon-star"></span>{% trans "Starred" %}</a></li>
{% if events_enabled %}
<li class="tab {% block cur_activities %}{% endblock %}"><a href="{{ SITE_ROOT }}#activities/"><span class="sf2-icon-clock"></span>{% trans "Activities" %}</a></li>
@ -64,6 +93,11 @@ $('#enable-mods').click(function() {
$('#simplemodal-container').css('height', 'auto');
return false;
});
$('#group-nav a:first').click(function() {
$('#group-nav .toggle-icon').toggleClass('icon-caret-left icon-caret-down');
$('#group-nav .grp-list').slideToggle();
return false;
});
{% endif %}
</script>
{% endblock %}

View File

@ -90,23 +90,6 @@
<td><%= mtime_relative %></td>
<td><span title="<%- owner %>"><%- owner_nickname %></span></td>
</script>
<script type="text/template" id="top-group-nav-tmpl">
<div id="top-nav-grp-info" class="top-info-popup hide">
<div class="outer-caret up-outer-caret">
<div class="inner-caret"></div>
</div>
<ul id="top-nav-grp-list">
<% for (var i = 0, len = groups.length; i < len; i++) { %>
<li class="item" data-url="#group/<%= groups[i].id %>/" title="<%= groups[i].name %>">
<%= groups[i].avatar %>
<span class="name ellipsis vam"><%= groups[i].name %></span>
<a href="{{SITE_ROOT}}group/<%= groups[i].id %>/discuss/" title="{% trans "Discussion" %}" class="op-icon sf2-icon-msgs vh"></a>
</li>
<% } %>
</ul>
<a href="{% url 'group_list' %}" class="item all-grp">{% trans 'All Groups' %}</a>
</div>
</script>
<script type="text/template" id="dir-op-bar-tmpl">
<% if (user_perm == 'rw') { %>
<div id="multi-dirents-op" class="hide">
@ -154,13 +137,12 @@
</script>
<script type="text/template" id="dir-path-bar-tmpl">
<% if (context == 'group') { %>
<a href="#<%= category %>/" class="path-link normal">{% trans "Libraries" %}</a> /
<a href="#<%= category %>/" class="path-link normal">{% trans "Group" %}</a> /
<% } else if (context == 'org') { %>
<a href="#<%= category %>/" class="path-link normal">{% trans "Libraries" %}</a> /
<a href="#<%= category %>/" class="path-link normal">{% trans "Organization" %}</a> /
<% } else if (context == 'common') { %>
<a href="#my-libs/" class="path-link normal">{% trans "Libraries" %}</a> /
<a href="#my-libs/" class="path-link normal">{% trans "Mine" %}</a> /
<% } else { %>
<a href="#" class="path-link normal">{% trans "Libraries" %}</a> /
<a href="#<%= category %>/" class="path-link normal"><% if (category == 'my-libs') { %>{% trans "Mine" %}<% } %><% if (category == 'shared-libs') { %>{% trans "Shared" %}<% } %><% if (category == 'my-sub-libs') { %>{% trans "Sub-libraries" %}<% } %></a> /
<% } %>
<% if (path == '/') { %>
@ -547,27 +529,75 @@
<td><a href="#my-libs/lib/<%= origin_repo_id %><%- origin_path %>"><%- abbrev_origin_path %></a></td>
<td><%= mtime_relative %></td>
</script>
<script type="text/template" id="myhome-side-nav-tmpl">
<div class="hd w100 ovhd">
<h3 class="fleft">{% trans "Personal" %}</h3>
<% if (can_add_repo) { %>
<span id="myhome-enable-mods" class="sf2-icon-cog2 op-icon fright" title="{% trans "Enable Modules" %}"></span>
<script type="text/template" id="side-nav-tmpl">
<h3 class="hd">{% trans "Files" %}</h3>
<ul class="side-tabnav-tabs">
{% if user.permissions.can_add_repo %}
<li class="tab<% if (cur_tab == 'mine') { %> tab-cur<% } %>"><a href="{{ SITE_ROOT }}#my-libs/"><span class="sf2-icon-user"></span>{% trans "Mine" %}</a></li>
{% comment %}
{% if sub_lib_enabled %}
<li class="tab<% if (cur_tab == 'sub-libs') { %> tab-cur<% } %>"><a href="#my-sub-libs/">{% trans "Sub-libraries" %}</a></li>
{% endif %}
{% endcomment %}
{% endif %}
<li class="tab<% if (cur_tab == 'shared') { %> tab-cur<% } %>"><a href="{{ SITE_ROOT }}#shared-libs/"><span class="sf2-icon-share"></span>{% trans "Shared" %}</a></li>
{% if user.permissions.can_view_org %}
<li class="tab<% if (cur_tab == 'org') { %> tab-cur<% } %>"><a href="{{ SITE_ROOT }}#org/"><span class="sf2-icon-organization"></span>{% trans "Organization" %}</a></li>
{% endif %}
<% if (cur_tab == 'group') { %>
<li class="tab" id="group-nav">
<a href="#"><span class="sf2-icon-group"></span>{% trans "Groups" %}<span class="toggle-icon icon-caret-down fright"></span></a>
<ul class="grp-list">
<li<% if (cur_group_tab == 'groups') { %> class="tab-cur"<% }%>><a href="{% url 'group_list' %}"><span class="sharp">#</span>{% trans "All Groups" %}</a></li>
{% for grp in grps %}
<li<% if (cur_group_id == '{{ grp.id }}') { %> class="tab-cur"<% }%>>
<a class="ellipsis" href="{{SITE_ROOT}}#group/{{ grp.id }}/" title="{{ grp.group_name }}"><span class="sharp">#</span>{{ grp.group_name }}</a>
</li>
{% endfor %}
</ul>
</li>
<% } else { %>
<li class="tab" id="group-nav">
<% if (show_group_list) { %>
<a href="#"><span class="sf2-icon-group"></span>{% trans "Groups" %}<span class="toggle-icon icon-caret-down fright"></span></a>
<ul class="grp-list">
<% } else { %>
<a href="#"><span class="sf2-icon-group"></span>{% trans "Groups" %}<span class="toggle-icon icon-caret-left fright"></span></a>
<ul class="grp-list hide">
<% } %>
<li>
<a href="{% url 'group_list' %}"><span class="sharp">#</span>{% trans "All Groups" %}</a>
</li>
{% for grp in grps %}
<li>
<a class="ellipsis" href="{{SITE_ROOT}}#group/{{ grp.id }}/" title="{{ grp.group_name }}"><span class="sharp">#</span>{{ grp.group_name }}</a>
</li>
{% endfor %}
</ul>
</li>
<% } %>
</ul>
<div class="hd w100 ovhd">
<h3 class="fleft">{% trans "Tools" %}</h3>
{% if user.permissions.can_add_repo %}
<span id="enable-mods" class="sf2-icon-cog2 op-icon fright" title="{% trans "Enable Modules" %}"></span>
{% endif %}
</div>
<ul class="side-tabnav-tabs">
<li class="tab<% if (cur_tab == 'libs') { %> tab-cur<% } %>"><a href="{{ SITE_ROOT }}#"><span class="sf2-icon-library"></span>{% trans "Libraries" %}</a></li>
<li class="tab<% if (cur_tab == 'starred') { %> tab-cur<% } %>"><a href="{{ SITE_ROOT }}#starred/"><span class="sf2-icon-star"></span>{% trans "Starred" %}</a></li>
<% if (events_enabled) { %>
{% if events_enabled %}
<li class="tab<% if (cur_tab == 'activities') { %> tab-cur<% } %>"><a href="{{ SITE_ROOT }}#activities/"><span class="sf2-icon-clock"></span>{% trans "Activities" %}</a></li>
<% } %>
{% endif %}
<% for (var i = 0, len = mods_enabled.length; i < len; i++) { %>
<% if (mods_enabled[i] == 'personal wiki') { %>
<li class="tab"><a href="{{ SITE_ROOT }}home/wiki/"><span class="sf2-icon-wiki"></span>{% trans "Personal Wiki" %}</a></li>
<li class="tab"><a href="{% url 'personal_wiki' %}"><span class="sf2-icon-wiki"></span>{% trans "Personal Wiki" %}</a></li>
<% } %>
<% } %>
<li class="tab"><a href="{{ SITE_ROOT }}devices/"><span class="sf2-icon-monitor"></span>{% trans "Devices" %}</a></li>
<li class="tab"><a href="{% url 'devices' %}"><span class="sf2-icon-monitor"></span>{% trans "Devices" %}</a></li>
</ul>
<h3 class="hd">{% trans "Share Admin" %}</h3>
@ -579,6 +609,7 @@
<li class="tab"><a href="{{ SITE_ROOT }}share/links/"><span class="sf2-icon-link"></span>{% trans "Links" %}</a></li>
</ul>
</script>
<script type="text/template" id="myhome-mods-enable-form-tmpl">
<form id="myhome-mods-enable-form" method="post" action="" class="hide">{% csrf_token%}
<h3>{% trans "Enable Modules"%}</h3>
@ -601,37 +632,23 @@
<input type="submit" value="{% trans "Submit"%}" class="submit" />
</form>
</script>
<script type="text/template" id="group-side-nav-tmpl">
<div class="hd w100 ovhd">
<h3 class="fleft">
<%= avatar %> <span title="<%- name %>" class="grp-name ellipsis vam"><%- name %></span>
</h3>
<% if (is_staff) { %>
<span id="enable-mods" class="sf2-icon-cog2 op-icon fright" title="{% trans "Enable Modules" %}" style="margin:6px 0 0 5px;"></span>
<% } %>
<% if (is_pub) { %>
<img src="{{MEDIA_URL}}img/grp_public.png" alt="" title="{% trans "This group is public." %}" class="fright" style="margin:8px 0 0 5px;" />
<% } %>
<script type="text/template" id="group-top-tmpl">
<p class="path"><a href="{% url 'group_list' %}" class="normal">{% trans "Groups" %}</a> / <%- name %></p>
<div class="hd ovhd">
{% if user.permissions.can_add_repo %}
<button class="repo-create fleft"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "New Library" %}</span></button>
{% endif %}
<div class="fright">
<% if (is_staff) { %>
<span class="sf2-icon-cog1 op-icon" title="{% trans "Admin" %}"></span>
<% } %>
<span class="sf2-icon-user2 op-icon" title="{% trans "Members" %}" id="group-members-icon"></span>
<% if (!is_pub) { %>
<span class="sf2-icon-msgs2 op-icon" title="{% trans "Discussion" %}"></span>
<% } %>
</div>
<ul class="side-tabnav-tabs">
<li class="tab tab-cur"><a href="#group/<%= id %>/"><span class="sf2-icon-library"></span>{% trans "Libraries" %}</a></li>
<% if (!is_pub) { %>
<li class="tab"><a href="{{ SITE_ROOT }}group/<%= id %>/discuss/"><span class="sf2-icon-msgs"></span>{% trans "Discussion" %}</a></li>
<% } %>
<% for (var i = 0, len = mods_enabled.length; i < len; i++) { %>
<% if (mods_enabled[i] == 'group wiki') { %>
<li class="tab"><a href="{{ SITE_ROOT }}group/<%= id %>/wiki/"><span class="sf2-icon-wiki"></span>{% trans "Wiki" %}</a></li>
<% } %>
<% } %>
<li class="tab"><a href="{{ SITE_ROOT }}group/<%= id %>/members/"><span class="sf2-icon-user"></span>{% trans "Members" %}</a></li>
<% if (is_staff) { %>
<li class="tab"><a href="{{ SITE_ROOT }}group/<%= id %>/manage/"><span class="sf2-icon-wrench"></span>{% trans "Admin" %}</a></li>
<% } %>
</ul>
</div>
</script>
<script type="text/template" id="group-mods-enable-form-tmpl">
<form id="mods-enable-form" method="post" action="" class="hide">{% csrf_token%}
@ -888,3 +905,10 @@
<p class="empty-tips alc">{% trans "No library is shared to this group" %}</p>
<% } %>
</script>
<script type="text/template" id="group-member-tmpl">
<img src="<%= avatar_url %>" alt="" width="32" class="avatar fleft" />
<div class="txt">
<p class="txt-item ellipsis" title="<%- name %>"><%- name %></p>
<p class="txt-item ellipsis" title="<%- contact_email %>"><%- contact_email %></p>
</div>
</script>

View File

@ -11,54 +11,16 @@
{% endblock %}
{% block left_panel %}
<div class="side-tabnav hide" id="myhome-side-nav">
</div>
<div class="side-tabnav hide" id="group-side-nav">
</div>
<div class="side-tabnav hide" id="org-side-nav">
<h3 class="hd">{% trans "Organization" %}</h3>
<ul class="side-tabnav-tabs">
<li class="tab tab-cur"><a href="{{ SITE_ROOT }}#org/"><span class="sf2-icon-library"></span>{% trans "Libraries" %}</a></li>
<li class="tab"><a href="{% url 'pubuser' %}"><span class="sf2-icon-user"></span>{% trans "Members" %}</a></li>
</ul>
</div>
<div class="info-item hide" id="groups-side-tips">
<h3 class="info-item-top">{% trans "Tips" %}</h3>
<div class="info-item-bottom">
{% if user.permissions.can_add_group %}
<p class="not-last">{% trans "After creating a group, you can add members and share libraries into it." %}</p>
{% else %}
<p class="not-last">{% trans "Since you are a guest user now, you can not create groups." %}</p>
{% endif %}
</div>
</div>
<div class="side-tabnav hide" id="side-nav"></div>
{% endblock %}
{% block right_panel %}
<div id="repo-tabs" class="tab-tabs hide">
<div class="hd">
<ul class="tab-tabs-nav fleft">
{% if user.permissions.can_add_repo %}
<li class="tab"><a href="#my-libs/" class="a" id="mylib-tab">{% trans "Mine" %}</a></li>
{% if sub_lib_enabled %}
<li class="tab"><a href="#my-sub-libs/" class="a" id="sublib-tab">{% trans "Sub-libraries" %}</a></li>
{% endif %}
{% endif %}
<li class="tab"><a href="#shared-libs/" class="a" id="shared-lib-tab">{% trans "Shared" %}</a></li>
</ul>
<div class="fright">
{% if user.permissions.can_add_repo %}
<button class="repo-create"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "New Library" %}</span></button>
{% endif %}
{% if sub_lib_enabled %}
<button id="sub-lib-create" class="hide" title="{% trans "New Sub-library" %}"><img src="{{ MEDIA_URL }}img/add.png" alt="" class="add vam" /><span class="vam">{% trans "New Sub-library" %}</span></button>
{% endif %}
{% if user.permissions.can_add_repo %}
<div id="my-own-repos" class="hide">
<div class="hd ovhd">
<h3 class="fleft">{% trans "Mine" %}</h3>
<button class="repo-create fright"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "New Library" %}</span></button>
</div>
</div>
<div id="my-own-repos">
<table class="hide">
<thead></thead>
<tbody></tbody>
@ -67,9 +29,17 @@
<h2 class="alc">{% trans "You have not created any libraries" %}</h2>
<p>{% trans "You can create a library to organize your files. For example, you can create one for each of your projects. Each library can be synchronized and shared separately." %}</p>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
</div>
{% endif %}
<div id="my-sub-repos">
{% if user.permissions.can_add_repo and sub_lib_enabled %}
<div id="my-sub-repos" class="hide">
<div class="hd ovhd">
<h3 class="fleft">{% trans "Sub-libraries" %}</h3>
<button id="sub-lib-create" class="fright"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "New Sub-library" %}</span></button>
</div>
<table class="hide">
<thead>
<tr>
@ -86,9 +56,13 @@
<h2 class="center-contents">{% trans "You have not created any sub-libraries" %}</h2>
<p>{% trans "You can create a sub-library from a directory inside a library. A sub-library can be independently synced and shared. Files in the sub-library will be automatically kept in sync with those in the directory of the origin library." %}</p>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
</div>
{% endif %}
<div id="repos-shared-to-me">
<div id="repos-shared-to-me" class="hide">
<h3 class="hd">{% trans "Shared" %}</h3>
<table class="hide">
<thead></thead>
<tbody></tbody>
@ -96,11 +70,10 @@
<div class="empty-tips hide">
<h2 class="alc">{% trans "No library is shared to you" %}</h2>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
</div>
<div id="starred-file" class="hide">
<h3 class="hd">{% trans "Starred" %}</h3>
@ -157,34 +130,41 @@
</form>
{% endif %}
<div id="group-repo-tabs" class="tab-tabs hide">
<div class="hd ovhd">
<h3 class="fleft">{% trans "Libraries" %}</h3>
{% if user.permissions.can_add_repo %}
<button class="repo-create fright"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "New Library" %}</span></button>
{% endif %}
</div>
<div id="group" class="hide">
<div id="group-top"></div>
<div id="grp-repos">
<table style="display:none">
<div id="group-repos">
<table class="hide">
<thead></thead>
<tbody></tbody>
</table>
<div class="empty-tips" style="margin-bottom:150px; display:none;">
<h2 class="alc">{% trans "No library is shared to this group" %}</h2>
<p>{% blocktrans %}You can share libraries by clicking the "New Library" button above or the "Share" icon on your libraries list.{% endblocktrans %}</p>
<p>{% trans "Libraries shared as writable can be downloaded and synced by other group members. Read only libraries can only be downloaded, updates by others will not be uploaded." %}</p>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
<div id="group-members" class="popover hide">
<div class="outer-caret up-outer-caret"><div class="inner-caret"></div></div>
<div class="popover-hd ovhd">
<span class="popover-close close sf2-icon-x1 op-icon fright" title="{% trans "Close" %}"></span>
<h3 class="popover-title">{% trans "Members" %}</h3>
</div>
<div class="popover-con">
<span class="loading-icon loading-tip"></span>
<ul id="group-member-list" class="hide"></ul>
<p class="error hide"></p>
</div>
</div>
</div>
<div id="organization-repos" class="tab-tabs hide">
<div id="organization-repos" class="hide">
<div class="hd">
<h3 class="fleft">{% trans "Libraries" %}</h3>
<h3 class="fleft">{% trans "Organization" %}</h3>
<button id="add-pub-lib" class="fright"><span class="icon-plus-square add vam"></span><span class="vam">{% trans "Add Library"%}</span></button>
<ul id="add-pub-lib-menu" class="hide">
<li class="item share-existing">{% trans "Share existing libraries" %}</li>
@ -255,17 +235,6 @@ app["pageOptions"] = {
{% endfor %}
return groups;
})(),
top_nav_groups: (function () {
var groups = [];
{% for group in grps %}
groups.push({
'name': '{{group.group_name}}',
'id': '{{group.id}}',
'avatar': '{% grp_avatar group.id 36 %}'
});
{% endfor %}
return groups;
})(),
user_mods_available: (function () {
var mods_available = [];
{% for mod in request.user.mods_available %}

View File

@ -1,50 +0,0 @@
{% load seahub_tags group_avatar_tags i18n %}<div id="group-repos">
{% if group_repos %}
<table>
<tr>
<th width="4%"><!--icon--></th>
<th width="13%">{% trans "Group" %}</th>
<th width="4%"><!--icon--></th>
<th width="20%">{% trans "Name" %}</th>
<th width="29%">{% trans "Description" %}</th>
<th width="15%">{% trans "Last Update" %}</th>
<th width="15%">{% trans "Shared By" %}</th>
</tr>
{% for repo in group_repos %}
<tr>
{% if repo.show_group_name %}
<td>{% grp_avatar repo.group.id 20 %}</td>
<td><a href="{% url 'group_info' repo.group.id %}">{{ repo.group.group_name }}</a></td>
{% else %}
<td></td>
<td></td>
{% endif %}
<td>
{% if repo.encrypted %}
<img src="{{MEDIA_URL}}img/sync-folder-encrypt-20.png" title="{% trans "Read-Write" %}" alt="{% trans "directory icon" %}" />
{% else %}
{% if repo.user_perm == 'rw' %}
<img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="{% trans "directory icon" %}" />
{% else %}
<img src="{{MEDIA_URL}}img/folder-no-write-20.png?t=1387267140" title="{% trans "Read-Only" %}" alt="{% trans "directory icon" %}" />
{% endif %}
{% endif %}
</td>
<td><a href="{% url 'repo' repo.repo_id %}">{{ repo.repo_name }}</a></td>
<td>{{ repo.repo_desc }}</td>
{% if repo.last_modified %}
<td>{{ repo.last_modified|translate_seahub_time }}</td>
{% else %}
<td>--</td>
{% endif %}
<td>{{ repo.user|email2nickname }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="empty-tips">
<h2 class="alc">{% trans "No library is shared to your groups" %}</h2>
</div>
{% endif %}
</div>

View File

@ -1,20 +1,4 @@
{% extends "base.html" %}
{% load i18n %}
{% block nav %}
<ul class="nav">
<li class="nav-item">
<a href="{{ SITE_ROOT }}" class="a {% block cur_myhome %}{% endblock %}">{% trans "My Home" %}</a>
</li>
<li class="nav-item" {% if grps %}style="position:relative;"{% endif %}>
<a href="{% url 'group_list' %}" class="a {% block cur_group %}{% endblock %}" {% if grps %}id="top-nav-grp"{% endif %}>{% trans "Groups" %}{% if grps %} <span class="icon-caret-down"></span>{% endif %}</a>
</li>
{% if user.permissions.can_view_org %}
<li class="nav-item">
<a href="{{ SITE_ROOT }}#org/" class="a {% block cur_pubinfo %}{% endblock %}">{% trans "Organization" %}</a>
</li>
{% endif %}
<li class="nav-item">
<a href="{{ SITE_ROOT }}help/" class="a {% block cur_help %}{% endblock %}">{% trans "Help" %}</a>
</li>
</ul>
{% endblock %}

View File

@ -98,6 +98,7 @@ urlpatterns = patterns(
url(r'^lib/(?P<repo_id>[-0-9a-f]{36})/file(?P<path>.*)$', view_lib_file, name='view_lib_file'),
url(r'^#common/lib/(?P<repo_id>[-0-9a-f]{36})/(?P<path>.*)$', fake_view, name='view_common_lib_dir'),
url(r'^#group/(?P<group_id>\d+)/$', fake_view, name='view_group'),
url(r'^#group/(?P<group_id>\d+)/members/$', fake_view, name='group_members'),
url(r'^#groups/', fake_view, name='group_list'),
# url(r'^home/my/lib/(?P<repo_id>[-0-9a-f]{36})/dir/(?P<path>.*)$', myhome_lib, name='myhome_lib'),
@ -192,6 +193,7 @@ urlpatterns = patterns(
### Apps ###
(r'^api2/', include('seahub.api2.urls')),
url(r'^api/v2.1/groups/$', Groups.as_view(), name='api-v2.1-groups'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/$', Groups.as_view(), name='api-v2.1-group'),
(r'^avatar/', include('seahub.avatar.urls')),
(r'^notification/', include('seahub.notifications.urls')),
(r'^contacts/', include('seahub.contacts.urls')),

View File

@ -0,0 +1,19 @@
define([
'underscore',
'backbone',
'common'
], function(_, Backbone, Common) {
'use strict';
var GroupMemberCollection = Backbone.Collection.extend({
setGroupId: function(group_id) {
this.group_id = group_id;
},
url: function() {
return Common.getUrl({name: 'group_members', group_id: this.group_id});
}
});
return GroupMemberCollection;
});

View File

@ -3,14 +3,14 @@ define([
'jquery',
'backbone',
'common',
'app/views/side-nav',
'app/views/myhome',
'app/views/groups',
'app/views/group',
'app/views/organization',
'app/views/dir',
'app/views/top-group-nav'
], function($, Backbone, Common, MyHomeView, GroupsView, GroupView, OrgView,
DirView, GroupNavView) {
'app/views/dir'
], function($, Backbone, Common, SideNavView, MyHomeView, GroupsView, GroupView,
OrgView, DirView) {
"use strict";
var Router = Backbone.Router.extend({
@ -25,6 +25,7 @@ define([
'groups/': 'showGroups',
'group/:group_id/': 'showGroupRepos',
'group/:group_id/lib/:repo_id(/*path)': 'showGroupRepoDir',
'group/:group_id/members/': 'showGroupMembers',
'org/': 'showOrgRepos',
'org/lib/:repo_id(/*path)': 'showOrgRepoDir',
'common/lib/:repo_id(/*path)': 'showCommonDir',
@ -39,6 +40,8 @@ define([
Common.initAccountPopup();
Common.initNoticePopup();
this.sideNavView = new SideNavView();
this.dirView = new DirView();
this.myHomeView = new MyHomeView({dirView: this.dirView});
@ -49,10 +52,6 @@ define([
this.currentView = this.myHomeView;
if (app.pageOptions.top_nav_groups.length > 0) {
this.topGroupNavView = new GroupNavView();
}
$('#info-bar .close').click(Common.closeTopNoticeBar);
$('#top-browser-tip .close').click(function () {
$('#top-browser-tip').addClass('hide');
@ -72,12 +71,14 @@ define([
this.myHomeView.showMyRepos();
} else {
this.myHomeView.showSharedRepos();
this.sideNavView.setCurTab('shared');
}
},
showMyRepos: function() {
this.switchCurrentView(this.myHomeView);
this.myHomeView.showMyRepos();
this.sideNavView.setCurTab('mine');
},
showMySubRepos: function() {
@ -88,16 +89,19 @@ define([
showSharedRepos: function() {
this.switchCurrentView(this.myHomeView);
this.myHomeView.showSharedRepos();
this.sideNavView.setCurTab('shared');
},
showStarredFile: function() {
this.switchCurrentView(this.myHomeView);
this.myHomeView.showStarredFile();
this.sideNavView.setCurTab('starred');
},
showActivities: function() {
this.switchCurrentView(this.myHomeView);
this.myHomeView.showActivities();
this.sideNavView.setCurTab('activities');
},
showMyRepoDir: function(repo_id, path) {
@ -108,6 +112,7 @@ define([
}
this.switchCurrentView(this.myHomeView);
this.myHomeView.showDir('my-libs', repo_id, path);
this.sideNavView.setCurTab('mine');
},
showCommonDir: function(repo_id, path) {
@ -128,6 +133,7 @@ define([
}
this.switchCurrentView(this.myHomeView);
this.myHomeView.showDir('my-sub-libs', repo_id, path);
this.sideNavView.setCurTab('sub-libs');
},
showSharedRepoDir: function(repo_id, path) {
@ -138,16 +144,25 @@ define([
}
this.switchCurrentView(this.myHomeView);
this.myHomeView.showDir('shared-libs', repo_id, path);
this.sideNavView.setCurTab('shared');
},
showGroups: function () {
this.switchCurrentView(this.groupsView);
this.groupsView.show();
this.sideNavView.setCurTab('group', {
'cur_group_tab': 'groups',
'cur_group_id': ''
});
},
showGroupRepos: function(group_id) {
this.switchCurrentView(this.groupView);
this.groupView.showRepoList(group_id);
this.sideNavView.setCurTab('group', {
'cur_group_tab': '',
'cur_group_id': group_id
});
},
showGroupRepoDir: function(group_id, repo_id, path) {
@ -158,11 +173,21 @@ define([
}
this.switchCurrentView(this.groupView);
this.groupView.showDir(group_id, repo_id, path);
this.sideNavView.setCurTab('group', {
'cur_group_tab': '',
'cur_group_id': group_id
});
},
showGroupMembers: function(group_id) {
this.showGroupRepos(group_id);
this.groupView.showMembers();
},
showOrgRepos: function() {
this.switchCurrentView(this.orgView);
this.orgView.showRepoList();
this.sideNavView.setCurTab('org');
},
showOrgRepoDir: function(repo_id, path) {
@ -173,6 +198,7 @@ define([
}
this.switchCurrentView(this.orgView);
this.orgView.showDir(repo_id, path);
this.sideNavView.setCurTab('org');
}
});

View File

@ -0,0 +1,47 @@
define([
'jquery',
'underscore',
'backbone',
'common'
], function($, _, Backbone, Common) {
'use strict';
var View = Backbone.View.extend({
tagName: 'li',
className: 'user-item cspt ovhd',
template: _.template($('#group-member-tmpl').html()),
events: {
'mouseenter': 'highlight',
'mouseleave': 'rmHighlight',
'click': 'visitMemberProfile'
},
initialize: function() {
},
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
},
highlight: function() {
this.$el.addClass('hl');
},
rmHighlight: function() {
this.$el.removeClass('hl');
},
visitMemberProfile: function() {
location.href = Common.getUrl({
'name': 'user_profile',
'username': encodeURIComponent(this.model.get('email'))
});
}
});
return View;
});

View File

@ -0,0 +1,110 @@
define([
'jquery',
'underscore',
'backbone',
'common',
'app/collections/group-members',
'app/views/group-member'
], function($, _, Backbone, Common, GroupMembers, ItemView) {
'use strict';
var View = Backbone.View.extend({
el: '#group-members',
initialize: function(options) {
this.collection = new GroupMembers();
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'reset', this.reset);
this.$loadingTip = this.$('.loading-tip');
this.$listContainer = $('#group-member-list');
this.$error = this.$('.error');
var _this = this;
$(window).resize(function() {
_this.setConMaxHeight();
});
$(document).click(function(e) {
var target = e.target || event.srcElement;
var $popup = _this.$el,
$popup_switch = $('#group-members-icon');
if ($('#group-members:visible').length &&
!$popup.is(target) &&
!$popup.find('*').is(target) &&
!$popup_switch.is(target)) {
_this.hide();
}
});
},
events: {
'click .close': 'hide'
},
addOne: function(item, collection, options) {
var view = new ItemView({
model: item
});
this.$listContainer.append(view.render().el);
},
reset: function() {
this.$error.hide();
this.$loadingTip.hide();
this.$listContainer.empty();
this.collection.each(this.addOne, this);
this.$listContainer.show();
},
render: function() {
this.$listContainer.hide();
this.$loadingTip.show();
var _this = this;
this.collection.setGroupId(this.group_id);
this.collection.fetch({
cache: false,
reset: true,
data: {'avatar_size': 64},
success: function(collection, response, opts) {
},
error: function(collection, response, opts) {
_this.$loadingTip.hide();
var err_msg;
if (response.responseText) {
if (response['status'] == 401 || response['status'] == 403) {
err_msg = gettext("Permission error");
} else {
err_msg = gettext("Error");
}
} else {
err_msg = gettext('Please check the network.');
}
_this.$error.html(err_msg).show();
}
});
},
// set max-height for '.popover-con'
setConMaxHeight: function() {
this.$('.popover-con').css({'max-height': $(window).height() - this.$el.offset().top - this.$('.popover-hd').outerHeight(true) - 2}); // 2: top, bottom border width of $el
},
show: function(options) {
this.group_id = options.group_id;
this.$el.show();
this.setConMaxHeight();
this.render();
app.router.navigate('group/' + this.group_id + '/members/');
},
hide: function() {
this.$el.hide();
app.router.navigate('group/' + this.group_id + '/');
}
});
return View;
});

View File

@ -1,96 +0,0 @@
define([
'jquery',
'underscore',
'backbone',
'common'
], function($, _, Backbone, Common) {
'use strict';
var GroupSideNavView = Backbone.View.extend({
el: '#group-side-nav',
template: _.template($("#group-side-nav-tmpl").html()),
enableModTemplate: _.template($("#group-mods-enable-form-tmpl").html()),
initialize: function() {
},
render: function (group_id) {
this.group_id = group_id;
var _this = this;
$.ajax({
url: Common.getUrl({
'name': 'group_basic_info',
'group_id': this.group_id
}),
cache: false,
dataType: 'json',
success: function (data) {
_this.$el.html(_this.template(data));
// for 'enable mod'
_this.mods_available = data.mods_available;
_this.mods_enabled = data.mods_enabled;
},
error: function(xhr) {
var err_msg;
if (xhr.responseText) {
err_msg = $.parseJSON(xhr.responseText).error;
} else {
err_msg = gettext("Please check the network.");
}
_this.$el.html('<p class="error">' + err_msg + '</p>');
}
});
},
events: {
'click #enable-mods': 'enableMods'
},
enableMods: function () {
var form = $(this.enableModTemplate({
'mods_available': this.mods_available,
'mods_enabled': this.mods_enabled
}));
form.modal();
$('#simplemodal-container').css('height', 'auto');
$('.checkbox-orig', form).click(function() {
$(this).parent().toggleClass('checkbox-checked');
});
var checkbox = $('[name="group_wiki"]');
var original_checked = checkbox.prop('checked');
var _this = this;
form.submit(function() {
var cur_checked = checkbox.prop('checked');
if (cur_checked == original_checked) {
return false;
}
Common.ajaxPost({
form: form,
form_id: form.attr('id'),
post_url: Common.getUrl({
'name': 'toggle_group_modules',
'group_id': _this.group_id
}),
post_data: {'group_wiki': cur_checked },
after_op_success: function () {
$.modal.close();
_this.render(_this.group_id);
}
});
return false;
});
},
show: function() {
this.$el.show();
},
hide: function() {
this.$el.hide();
}
});
return GroupSideNavView;
});

View File

@ -6,17 +6,19 @@ define([
'app/collections/group-repos',
'app/views/group-repo',
'app/views/add-group-repo',
'app/views/group-side-nav'
'app/views/group-members'
], function($, _, Backbone, Common, GroupRepos, GroupRepoView,
AddGroupRepoView, GroupSideNavView) {
AddGroupRepoView, GroupMembersView) {
'use strict';
var GroupView = Backbone.View.extend({
el: '#group-repo-tabs',
el: '#group',
groupTopTemplate: _.template($('#group-top-tmpl').html()),
reposHdTemplate: _.template($('#shared-repos-hd-tmpl').html()),
events: {
'click #group-members-icon': 'toggleMembersPanel',
'click .repo-create': 'createRepo',
'click .by-name': 'sortByName',
'click .by-time': 'sortByTime'
@ -27,16 +29,16 @@ define([
this.$table = this.$('table');
this.$tableHead = this.$('thead');
this.$tableBody = this.$('tbody');
this.$loadingTip = this.$('.loading-tip');
this.$emptyTip = this.$('.empty-tips');
this.sideNavView = new GroupSideNavView();
this.$loadingTip = this.$('#group-repos .loading-tip');
this.$emptyTip = this.$('#group-repos .empty-tips');
this.repos = new GroupRepos();
this.listenTo(this.repos, 'add', this.addOne);
this.listenTo(this.repos, 'reset', this.reset);
this.dirView = options.dirView;
this.membersView = new GroupMembersView();
},
addOne: function(repo, collection, options) {
@ -71,21 +73,36 @@ define([
}
},
showSideNav: function () {
var sideNavView = this.sideNavView;
if (sideNavView.group_id && sideNavView.group_id == this.group_id) {
sideNavView.show();
return;
}
sideNavView.render(this.group_id);
sideNavView.show();
renderGroupTop: function(group_id) {
var _this = this;
var $groupTop = $('#group-top');
$.ajax({
url: Common.getUrl({
'name': 'group_basic_info',
'group_id': group_id
}),
cache: false,
dataType: 'json',
success: function (data) {
$groupTop.html(_this.groupTopTemplate(data));
},
error: function(xhr) {
var err_msg;
if (xhr.responseText) {
err_msg = $.parseJSON(xhr.responseText).error;
} else {
err_msg = gettext("Please check the network.");
}
$groupTop.html('<p class="error">' + err_msg + '</p>');
}
});
},
showRepoList: function(group_id) {
this.group_id = group_id;
this.showSideNav();
this.dirView.hide();
this.$emptyTip.hide();
this.renderGroupTop(group_id);
this.$tabs.show();
this.$table.hide();
var $loadingTip = this.$loadingTip;
@ -122,7 +139,6 @@ define([
showDir: function(group_id, repo_id, path) {
this.group_id = group_id;
this.showSideNav();
this.hideRepoList();
this.dirView.showDir('group/' + this.group_id, repo_id, path);
},
@ -169,10 +185,22 @@ define([
},
hide: function() {
this.sideNavView.hide();
this.hideRepoList();
this.dirView.hide();
this.$emptyTip.hide();
},
showMembers: function() {
this.membersView.show({'group_id': this.group_id});
},
toggleMembersPanel: function() {
var panel_id = this.membersView.el.id;
if ($('#' + panel_id + ':visible').length) { // the panel is shown
this.membersView.hide();
} else {
this.showMembers();
}
}
});

View File

@ -16,7 +16,6 @@ define([
this.listenTo(this.groups, 'add', this.addOne);
this.listenTo(this.groups, 'reset', this.reset);
this.$sideTips = $('#groups-side-tips');
this.$loadingTip = this.$('.loading-tip');
this.$groupList = $('#group-list');
this.$emptyTip = this.$('.empty-tips');
@ -82,13 +81,11 @@ define([
},
show: function() {
this.$sideTips.show();
this.$el.show();
this.render();
},
hide: function() {
this.$sideTips.hide();
this.$el.hide();
},

View File

@ -10,23 +10,22 @@ define([
'use strict';
var ReposView = Backbone.View.extend({
el: $('#repo-tabs'),
el: $('#my-own-repos'),
reposHdTemplate: _.template($('#my-repos-hd-tmpl').html()),
events: {
'click .repo-create': 'createRepo',
'click #my-own-repos .by-name': 'sortByName',
'click #my-own-repos .by-time': 'sortByTime'
'click .by-name': 'sortByName',
'click .by-time': 'sortByTime'
},
initialize: function(options) {
this.$tabs = $('#repo-tabs');
this.$table = this.$('#my-own-repos table');
this.$table = this.$('table');
this.$tableHead = $('thead', this.$table);
this.$tableBody = $('tbody', this.$table);
this.$loadingTip = $('.loading-tip', this.$tabs);
this.$emptyTip = $('#my-own-repos .empty-tips');
this.$loadingTip = this.$('.loading-tip');
this.$emptyTip = this.$('.empty-tips');
this.$repoCreateBtn = this.$('.repo-create');
this.repos = new RepoCollection();
@ -68,8 +67,7 @@ define([
},
showMyRepos: function() {
this.$tabs.show();
$('#mylib-tab').parent().addClass('ui-state-active');
this.$el.show();
this.$table.hide();
var $loadingTip = this.$loadingTip;
$loadingTip.show();
@ -98,16 +96,11 @@ define([
},
show: function() {
this.$repoCreateBtn.show();
this.showMyRepos();
},
hide: function() {
this.$repoCreateBtn.hide();
this.$el.hide();
this.$table.hide();
this.$emptyTip.hide();
$('#mylib-tab', this.$tabs).parent().removeClass('ui-state-active');
},
createRepo: function() {

View File

@ -9,17 +9,16 @@ define([
'use strict';
var SharedReposView = Backbone.View.extend({
el: $('#repo-tabs'),
el: $('#repos-shared-to-me'),
reposHdTemplate: _.template($('#shared-repos-hd-tmpl').html()),
initialize: function(options) {
this.$tabs = $('#repo-tabs');
this.$table = $('#repos-shared-to-me table');
this.$table = this.$('table');
this.$tableHead = $('thead', this.$table);
this.$tableBody = $('tbody', this.$table);
this.$loadingTip = $('.loading-tip', this.$tabs);
this.$emptyTip = $('#repos-shared-to-me .empty-tips');
this.$loadingTip = this.$('.loading-tip');
this.$emptyTip = this.$('.empty-tips');
this.repos = new RepoCollection({type: 'shared'});
this.listenTo(this.repos, 'add', this.addOne);
@ -55,8 +54,7 @@ define([
},
showSharedRepos: function() {
this.$tabs.show();
$('#shared-lib-tab').parent().addClass('ui-state-active');
this.$el.show();
this.$table.hide();
var $loadingTip = this.$loadingTip;
$loadingTip.show();
@ -89,14 +87,11 @@ define([
hide: function() {
this.$el.hide();
this.$table.hide();
this.$emptyTip.hide();
$('#shared-lib-tab', this.$tabs).parent().removeClass('ui-state-active');
},
events: {
'click #repos-shared-to-me .by-name': 'sortByName',
'click #repos-shared-to-me .by-time': 'sortByTime'
'click .by-name': 'sortByName',
'click .by-time': 'sortByTime'
},
sortByName: function() {

View File

@ -11,19 +11,18 @@ define([
'use strict';
var ReposView = Backbone.View.extend({
el: $('#repo-tabs'),
el: $('#my-sub-repos'),
events: {
'click #sub-lib-create': 'createRepo'
},
initialize: function(options) {
this.$tabs = $('#repo-tabs');
this.$table = this.$('#my-sub-repos table');
this.$table = this.$('table');
this.$tableHead = $('thead', this.$table);
this.$tableBody = $('tbody', this.$table);
this.$loadingTip = $('.loading-tip', this.$tabs);
this.$emptyTip = $('#my-sub-repos .empty-tips');
this.$loadingTip = this.$('.loading-tip');
this.$emptyTip = this.$('.empty-tips');
this.repos = new RepoCollection({type: 'sub'});
this.listenTo(this.repos, 'add', this.addOne);
@ -54,8 +53,7 @@ define([
},
showSubRepos: function() {
this.$tabs.show();
$('#sublib-tab').parent().addClass('ui-state-active');
this.$el.show();
this.$table.hide();
var $loadingTip = this.$loadingTip;
$loadingTip.show();
@ -83,16 +81,11 @@ define([
},
show: function() {
$('#sub-lib-create').show();
this.showSubRepos();
},
hide: function() {
$('#sub-lib-create').hide();
this.$el.hide();
this.$table.hide();
this.$emptyTip.hide();
$('#sublib-tab', this.$tabs).parent().removeClass('ui-state-active');
},
createRepo: function() {

View File

@ -7,17 +7,15 @@ define([
'app/views/myhome-sub-repos',
'app/views/myhome-shared-repos',
'app/views/starred-file',
'app/views/activities',
'app/views/myhome-side-nav'
'app/views/activities'
], function($, _, Backbone, Common, ReposView, SubReposView,
SharedReposView, StarredFileView, ActivitiesView, MyhomeSideNavView) {
SharedReposView, StarredFileView, ActivitiesView) {
'use strict';
var MyHomeView = Backbone.View.extend({
el: '#main',
initialize: function(options) {
this.sideNavView = new MyhomeSideNavView();
this.reposView = new ReposView();
this.subReposView = new SubReposView();
this.sharedReposView = new SharedReposView();
@ -32,42 +30,36 @@ define([
},
showMyRepos: function() {
this.sideNavView.show();
this.currentView.hide();
this.reposView.show();
this.currentView = this.reposView;
},
showMySubRepos: function() {
this.sideNavView.show();
this.currentView.hide();
this.subReposView.show();
this.currentView = this.subReposView;
},
showSharedRepos: function() {
this.sideNavView.show();
this.currentView.hide();
this.sharedReposView.show();
this.currentView = this.sharedReposView;
},
showStarredFile: function() {
this.sideNavView.show({'cur_tab': 'starred'});
this.currentView.hide();
this.starredFileView.show();
this.currentView = this.starredFileView;
},
showActivities: function() {
this.sideNavView.show({'cur_tab': 'activities'});
this.currentView.hide();
this.activitiesView.show();
this.currentView = this.activitiesView;
},
showDir: function(category, repo_id, path) {
this.sideNavView.show();
var path = path || '/';
this.currentView.hide();
this.dirView.showDir(category, repo_id, path);
@ -76,7 +68,6 @@ define([
hide: function() {
this.currentView.hide();
this.sideNavView.hide();
}
});

View File

@ -12,19 +12,16 @@ define([
'use strict';
var OrganizationView = Backbone.View.extend({
el: '#main',
el: '#organization-repos',
reposHdTemplate: _.template($('#shared-repos-hd-tmpl').html()),
initialize: function(options) {
this.$sideNav = $('#org-side-nav');
this.$reposDiv = $('#organization-repos');
this.$table = $('#organization-repos table');
this.$table = this.$('table');
this.$tableHead = $('thead', this.$table);
this.$tableBody = $('tbody', this.$table);
this.$loadingTip = $('#organization-repos .loading-tip');
this.$emptyTip = $('#organization-repos .empty-tips');
this.$loadingTip = this.$('.loading-tip');
this.$emptyTip = this.$('.empty-tips');
this.repos = new PubRepoCollection();
this.listenTo(this.repos, 'add', this.addOne);
@ -56,10 +53,10 @@ define([
},
events: {
'click #organization-repos .share-existing': 'addRepo',
'click #organization-repos .create-new': 'createRepo',
'click #organization-repos .by-name': 'sortByName',
'click #organization-repos .by-time': 'sortByTime'
'click .share-existing': 'addRepo',
'click .create-new': 'createRepo',
'click .by-name': 'sortByName',
'click .by-time': 'sortByTime'
},
createRepo: function() {
@ -99,9 +96,8 @@ define([
},
showRepoList: function() {
this.$sideNav.show();
this.dirView.hide();
this.$reposDiv.show();
this.$el.show();
var $loadingTip = this.$loadingTip;
$loadingTip.show();
var _this = this;
@ -129,11 +125,10 @@ define([
},
hideRepoList: function() {
this.$reposDiv.hide();
this.$el.hide();
},
showDir: function(repo_id, path) {
this.$sideNav.show();
var path = path || '/';
this.hideRepoList();
this.dirView.showDir('org', repo_id, path);
@ -177,7 +172,6 @@ define([
},
hide: function() {
this.$sideNav.hide();
this.hideRepoList();
this.$emptyTip.hide();
this.dirView.hide();

View File

@ -6,21 +6,22 @@ define([
], function($, _, Backbone, Common) {
'use strict';
var MyhomeSideNavView = Backbone.View.extend({
el: '#myhome-side-nav',
var sideNavView = Backbone.View.extend({
el: '#side-nav',
template: _.template($("#myhome-side-nav-tmpl").html()),
template: _.template($("#side-nav-tmpl").html()),
enableModTemplate: _.template($("#myhome-mods-enable-form-tmpl").html()),
initialize: function() {
this.default_cur_tab = 'libs';
this.default_cur_tab = 'mine';
this.data = {
'cur_tab': this.default_cur_tab,
'show_group_list': false, // when cur_tab is not 'group'
'mods_enabled': app.pageOptions.user_mods_enabled,
'can_add_repo': app.pageOptions.can_add_repo,
'events_enabled': app.pageOptions.events_enabled
};
this.render();
this.$el.show();
},
render: function() {
@ -29,7 +30,14 @@ define([
},
events: {
'click #myhome-enable-mods': 'enableMods'
'click #group-nav a:first': 'toggleGroupList',
'click #enable-mods': 'enableMods'
},
toggleGroupList: function () {
$('#group-nav .toggle-icon').toggleClass('icon-caret-left icon-caret-down');
$('#group-nav .grp-list').slideToggle();
return false;
},
enableMods: function () {
@ -77,24 +85,16 @@ define([
});
},
show: function(options) {
if (options && options.cur_tab) {
this.data.cur_tab = options.cur_tab;
this.render();
} else {
if (this.data.cur_tab != this.default_cur_tab) {
this.data.cur_tab = this.default_cur_tab;
this.render();
}
setCurTab: function (cur_tab, options) {
this.data.cur_tab = cur_tab || this.default_cur_tab;
if (options) {
$.extend(this.data, options);
}
this.$el.show();
},
hide: function() {
this.$el.hide();
this.data.show_group_list = $('#group-nav .grp-list:visible').length ? true : false;
this.render();
}
});
return MyhomeSideNavView;
return sideNavView;
});

View File

@ -1,52 +0,0 @@
define([
'jquery',
'underscore',
'backbone',
'common'
], function($, _, Backbone, Common) {
'use strict';
var GroupNavView = Backbone.View.extend({
el: '.nav .nav-item-group',
popupTemplate: _.template($('#top-group-nav-tmpl').html()),
initialize: function() {
var popup = $(this.popupTemplate({groups: app.pageOptions.top_nav_groups}));
this.$el.append(popup);
popup.css({'right': ($('#top-nav-grp').outerWidth() - popup.outerWidth())/6 * 5});
this.popup = popup;
},
events: {
'mouseenter': 'showPopup',
'mouseleave': 'hidePopup',
'mouseenter #top-nav-grp-list .item': 'highlightGroupItem',
'mouseleave #top-nav-grp-list .item': 'rmHighlightGroupItem',
'click #top-nav-grp-list .item': 'visitGroup'
},
showPopup: function(e) {
this.popup.removeClass('hide');
},
hidePopup: function(e) {
this.popup.addClass('hide');
},
highlightGroupItem: function(e) {
$(e.currentTarget).addClass('hl').children('a').removeClass('vh');
},
rmHighlightGroupItem: function(e) {
$(e.currentTarget).removeClass('hl').children('a').addClass('vh');
},
visitGroup: function(e) {
this.hidePopup(e);
location.href = $(e.currentTarget).attr('data-url');
}
});
return GroupNavView;
});

View File

@ -104,6 +104,7 @@ define([
case 'repo_set_password': return siteRoot + 'repo/set_password/';
case 'groups': return siteRoot + 'api/v2.1/groups/';
case 'group_repos': return siteRoot + 'api2/groups/' + options.group_id + '/repos/';
case 'group_members': return siteRoot + 'api/v2.1/groups/' + options.group_id + '/members/';
case 'group_basic_info': return siteRoot + 'ajax/group/' + options.group_id + '/basic-info/';
case 'toggle_group_modules': return siteRoot + 'ajax/group/' + options.group_id + '/toggle-modules/';
case 'toggle_personal_modules': return siteRoot + 'ajax/toggle-personal-modules/';
@ -117,6 +118,7 @@ define([
case 'search_user': return siteRoot + 'api2/search-user/';
case 'dir_shared_items': return siteRoot + 'api2/repos/' + options.repo_id + '/dir/shared_items/';
case 'events': return siteRoot + 'api2/events/';
case 'user_profile': return siteRoot + 'profile/' + options.username + '/';
}
},

View File

@ -7,6 +7,7 @@ from seaserv import seafile_api
from seahub.test_utils import BaseTestCase
from seahub.api2.endpoints.groups import Groups
from tests.common.utils import randstring
class GroupsTest(BaseTestCase):
@ -61,7 +62,7 @@ class GroupsTest(BaseTestCase):
assert self.group_id in group_ids
def test_create_group(self):
new_group_name = 'new-group-1'
new_group_name = 'new-group-' + randstring(6)
resp = self.client.post(self.url, {'group_name': new_group_name})
self.assertEqual(201, resp.status_code)
@ -74,7 +75,7 @@ class GroupsTest(BaseTestCase):
self.remove_group(json_resp['id'])
def test_create_group_with_cn_name(self):
new_group_name = u'中文'
new_group_name = u'中文' + randstring(6)
resp = self.client.post(self.url, {'group_name': new_group_name})
self.assertEqual(201, resp.status_code)
@ -90,15 +91,53 @@ class GroupsTest(BaseTestCase):
self.assertEqual(400, resp.status_code)
def test_can_not_create_group_with_invalid_name(self):
group_name = 'new%group-2'
new_group_name = 'new%group-' + randstring(6)
resp = self.client.post(self.url, {'group_name': group_name})
resp = self.client.post(self.url, {'group_name': new_group_name})
self.assertEqual(400, resp.status_code)
@patch.object(Groups, '_can_add_group')
def test_can_not_create_group_with_invalid_permission(self, mock_can_add_group):
mock_can_add_group.return_value = False
group_name = 'new-group-3'
new_group_name = 'new-group-' + randstring(6)
resp = self.client.post(self.url, {'group_name': group_name})
resp = self.client.post(self.url, {'group_name': new_group_name})
self.assertEqual(403, resp.status_code)
def test_can_rename_group(self):
new_group_name = 'new-group-' + randstring(6)
url = reverse('api-v2.1-group', args=[self.group_id])
data = 'operation=rename&new_group_name=%s' % new_group_name
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
self.assertEqual(200, resp.status_code)
json_resp = json.loads(resp.content)
assert json_resp['name'] == new_group_name
def test_can_transfer_group(self):
new_creator = self.admin.email
url = reverse('api-v2.1-group', args=[self.group_id])
data = 'operation=transfer&email=%s' % new_creator
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
self.assertEqual(200, resp.status_code)
json_resp = json.loads(resp.content)
assert json_resp['creator'] == new_creator
def test_can_not_transfer_group_to_group_owner(self):
new_creator = self.user.email
url = reverse('api-v2.1-group', args=[self.group_id])
data = 'operation=transfer&email=%s' % new_creator
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
self.assertEqual(400, resp.status_code)
def test_can_delete_group(self):
url = reverse('api-v2.1-group', args=[self.group_id])
resp = self.client.delete(url)
self.assertEqual(200, resp.status_code)
json_resp = json.loads(resp.content)
assert json_resp['success'] is True

View File

@ -198,6 +198,8 @@ class UserInfoTest(BaseTestCase):
self.admin_repo_id = r.id
# set common user as staff in admin user's group
ccnet_threaded_rpc.group_add_member(self.admin_group_1_id,
self.admin.email, self.user.email)
ccnet_threaded_rpc.group_set_admin(self.admin_group_1_id, self.user.email)
# add common user to admin user's another group