1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-11 11:51:27 +00:00

[group members] redesigned it

This commit is contained in:
llj
2015-12-11 20:41:16 +08:00
parent 4c3e5ab067
commit 03d075a00b
14 changed files with 284 additions and 120 deletions

View File

@@ -1140,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;
@@ -3696,6 +3735,7 @@ img.thumbnail {
border-radius:3px;
margin:0;
}
/**** #groups ****/ /* groups page */
#groups .group-name {
font-size:16px;
margin:15px 0 10px;
@@ -3706,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;
}

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.defaults import *
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

@@ -643,7 +643,7 @@
<% if (is_staff) { %>
<span class="sf2-icon-cog1 op-icon" title="{% trans "Admin" %}"></span>
<% } %>
<span class="sf2-icon-user2 op-icon" title="{% trans "Members" %}"></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>
<% } %>
@@ -905,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

@@ -130,26 +130,38 @@
</form>
{% endif %}
<div id="group-repo-tabs" class="hide">
<div id="group" class="hide">
<div id="group-top"></div>
<div id="grp-repos">
<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>
</div>
<span class="loading-icon loading-tip"></span>
<p class="error error-tip hide"></p>
</div>
<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="hide">
<div class="hd">
<h3 class="fleft">{% trans "Organization" %}</h3>

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

@@ -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'),

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

@@ -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',
@@ -178,6 +179,11 @@ define([
});
},
showGroupMembers: function(group_id) {
this.showGroupRepos(group_id);
this.groupView.showMembers();
},
showOrgRepos: function() {
this.switchCurrentView(this.orgView);
this.orgView.showRepoList();

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': 32},
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

@@ -5,18 +5,20 @@ define([
'common',
'app/collections/group-repos',
'app/views/group-repo',
'app/views/add-group-repo'
'app/views/add-group-repo',
'app/views/group-members'
], function($, _, Backbone, Common, GroupRepos, GroupRepoView,
AddGroupRepoView) {
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,8 +29,8 @@ define([
this.$table = this.$('table');
this.$tableHead = this.$('thead');
this.$tableBody = this.$('tbody');
this.$loadingTip = this.$('.loading-tip');
this.$emptyTip = this.$('.empty-tips');
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);
@@ -36,6 +38,7 @@ define([
this.dirView = options.dirView;
this.membersView = new GroupMembersView();
},
addOne: function(repo, collection, options) {
@@ -185,6 +188,19 @@ define([
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

@@ -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 + '/';
}
},