1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-14 06:11:16 +00:00
This commit is contained in:
zhengxie
2015-01-21 22:22:34 +08:00
committed by Daniel Pan
parent 92be0754bd
commit 26e26ac22d
12 changed files with 361 additions and 115 deletions

View File

@@ -0,0 +1,14 @@
define([
'underscore',
'backbone',
'app/models/group-repo'
], function(_, Backbone, GroupRepo) {
'use strict';
var GroupRepoCollection = Backbone.Collection.extend({
model: GroupRepo,
url: app.pageOptions.groupReposUrl
});
return new GroupRepoCollection();
});

View File

@@ -0,0 +1,6 @@
define([
'app/routers/group'
], function(Router){
new Router();
Backbone.history.start();
});

View File

@@ -0,0 +1,22 @@
define([
'underscore',
'backbone'
], function(_, Backbone) {
'use strict';
var GroupRepo = Backbone.Model.extend({
defaults: {
id: "",
name: "",
desc: "",
mtime: "",
encrypted: false,
permission: "",
owner: gettext("Unknown")
}
});
return GroupRepo;
});

View File

@@ -0,0 +1,32 @@
/*global define*/
define([
'jquery',
'backbone',
'app/collections/group-repos',
'app/views/group'
], function($, Backbone, Repos, GroupView) {
"use strict";
var GroupRouter = Backbone.Router.extend({
routes: {
'libs/:id(/*path)': 'showDirents',
// Default
'*actions': 'defaultAction'
},
showDirents: function(id, path){
console.log("Repo route has been called.." + "id:" + id + " path:" + path);
new GroupView().showDirentList(id, path);
},
defaultAction: function(actions){
// We have no matching route, lets just log what the URL was
console.log('No route:', actions);
new GroupView().showRepoList();
}
});
return GroupRouter;
});

View File

@@ -0,0 +1,47 @@
define([
'jquery',
'underscore',
'backbone',
'text!' + app.config._tmplRoot + 'group-repos.html'
], function($, _, Backbone, reposTemplate) {
'use strict';
var GroupRepoView = Backbone.View.extend({
tagName: 'tr',
template: _.template(reposTemplate),
events: {
'mouseenter': 'showAction',
'mouseleave': 'hideAction',
'click .cancel-share': 'unshare'
},
initialize: function() {
console.log('init GroupRepoView');
Backbone.View.prototype.initialize.apply(this, arguments);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
showAction: function() {
this.$el.addClass('hl');
this.$el.find('.op-icon').removeClass('vh');
},
hideAction: function() {
this.$el.removeClass('hl');
this.$el.find('.op-icon').addClass('vh');
},
unshare: function() {
this.model.destroy();
}
});
return GroupRepoView;
});

View File

@@ -0,0 +1,143 @@
define([
'jquery',
'underscore',
'backbone',
'app/collections/group-repos',
'app/collections/dirents',
'app/views/group-repos',
'app/views/dirents'
], function($, _, Backbone, Repos, DirentCollection, GroupRepoView, DirentView) {
'use strict';
var GroupView = Backbone.View.extend({
el: '#main',
initialize: function() {
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
var token;
options.xhrFields = {
withCredentials: true
};
// token = $('meta[name="csrf-token"]').attr('content');
token = app.pageOptions.csrfToken;
if (token) {
return jqXHR.setRequestHeader('X-CSRF-Token', token);
}
});
this.$cont = this.$('#right-panel');
this.$tab = this.$('#tabs div:first-child');
this.$tabCont = this.$('#grp-repos');
this.$tableCont = this.$('#grp-repos table');
},
initializeRepos: function() {
this.listenTo(Repos, 'add', this.addOne);
this.listenTo(Repos, 'reset', this.addAll);
this.listenTo(Repos, 'sync', this.render);
},
initializeDirents: function() {
this.listenTo(this.dirents, 'add', this.addOneDirent);
this.listenTo(this.dirents, 'reset', this.addAllDirent);
// this.listenTo(this.dirents, 'sync', this.render);
this.listenTo(this.dirents, 'all', this.renderDirent);
},
addOne: function(repo) {
console.log('add repo: ' + repo);
var view = new GroupRepoView({model: repo});
this.$tableCont.append(view.render().el);
},
addAll: function() {
console.log('add all');
this.resetTable();
Repos.each(this.addOne, this);
},
addOneDirent: function(dirent) {
var view = new DirentView({model: dirent});
this.$tableCont.append(view.render().el);
},
addAllDirent: function() {
this.$tableCont.empty();
this.dirents.each(this.addOneDirent, this);
},
renderDirent: function(eventName) {
console.log('render dirents with event: ' + eventName);
if (this.dirents.length) {
this.$tabCont.show();
}
},
resetTable: function() {
console.log('rest table');
_.each($('#grp-repos table').find('tr'), function(el, idx) {
if (idx != 0) {
$(el).remove(); // remove table content except first row.
}
});
},
hideTable: function() {
this.$tableCont.hide();
},
showTable: function() {
this.$tableCont.show();
},
hideLoading: function() {
this.$cont.find('.loading').hide();
},
showLoading: function() {
this.$cont.find('.loading').show();
},
hideEmptyTips: function() {
this.$cont.find('.empty-tips').hide();
},
showEmptyTips: function() {
this.$cont.find('.empty-tips').show();
},
render: function(eventName) {
this.hideLoading();
if (Repos.length) {
this.hideEmptyTips();
this.showTable();
} else {
this.showEmptyTips();
}
},
showRepoList: function() {
this.initializeRepos();
Repos.fetch({reset: true});
// $('#my-own-repos table').append(new RepoView().render().el);
},
showDirentList: function(id, path) {
console.log('show repo page and hide repo list: ' + id + ' ' + path);
var path = path || '/';
this.dirents = new DirentCollection(id, path);
this.initializeDirents();
this.dirents.fetch({reset: true});
// this.dirent_list = new app.DirentListView({id: id, path: path});
// $('#my-own-repos table').children().remove();
// $('#my-own-repos table').append(this.dirent_list.render().el);
}
});
return GroupView;
});

