mirror of
https://github.com/haiwen/seahub.git
synced 2025-10-21 10:51:17 +00:00
Add wiki use lib (#2297)
This commit is contained in:
committed by
Daniel Pan
parent
6d8bfb93f6
commit
5d1fd88da3
@@ -3363,7 +3363,7 @@ button.sf-dropdown-toggle:focus {
|
||||
color:#333;
|
||||
font-weight:normal;
|
||||
}
|
||||
#new-wiki {
|
||||
.add-wiki-container {
|
||||
margin-left:auto;
|
||||
}
|
||||
.wiki-page-ops {
|
||||
@@ -4364,9 +4364,13 @@ img.thumbnail {
|
||||
.wiki-hl {background-color: #f8f8f8;}
|
||||
.wiki-vs {visibility: visible;}
|
||||
.wiki-dropdown-menu {
|
||||
margin-left: -80px;
|
||||
margin-left: -5rem;
|
||||
}
|
||||
.wiki-list input {
|
||||
width: 200px;
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
#new-wiki-by-existing-form .repo-container {
|
||||
max-height: 20rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ from seahub.api2.utils import api_error
|
||||
from seahub.wiki.models import Wiki, DuplicateWikiNameError
|
||||
from seahub.wiki.utils import is_valid_wiki_name, slugfy_wiki_name
|
||||
from seahub.utils import is_org_context, get_user_repos
|
||||
from seahub.views import check_folder_permission
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -76,41 +77,81 @@ class WikisView(APIView):
|
||||
def post(self, request, format=None):
|
||||
"""Add a new wiki.
|
||||
"""
|
||||
result = {}
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
use_exist_repo = request.POST.get('use_exist_repo', '')
|
||||
if not use_exist_repo:
|
||||
msg = 'Use exist repo is invalid'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
|
||||
name = request.POST.get('name', '')
|
||||
if not name:
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, _('Name is required.'))
|
||||
msg = 'Name is invalid'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
|
||||
if not is_valid_wiki_name(name):
|
||||
msg = _('Name can only contain letters, numbers, blank, hyphen or underscore.')
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
|
||||
username = request.user.username
|
||||
|
||||
org_id = -1
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
|
||||
username = request.user.username
|
||||
try:
|
||||
wiki = Wiki.objects.add(name, username, org_id=org_id)
|
||||
except DuplicateWikiNameError:
|
||||
msg = _('%s is taken by others, please try another name.') % name
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
except IntegrityError:
|
||||
msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)
|
||||
if use_exist_repo == 'false':
|
||||
try:
|
||||
wiki = Wiki.objects.add(name, username, org_id=org_id)
|
||||
except DuplicateWikiNameError:
|
||||
msg = _('%s is taken by others, please try another name.') % name
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
except IntegrityError:
|
||||
msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)
|
||||
|
||||
# create home page
|
||||
page_name = "home.md"
|
||||
try:
|
||||
seafile_api.post_empty_file(wiki.repo_id, '/',
|
||||
page_name, request.user.username)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)
|
||||
# create home page
|
||||
page_name = "home.md"
|
||||
try:
|
||||
seafile_api.post_empty_file(wiki.repo_id, '/',
|
||||
page_name, request.user.username)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)
|
||||
|
||||
return Response(wiki.to_dict())
|
||||
return Response(wiki.to_dict())
|
||||
|
||||
if use_exist_repo == 'true':
|
||||
repo_id = request.POST.get('repo_id', '')
|
||||
if not repo_id:
|
||||
msg = 'Repo id is invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
|
||||
if check_folder_permission(request, repo_id, '/') != 'rw':
|
||||
error_msg = _('Permission denied.')
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
try:
|
||||
wiki = Wiki.objects.add(wiki_name=repo.repo_name, username=username,
|
||||
repo_id=repo.repo_id, org_id=org_id)
|
||||
except DuplicateWikiNameError:
|
||||
msg = _('%s is taken by others, please try another name.') % repo.repo_name
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
except IntegrityError:
|
||||
msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)
|
||||
|
||||
# create home page if not exist
|
||||
page_name = "home.md"
|
||||
if not seafile_api.get_file_id_by_path(repo_id, "/" + page_name):
|
||||
try:
|
||||
seafile_api.post_empty_file(repo_id, '/', page_name, username)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)
|
||||
|
||||
|
||||
return Response(wiki.to_dict())
|
||||
|
||||
|
||||
class WikiView(APIView):
|
||||
@@ -190,7 +231,6 @@ class WikiView(APIView):
|
||||
msg = _('%s is taken by others, please try another name.') % wiki_name
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, msg)
|
||||
|
||||
|
||||
if edit_repo(wiki.repo_id, wiki_name, '', username):
|
||||
wiki.slug = wiki_slug
|
||||
wiki.name = wiki_name
|
||||
|
@@ -9,7 +9,8 @@
|
||||
{% block right_panel %}
|
||||
<div class="hd d-flex">
|
||||
<h3>{% trans "Wikis" %}</h3>
|
||||
<button class="btn-white" id="new-wiki">{% trans "New Wiki" %}</button>
|
||||
<div class="add-wiki-container">
|
||||
</div>
|
||||
</div>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<table class="wiki-list hide">
|
||||
@@ -37,6 +38,26 @@
|
||||
<button type="submit" class="submit">{% trans "Submit" %}</button>
|
||||
</form>
|
||||
|
||||
<form id="new-wiki-by-existing-form" action="" method="post" class="hide">{% csrf_token %}
|
||||
<h3 id="dialogTitle">{% trans "Create Wiki from a library" %}</h3>
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<div class="repo-container">
|
||||
<table class="repo-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="3%"><!--select--></th>
|
||||
<th width="4%"><!--icon--></th>
|
||||
<th width="38%">{% trans "Name" %}</th>
|
||||
<th width="25%">{% trans "Last Update" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="error hide"></p>
|
||||
<button type="submit" class="submit">{% trans "Submit" %}</button>
|
||||
</form>
|
||||
|
||||
<script type="text/script" id="wiki-tmpl">
|
||||
<tr data-slug="<%= slug %>">
|
||||
<td>
|
||||
@@ -64,6 +85,32 @@
|
||||
<button type="button" class="cancel sf2-icon-x2 vam" title="{% trans "Cancel" %}"></button>
|
||||
</form>
|
||||
</script>
|
||||
<script type="text/template" id="wiki-add-wiki-tmpl">
|
||||
<button class="btn-white sf-dropdown-toggle hidden-sm-down add-wiki"><span aria-hidden="true" class="icon-plus-square add vam"></span><span class="vam">{% trans "Add Wiki"%}</span></button>
|
||||
<span aria-label="{% trans "Add Wiki" %}" class="hidden-md-up sf-dropdown-toggle sf2-icon-plus2 mobile-icon"></span>
|
||||
<ul class="sf-dropdown-menu wiki-dropdown-menu hide">
|
||||
<li><a class="op new-wiki-by-build" href="#">{% trans "New Wiki" %}</a></li>
|
||||
<li><a class="op new-wiki-by-own" href="#">{% trans "Choose a library as Wiki" %}</a></li>
|
||||
</ul>
|
||||
</script>
|
||||
<script type="text/template" id="wiki-choose-wiki-tmpl">
|
||||
<% var repos = obj %>
|
||||
<% for (var i = 0; i< repos.length; i++) {%>
|
||||
<% var repo = repos[i] %>
|
||||
<tr>
|
||||
<td><input type="radio" name="repo" class="vam" value="<%= repo.id%>"/></td>
|
||||
<td>
|
||||
<% if (repo.encrypted) { %>
|
||||
<img src="{{ MEDIA_URL }}img/lib/48/lib-encrypted.png" width="24" />
|
||||
<% } else { %>
|
||||
<img src="{{ MEDIA_URL }}img/lib/48/lib.png" width="24" />
|
||||
<% } %>
|
||||
</td>
|
||||
<td class="repo-name"><%= repo.name %></td>
|
||||
<td><%= repo.mtime_relative %></td>
|
||||
</tr>
|
||||
<% }%>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}{{block.super}}
|
||||
@@ -77,7 +124,7 @@ $.ajax({
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var list = data.data;
|
||||
var $tbody = $('tbody');
|
||||
var $tbody = $('.wiki-list tbody');
|
||||
if (list.length) {
|
||||
$(list).each(function(index, item) {
|
||||
$tbody.append(wiki.render(item));
|
||||
@@ -105,67 +152,6 @@ $.ajax({
|
||||
}
|
||||
});
|
||||
|
||||
// create new wiki
|
||||
$('#new-wiki').on('click', function() {
|
||||
$('#new-wiki-form').modal();
|
||||
$('#simplemodal-container').css({'width':'auto', 'height':'auto'});
|
||||
});
|
||||
|
||||
$('#new-wiki-form').on('submit', function () {
|
||||
var $form = $(this),
|
||||
$error = $('.error', $form),
|
||||
name = $('[name="name"]', $form).val();
|
||||
var $table = $('table'),
|
||||
$tbody = $('tbody'),
|
||||
$emptyTips = $('.empty-tips');
|
||||
|
||||
if (!$.trim(name)) {
|
||||
$error.html("{% trans "Name is required." %}").show();
|
||||
return false;
|
||||
}
|
||||
|
||||
var $submitBtn = $('[type="submit"]', $form);
|
||||
disable($submitBtn);
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'api-v2.1-wikis' %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'name': name,
|
||||
},
|
||||
success: function(data) {
|
||||
$.modal.close();
|
||||
var $wiki = wiki.render(data);
|
||||
if ($emptyTips.is(':visible')) {
|
||||
$tbody.append($wiki);
|
||||
$emptyTips.hide();
|
||||
$table.show();
|
||||
} else {
|
||||
$tbody.prepend($wiki);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
var error_msg;
|
||||
if (xhr.responseText) {
|
||||
try {
|
||||
error_msg = JSON.parse(xhr.responseText).error_msg;
|
||||
} catch(e) {
|
||||
error_msg = "{% trans "Error" %}";
|
||||
}
|
||||
} else {
|
||||
error_msg = "{% trans "Please check the network." %}";
|
||||
}
|
||||
$error.html(error_msg).show();
|
||||
enable($submitBtn);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
var wiki = {
|
||||
|
||||
init: function() {
|
||||
@@ -436,5 +422,176 @@ var wikiListController = {
|
||||
|
||||
wikiListController.init();
|
||||
|
||||
var NewWikiController = {
|
||||
el: $('.add-wiki-container'),
|
||||
chooseEl: $('#new-wiki-by-existing-form tbody'),
|
||||
|
||||
addWikiTmpl: _.template($('#wiki-add-wiki-tmpl').html()),
|
||||
chooseWikiTmpl: _.template($('#wiki-choose-wiki-tmpl').html()),
|
||||
|
||||
init: function() {
|
||||
var _this = this;
|
||||
this.el.append(this.addWikiTmpl);
|
||||
|
||||
$('.add-wiki').on('click', $.proxy(_this.showWikiMenu, _this));
|
||||
|
||||
$('.new-wiki-by-build').on('click', $.proxy(_this.clickToNewWiki, _this));
|
||||
$('.new-wiki-by-own').on('click', $.proxy(_this.clickToNewWikiByOwnlib, _this));
|
||||
|
||||
$('#new-wiki-form').on('submit', $.proxy(_this.handlerDriectNewWikiEvent, _this));
|
||||
$('#new-wiki-by-existing-form').on('submit', $.proxy(_this.handlerDependentNewWikiEvent, _this));
|
||||
|
||||
$(document).on("click", function(event) {
|
||||
var view = _this.newWikiMenu;
|
||||
var target = event.target || event.srcElement;
|
||||
|
||||
if (!view) {
|
||||
return true;
|
||||
}
|
||||
if (!view.is(target) &&
|
||||
!view.find('*').is(target)) {
|
||||
_this.hideWikiMenu();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
clickToNewWiki: function() {
|
||||
$('#new-wiki-form').modal();
|
||||
$('#simplemodal-container').css({'width':'auto', 'height':'auto'})
|
||||
},
|
||||
|
||||
clickToNewWikiByOwnlib: function(event) {
|
||||
var _this = this;
|
||||
$.ajax({
|
||||
url: "/api2/repos/?type=mine",
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if (data && data.length) {
|
||||
_this.chooseEl.append($(_this.chooseWikiTmpl(data)));
|
||||
$('#new-wiki-by-existing-form').modal();
|
||||
$('#simplemodal-container').css({'width':'auto', 'height':'auto'})
|
||||
} else {
|
||||
_this.chooseEl.html("{% trans "No existing library to choose." %}");
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
var error_msg;
|
||||
if (xhr.responseText) {
|
||||
try {
|
||||
error_msg = JSON.parse(xhr.responseText).error_msg;
|
||||
} catch(e) {
|
||||
error_msg = "{% trans "Error" %}";
|
||||
}
|
||||
} else {
|
||||
error_msg = "{% trans "Please check the network." %}";
|
||||
}
|
||||
_this.chooseEl.html(error_msg);
|
||||
},
|
||||
complete: function() {
|
||||
$('#new-wiki-by-existing-form .loading-tip').hide();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handlerDriectNewWikiEvent(event) {
|
||||
var $form = $(event.target);
|
||||
var name = $('[name="name"]', $form).val();
|
||||
var params = {
|
||||
use_exist_repo: false,
|
||||
repo_id: '',
|
||||
name: name
|
||||
}
|
||||
this.updateWikiList($form, params);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
handlerDependentNewWikiEvent: function(event) {
|
||||
var $form = $(event.target);
|
||||
var radio = $("input:radio:checked", $form);
|
||||
var repo_id = $("input:radio:checked", $form).val();
|
||||
var name = radio.closest('tr').find(".repo-name").text();
|
||||
var params = {
|
||||
use_exist_repo: true,
|
||||
repo_id: repo_id,
|
||||
name: name,
|
||||
}
|
||||
this.updateWikiList($form,params);
|
||||
return false;
|
||||
},
|
||||
|
||||
updateWikiList: function($container, ajaxData){
|
||||
var $form = $container,
|
||||
$error = $('.error', $form);
|
||||
var $table = $('.wiki-list'),
|
||||
$tbody = $('tbody', $table),
|
||||
$emptyTips = $('.empty-tips');
|
||||
|
||||
if (!$.trim(ajaxData.name)) {
|
||||
$error.html("{% trans "Name is required." %}").show();
|
||||
return false;
|
||||
}
|
||||
|
||||
var $submitBtn = $('[type="submit"]', $form);
|
||||
disable($submitBtn);
|
||||
|
||||
$.ajax({
|
||||
url: '{% url 'api-v2.1-wikis' %}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: ajaxData,
|
||||
success: function(data) {
|
||||
$.modal.close();
|
||||
var $wiki = wiki.render(data);
|
||||
if ($emptyTips.is(':visible')) {
|
||||
$tbody.append($wiki);
|
||||
$emptyTips.hide();
|
||||
$table.show();
|
||||
} else {
|
||||
$tbody.prepend($wiki);
|
||||
}
|
||||
},
|
||||
error: function(xhr) {
|
||||
var error_msg;
|
||||
if (xhr.responseText) {
|
||||
try {
|
||||
error_msg = JSON.parse(xhr.responseText).error_msg;
|
||||
} catch(e) {
|
||||
error_msg = "{% trans "Error" %}";
|
||||
}
|
||||
} else {
|
||||
error_msg = "{% trans "Please check the network." %}";
|
||||
}
|
||||
$error.html(error_msg).show();
|
||||
enable($submitBtn);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
hideWikiMenu: function() {
|
||||
this.newWikiMenu.hide();
|
||||
this.newWikiMenu = null;
|
||||
},
|
||||
|
||||
showWikiMenu: function(event) {
|
||||
var container = $(event.target).closest('.add-wiki-container');
|
||||
var newWikiMenu = container.find('.sf-dropdown-menu');
|
||||
if (this.newWikiMenu) {
|
||||
this.newWikiMenu.hide();
|
||||
this.newWikiMenu = null;
|
||||
return false;
|
||||
}
|
||||
newWikiMenu.show();
|
||||
this.newWikiMenu = newWikiMenu;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NewWikiController.init();
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user