mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-16 07:08:55 +00:00
[deleted libs] list deleted libraries, and enable user to restore a library
This commit is contained in:
@@ -117,6 +117,7 @@
|
||||
.icon-eye-slash:before { content: "\f070"; }
|
||||
.icon-plus-square:before { content: "\f0fe"; }
|
||||
.icon-envelope:before { content: "\f0e0"; }
|
||||
.icon-ellipsis-vertical:before { content: "\f142"; }
|
||||
.fa-1x {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
@@ -1788,6 +1789,9 @@ button.sf-dropdown-toggle:focus {
|
||||
background:#fff;
|
||||
line-height:17px;
|
||||
}
|
||||
.more-op-btn-white {
|
||||
width:29px;
|
||||
}
|
||||
/* info-bar */
|
||||
#info-bar {
|
||||
color:#1f0600;
|
||||
|
@@ -154,6 +154,30 @@
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="deleted-repo-tmpl">
|
||||
<td>
|
||||
<img src="<%= icon_url %>" title="<%= icon_title %>" alt="<%= icon_title %>" width="24" />
|
||||
</td>
|
||||
<td><%- repo_name %></td>
|
||||
<td><span title="<%= time %>"><%= time_from_now %></span></td>
|
||||
<td>
|
||||
<a href="#" class="sf2-icon-reply sf2-x restore op-icon vh" title="{% trans "Restore" %}" aria-label="{% trans "Restore" %}"></a>
|
||||
</td>
|
||||
</script>
|
||||
<script type="text/template" id="deleted-repo-mobile-tmpl">
|
||||
<td>
|
||||
<img src="<%= icon_url %>" title="<%= icon_title %>" alt="<%= icon_title %>" width="24" />
|
||||
</td>
|
||||
<td>
|
||||
<span class="repo-name-span">
|
||||
<%- repo_name %><br />
|
||||
<span class="repo-meta-info" title="<%= time %>"><%= time_from_now %></span>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="sf2-icon-reply sf2-x restore op-icon" title="{% trans "Restore" %}" aria-label="{% trans "Restore" %}"></a>
|
||||
</td>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="group-repo-tmpl">
|
||||
<td>
|
||||
@@ -1260,13 +1284,13 @@
|
||||
|
||||
|
||||
<script type="text/template" id="my-repos-hd-tmpl">
|
||||
<tr>
|
||||
<th width="4%"><span class="sr-only">{% trans "Library Type" %}</span><!--icon--></th>
|
||||
<th width="42%"><a class="table-sort-op by-name" href="#">{% trans "Name" %} <span class="sort-icon icon-caret-down hide"></span></a></th>
|
||||
<th width="14%"><span class="sr-only">{% trans "Actions" %}</span></th>
|
||||
<th width="20%">{% trans "Size" %}</th>
|
||||
<th width="20%"><a class="table-sort-op by-time" href="#">{% trans "Last Update" %} <span class="sort-icon icon-caret-up"></span></a></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="4%"><span class="sr-only">{% trans "Library Type" %}</span><!--icon--></th>
|
||||
<th width="42%"><a class="table-sort-op by-name" href="#">{% trans "Name" %} <span class="sort-icon icon-caret-down hide"></span></a></th>
|
||||
<th width="14%"><span class="sr-only">{% trans "Actions" %}</span></th>
|
||||
<th width="20%">{% trans "Size" %}</th>
|
||||
<th width="20%"><a class="table-sort-op by-time" href="#">{% trans "Last Update" %} <span class="sort-icon icon-caret-up"></span></a></th>
|
||||
</tr>
|
||||
</script>
|
||||
<script type="text/template" id="my-repos-hd-mobile-tmpl">
|
||||
<tr>
|
||||
@@ -1278,6 +1302,23 @@
|
||||
<th width="4%"><span class="sr-only">{% trans "Actions" %}</span></th>
|
||||
</tr>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="my-deleted-repos-hd-tmpl">
|
||||
<tr>
|
||||
<th width="4%"><span class="sr-only">{% trans "Library Type" %}</span><!--icon--></th>
|
||||
<th width="52%">{% trans "Name" %}</th>
|
||||
<th width="30%">{% trans "Deleted Time" %}</th>
|
||||
<th width="14%"><span class="sr-only">{% trans "Actions" %}</span></th>
|
||||
</tr>
|
||||
</script>
|
||||
<script type="text/template" id="my-deleted-repos-hd-mobile-tmpl">
|
||||
<tr class="vh">
|
||||
<th width="4%"><span class="sr-only">{% trans "Library Type" %}</span><!--icon--></th>
|
||||
<th width="82%">{% trans "Name" %}{% trans "Deleted Time" %}</th>
|
||||
<th width="14%"><span class="sr-only">{% trans "Actions" %}</span></th>
|
||||
</tr>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="shared-repos-hd-tmpl">
|
||||
<tr>
|
||||
<th width="4%"><span class="sr-only">{% trans "Library Type" %}</span><!--icon--></th>
|
||||
|
@@ -9,9 +9,18 @@
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/template" id="my-own-repos-tmpl">
|
||||
<div class="hd ovhd">
|
||||
<div class="hd">
|
||||
<h3 class="fleft">{% trans "My Libraries" %}</h3>
|
||||
<button class="repo-create btn-white fright"><span aria-hidden="true" class="icon-plus-square add vam"></span><span class="vam">{% trans "New Library" %}</span></button>
|
||||
<div class="fright">
|
||||
<button class="repo-create btn-white"><span aria-hidden="true" class="icon-plus-square add vam"></span><span class="vam">{% trans "New Library" %}</span></button>
|
||||
|
||||
<div id="my-libs-more-op" class="sf-dropdown sf-dropdown-inline">
|
||||
<button class="sf-dropdown-toggle btn-white more-op-btn-white"><span class="icon-ellipsis-vertical"></span></button>
|
||||
<ul class="sf-dropdown-menu hide">
|
||||
<li><a href="#my-libs/deleted/">{% trans "Deleted Libraries" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="my-own-repos-table hide">
|
||||
<thead></thead>
|
||||
@@ -25,6 +34,24 @@
|
||||
<p class="error error-tip hide"></p>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="my-deleted-repos-tmpl">
|
||||
<p class="path-bar">
|
||||
<a href="#my-libs/" class="normal">{% trans "My Libraries" %}</a>
|
||||
<span class="path-split">/</span>
|
||||
<span>{% trans "Deleted" %}</span>
|
||||
</p>
|
||||
<table class="my-deleted-repos-table hide">
|
||||
<thead></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<div class="empty-tips hide">
|
||||
<h2 class="alc">{% trans "No deleted library." %}</h2>
|
||||
</div>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<p class="error error-tip hide"></p>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/template" id="repos-shared-to-me-tmpl">
|
||||
<h3 class="hd">{% trans "Shared with me" %}</h3>
|
||||
<table class="hide">
|
||||
|
18
static/scripts/app/collections/deleted-repos.js
Normal file
18
static/scripts/app/collections/deleted-repos.js
Normal file
@@ -0,0 +1,18 @@
|
||||
define([
|
||||
'underscore',
|
||||
'backbone',
|
||||
'common',
|
||||
'app/models/deleted-repo'
|
||||
], function(_, Backbone, Common, DeletedRepo) {
|
||||
'use strict';
|
||||
|
||||
var collection = Backbone.Collection.extend({
|
||||
model: DeletedRepo,
|
||||
|
||||
url: function () {
|
||||
return Common.getUrl({name: 'deleted_repos'});
|
||||
}
|
||||
});
|
||||
|
||||
return collection;
|
||||
});
|
30
static/scripts/app/models/deleted-repo.js
Normal file
30
static/scripts/app/models/deleted-repo.js
Normal file
@@ -0,0 +1,30 @@
|
||||
define([
|
||||
'underscore',
|
||||
'backbone',
|
||||
'common'
|
||||
], function(_, Backbone, Common) {
|
||||
'use strict';
|
||||
|
||||
var model = Backbone.Model.extend({
|
||||
|
||||
getIconUrl: function(size) {
|
||||
var is_encrypted = this.get('encrypted');
|
||||
var is_readonly = false;
|
||||
return Common.getLibIconUrl(is_encrypted, is_readonly, size);
|
||||
},
|
||||
|
||||
getIconTitle: function() {
|
||||
var icon_title = '';
|
||||
if (this.get('encrypted')) {
|
||||
icon_title = gettext("Encrypted library");
|
||||
} else {
|
||||
icon_title = gettext("Read-Write library");
|
||||
}
|
||||
|
||||
return icon_title;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return model;
|
||||
});
|
@@ -6,6 +6,7 @@ define([
|
||||
'js.cookie',
|
||||
'app/views/side-nav',
|
||||
'app/views/myhome-repos',
|
||||
'app/views/my-deleted-repos',
|
||||
'app/views/myhome-shared-repos',
|
||||
'app/views/groups',
|
||||
'app/views/group',
|
||||
@@ -22,8 +23,8 @@ define([
|
||||
'app/views/notifications',
|
||||
'app/views/account'
|
||||
], function($, Backbone, Common, Cookies, SideNavView, MyReposView,
|
||||
SharedReposView, GroupsView, GroupView, OrgView, DirView,
|
||||
StarredFileView, ActivitiesView, DevicesView, InvitationsView,
|
||||
MyDeletedReposView, SharedReposView, GroupsView, GroupView, OrgView,
|
||||
DirView, StarredFileView, ActivitiesView, DevicesView, InvitationsView,
|
||||
ShareAdminReposView, ShareAdminFoldersView, ShareAdminShareLinksView,
|
||||
ShareAdminUploadLinksView, NotificationsView, AccountView) {
|
||||
"use strict";
|
||||
@@ -32,6 +33,7 @@ define([
|
||||
routes: {
|
||||
'': 'showRepos',
|
||||
'my-libs/': 'showMyRepos',
|
||||
'my-libs/deleted/': 'showMyDeletedRepos',
|
||||
'my-libs/lib/:repo_id(/*path)': 'showMyRepoDir',
|
||||
'shared-libs/': 'showSharedRepos',
|
||||
'shared-libs/lib/:repo_id(/*path)': 'showSharedRepoDir',
|
||||
@@ -67,6 +69,7 @@ define([
|
||||
this.dirView = new DirView();
|
||||
|
||||
this.myReposView = new MyReposView();
|
||||
this.myDeletedReposView = new MyDeletedReposView();
|
||||
this.sharedReposView = new SharedReposView();
|
||||
this.orgView = new OrgView();
|
||||
this.groupView = new GroupView();
|
||||
@@ -148,6 +151,12 @@ define([
|
||||
this.sideNavView.setCurTab('mine');
|
||||
},
|
||||
|
||||
showMyDeletedRepos: function() {
|
||||
this.switchCurrentView(this.myDeletedReposView);
|
||||
this.myDeletedReposView.show();
|
||||
this.sideNavView.setCurTab('mine');
|
||||
},
|
||||
|
||||
showSharedRepos: function() {
|
||||
this.switchCurrentView(this.sharedReposView);
|
||||
this.sharedReposView.show();
|
||||
|
72
static/scripts/app/views/deleted-repo.js
Normal file
72
static/scripts/app/views/deleted-repo.js
Normal file
@@ -0,0 +1,72 @@
|
||||
define([
|
||||
'jquery',
|
||||
'underscore',
|
||||
'backbone',
|
||||
'common',
|
||||
'moment',
|
||||
'app/views/widgets/hl-item-view'
|
||||
], function($, _, Backbone, Common, Moment, HLItemView) {
|
||||
'use strict';
|
||||
|
||||
var RepoView = HLItemView.extend({
|
||||
tagName: 'tr',
|
||||
|
||||
template: _.template($('#deleted-repo-tmpl').html()),
|
||||
mobileTemplate: _.template($('#deleted-repo-mobile-tmpl').html()),
|
||||
|
||||
events: {
|
||||
'click .restore': 'restoreRepo'
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
HLItemView.prototype.initialize.call(this);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var obj = this.model.toJSON();
|
||||
var icon_size = Common.isHiDPI() ? 96 : 24;
|
||||
var icon_url = this.model.getIconUrl(icon_size);
|
||||
var m = Moment(this.model.get('del_time'));
|
||||
var tmpl;
|
||||
if ($(window).width() >= 768) {
|
||||
tmpl = this.template;
|
||||
} else {
|
||||
tmpl = this.mobileTemplate;
|
||||
}
|
||||
_.extend(obj, {
|
||||
'icon_url': icon_url,
|
||||
'icon_title': this.model.getIconTitle(),
|
||||
'time': m.format('LLLL'),
|
||||
'time_from_now': Common.getRelativeTimeStr(m)
|
||||
});
|
||||
this.$el.html(tmpl(obj));
|
||||
return this;
|
||||
},
|
||||
|
||||
restoreRepo: function() {
|
||||
var _this = this;
|
||||
$.ajax({
|
||||
url: Common.getUrl({'name': 'deleted_repos'}),
|
||||
type: 'POST',
|
||||
data: {
|
||||
'repo_id': this.model.get('repo_id')
|
||||
},
|
||||
beforeSend: Common.prepareCSRFToken,
|
||||
success: function() {
|
||||
_this.remove();
|
||||
|
||||
var msg = gettext("Successfully restored library {placeholder}").replace('{placeholder}', _this.model.get('repo_name'));
|
||||
Common.feedback(msg, 'success');
|
||||
},
|
||||
error: function(xhr) {
|
||||
Common.ajaxErrorHandler(xhr);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return RepoView;
|
||||
});
|
105
static/scripts/app/views/my-deleted-repos.js
Normal file
105
static/scripts/app/views/my-deleted-repos.js
Normal file
@@ -0,0 +1,105 @@
|
||||
define([
|
||||
'jquery',
|
||||
'underscore',
|
||||
'backbone',
|
||||
'common',
|
||||
'app/collections/deleted-repos',
|
||||
'app/views/deleted-repo'
|
||||
], function($, _, Backbone, Common, RepoCollection, RepoView) {
|
||||
'use strict';
|
||||
|
||||
var ReposView = Backbone.View.extend({
|
||||
id: "my-deleted-repos",
|
||||
|
||||
template: _.template($('#my-deleted-repos-tmpl').html()),
|
||||
reposHdTemplate: _.template($('#my-deleted-repos-hd-tmpl').html()),
|
||||
mobileReposHdTemplate: _.template($('#my-deleted-repos-hd-mobile-tmpl').html()),
|
||||
|
||||
events: {
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.repos = new RepoCollection();
|
||||
this.listenTo(this.repos, 'add', this.addOne);
|
||||
this.listenTo(this.repos, 'reset', this.reset);
|
||||
|
||||
this.render();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template());
|
||||
this.$table = this.$('table');
|
||||
this.$tableHead = $('thead', this.$table);
|
||||
this.$tableBody = $('tbody', this.$table);
|
||||
this.$loadingTip = this.$('.loading-tip');
|
||||
this.$emptyTip = this.$('.empty-tips');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
addOne: function(repo, collection, options) {
|
||||
var view = new RepoView({model: repo});
|
||||
this.$tableBody.append(view.render().el);
|
||||
},
|
||||
|
||||
renderReposHd: function() {
|
||||
var tmpl = $(window).width() >= 768 ? this.reposHdTemplate : this.mobileReposHdTemplate;
|
||||
this.$tableHead.html(tmpl());
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this.$('.error').hide();
|
||||
this.$loadingTip.hide();
|
||||
if (this.repos.length) {
|
||||
this.$emptyTip.hide();
|
||||
this.renderReposHd();
|
||||
this.$tableBody.empty();
|
||||
|
||||
this.repos.each(this.addOne, this);
|
||||
this.$table.show();
|
||||
} else {
|
||||
this.$table.hide();
|
||||
this.$emptyTip.show();
|
||||
}
|
||||
},
|
||||
|
||||
showRepos: function() {
|
||||
this.$table.hide();
|
||||
this.$loadingTip.show();
|
||||
var _this = this;
|
||||
this.repos.fetch({
|
||||
cache: false,
|
||||
reset: true,
|
||||
success: function (collection, response, opts) {
|
||||
},
|
||||
error: function (collection, response, opts) {
|
||||
_this.$loadingTip.hide();
|
||||
var $error = _this.$('.error');
|
||||
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.');
|
||||
}
|
||||
$error.html(err_msg).show();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
show: function() {
|
||||
$("#right-panel").html(this.$el);
|
||||
this.showRepos();
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.$el.detach();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return ReposView;
|
||||
});
|
@@ -6,9 +6,10 @@ define([
|
||||
'app/collections/repos',
|
||||
'app/views/repo',
|
||||
'app/views/add-repo',
|
||||
'app/views/repo-details'
|
||||
'app/views/repo-details',
|
||||
'app/views/widgets/dropdown'
|
||||
], function($, _, Backbone, Common, RepoCollection, RepoView, AddRepoView,
|
||||
RepoDetailsView) {
|
||||
RepoDetailsView, DropdownView) {
|
||||
'use strict';
|
||||
|
||||
var ReposView = Backbone.View.extend({
|
||||
@@ -21,7 +22,8 @@ define([
|
||||
events: {
|
||||
'click .repo-create': 'createRepo',
|
||||
'click .by-name': 'sortByName',
|
||||
'click .by-time': 'sortByTime'
|
||||
'click .by-time': 'sortByTime',
|
||||
'click #my-libs-more-op a': 'closeDropdown'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
@@ -32,6 +34,11 @@ define([
|
||||
this.repoDetailsView = new RepoDetailsView();
|
||||
|
||||
this.render();
|
||||
|
||||
this.more_op_dropdown = new DropdownView({
|
||||
el: this.$("#my-libs-more-op"),
|
||||
right: 0
|
||||
})
|
||||
},
|
||||
|
||||
addOne: function(repo, collection, options) {
|
||||
@@ -149,6 +156,10 @@ define([
|
||||
this.repos.comparator = null;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
closeDropdown: function() {
|
||||
this.more_op_dropdown.hide();
|
||||
}
|
||||
|
||||
});
|
||||
|
@@ -98,6 +98,7 @@ define([
|
||||
|
||||
// Repos
|
||||
case 'repos': return siteRoot + 'api2/repos/';
|
||||
case 'deleted_repos': return siteRoot + 'api/v2.1/deleted-repos/';
|
||||
case 'pub_repos': return siteRoot + 'api2/repos/public/';
|
||||
case 'unenc_rw_repos': return siteRoot + 'ajax/unenc-rw-repos/';
|
||||
case 'api_v2.1_repo_set_password': return siteRoot + 'api/v2.1/repos/' + options.repo_id + '/set-password/';
|
||||
|
Reference in New Issue
Block a user