4
media/scripts/group.js Normal file
View File

@@ -0,0 +1,4 @@
//Load common code that includes config, then load the app logic for this page.
require(['./common'], function (common) {
require(['app/main/group']);
});

View File

@@ -70,6 +70,8 @@ urlpatterns = patterns('',
url(r'^groups/$', Groups.as_view()),
url(r'^groups/(?P<group_id>\d+)/$', Groups.as_view()),
url(r'^groups/(?P<group_id>\d+)/members/$', GroupMembers.as_view()),
url(r'^groups/(?P<group_id>\d+)/repos/$', GroupRepos.as_view(), name="api2-grouprepos"),
url(r'^groups/(?P<group_id>\d+)/repos/(?P<repo_id>[-0-9a-f]{36})/$', GroupRepos.as_view()),
url(r'^html/events/$', EventsHtml.as_view()),
url(r'^html/more_events/$', AjaxEvents.as_view(), name="more_events"),

View File

@@ -2826,6 +2826,42 @@ class GroupMembers(APIView):
return HttpResponse(json.dumps({'success': True}), status=200, content_type=json_content_type)
class GroupRepos(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
def get(self, request, group_id, format=None):
username = request.user.username
if is_org_context(request):
org_id = request.user.org.org_id
repos = get_org_group_repos(org_id, group_id, username)
else:
repos = seaserv.get_group_repos(int(group_id), username)
repos_json = []
for r in repos:
repo = {
"id": r.id,
"name": r.name,
"desc": r.desc,
"mtime": r.latest_modify,
"encrypted": r.encrypted,
"permission": check_permission(r.id, username)
}
repos_json.append(repo)
return Response(repos_json)
class GroupRepo(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
def delete(self, request, group_id, repo_id, format=None):
assert False
def is_group_staff(group, user):
if user.is_anonymous():
return False

View File

@@ -15,9 +15,8 @@
<button id="repo-create" class="fright"><img src="{{ MEDIA_URL }}img/add.png" alt="" class="add vam" /><span class="vam">{% trans "New Library" %}</span></button>
{% endif %}
</div>
<div id="grp-repos" class="hide">
{% if repos %}
<table>
<div id="grp-repos">
<table style="display:none">
<tr>
<th width="4%"><!--icon--></th>
<th width="20%">{% trans "Name" %} <span id="grp-repo-list-name-down" class="icon-caret-up cspt"></span> <span id="grp-repo-list-name-up" class="icon-caret-down cspt hide"></span></th>
@@ -26,44 +25,15 @@
<th width="14%">{% trans "Shared By" %}</th>
<th width="13%">{% trans "Operations" %}</th>
</tr>
{% for repo in repos %}
<tr data-repo_name="{{repo.props.name}}" data-time="{% if repo.latest_modify %}{{ repo.latest_modify }}{% else %}0{% endif %}">
<td>
{% if repo.encrypted %}
<img src="{{MEDIA_URL}}img/sync-folder-encrypt-20.png" title="{% trans "Read-Write" %}" alt="" />
{% else%}
{% if repo.user_perm == 'rw' %}
<img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="" />
{% else %}
<img src="{{MEDIA_URL}}img/folder-no-write-20.png?t=1387267140" title="{% trans "Read-Only" %}" alt="" />
{% endif %}
{% endif %}
</td>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/">{{ repo.props.name }}</a></td>
<td>{{ repo.props.desc }}</td>
<td>
{% if repo.latest_modify %}
{{ repo.latest_modify|translate_seahub_time }}
{% else %}
--
{% endif %}
</td>
<td>{{ repo.owner|email2nickname }}</td>
<td data-id="{{ repo.props.id }}" data-owner="{{ repo.owner }}" data-name="{{ repo.props.name }}" data-perm="{{ repo.user_perm }}">
{% if is_staff or repo.share_from_me %}
<img src="{{MEDIA_URL}}img/rm.png" alt="" class="cancel-share op-icon vh" title="{% trans "Unshare" %}" />
{% endif %}
</td>
</tr>
{% endfor %}
<p class="loading">{% trans "Loading ..." %}</p>
</table>
{% else %}
<div class="empty-tips" style="margin-bottom:150px;">
<div class="empty-tips" style="margin-bottom:150px; display:none;">
<h2 class="alc">{% trans "No library is sharing 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>
{% endif %}
</div>
<div id="grp-repos-commits" class="hide">
@@ -135,48 +105,19 @@
{% endblock %}
{% block extra_script %}{{block.super}}
<script type="text/javascript">
$('.cancel-share').click(function() {
var btn_ct = $(this).parent(),
repo_id = btn_ct.data('id'),
repo_owner = btn_ct.attr('data-owner'),
repo_perm = btn_ct.attr('data-perm'),
repo_name = btn_ct.attr('data-name');
$(this).data('url', '{% url 'repo_remove_share' %}?repo_id=' + e(repo_id) + '&from=' + e(repo_owner) + '&gid={{ group.id }}' + '&permission=' + e(repo_perm)).attr('data-target', repo_name);
});
addConfirmTo($('.cancel-share'), {
'title': "{% trans "Unshare Library" %}",
'con': "{% trans "Are you sure you want to unshare %s ?" %}"
});
{% if user.permissions.can_add_repo %}
function repoCreateSuccessCallback() {
location.reload();
}
{% url 'create_group_repo' group.id as repo_create_url %}
{% with post_url=repo_create_url %}
{% include 'snippets/repo_create_js.html' %}
{% endwith %}
{% endif %}
{% if recent_commits %}
{% include 'snippets/list_commit_detail.html' %}
$('.lsch-encrypted').click(function() {
if ($(this).data('passwordset')) {
listCommitDetails($(this).data('url'), $(this).data('time'));
} else {
var form = $('#repo-decrypt-form');
form.find('input[name="repo_id"]').val($(this).data('repoid'));
form.find('.op-target').html($(this).data('reponame'));
form.data({'url':$(this).data('url'), 'time':$(this).data('time')}).modal({appendTo:'#main'});
$('#simplemodal-container').css({'width':'auto'});
$(window).resize();
}
{% block extra_script %}
<script>
app["pageOptions"] = {
groupId: {{ group.id }},
groupReposUrl: "{% url "api2-grouprepos" group.id %}",
isGroupStaff: (function() {
if ("{{ is_staff }}" == "True")
return true;
return false;
});
{% include 'snippets/repo_decrypt_js.html' %}
{% endif %}
{% include "snippets/sort_lib_js.html" %}
})(),
csrfToken: "{{csrf_token}}"
};
</script>
<script data-main="{{ MEDIA_URL }}scripts/group" src="{{ MEDIA_URL }}scripts/lib/require.js"></script>
{% endblock %}

View File

@@ -135,29 +135,6 @@
{% include 'footer.html' %}
</div><!-- wrapper -->
<!-- <script type="text/javascript" src="{{ MEDIA_URL }}js/jq.min.js?t=1398068110"></script> -->
<!-- <script type="text/javascript" src="{{ MEDIA_URL }}js/base.js?t=1404370380"></script> -->
<!-- <script type="text/javascript" src="{{ MEDIA_URL }}js/lib/underscore.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/lib/backbone.js"></script>
<script type="text/javascript">
app = window.app = {
config: {
mediaUrl: '{{ MEDIA_URL }}',
siteRoot: '{{ SITE_ROOT }}'
},
templates: {},
utils: {}
};
</script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/models.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/collections.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/utils.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/templates.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/views.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/app.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/routers.js"></script> -->
<script type="text/javascript">
app = window.app = {
config: {

View File

@@ -0,0 +1,22 @@
{% load i18n %}
<td>
<% if (encrypted) { %>
<img src="<%= app.config.mediaUrl %>img/sync-folder-encrypt-20.png" title="{% trans "Read-Write" %}" alt="" />
<% } else { %>
<% if (permission == 'rw') { %>
<img src="<%= app.config.mediaUrl %>img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write" %}" alt="" />
<% } else { %>
<img src="<%= app.config.mediaUrl %>img/folder-no-write-20.png?t=1387267140" title="{% trans "Read-Only" %}" alt="" />
<% } %>
<% } %>
</td>
<td><a href="#/libs/<%= id %>"><%- name %></a></td>
<td><%- desc %></td>
<td><%- mtime %></td>
<td><%- owner %></td>
<td>
<% if (app.pageOptions.isGroupStaff) { %>
<img src="<%= app.config.mediaUrl%>img/rm.png" alt="" class="cancel-share op-icon vh" title="{% trans "Unshare" %}" />
<% } %>
</td>