diff --git a/media/css/seahub.css b/media/css/seahub.css index bc7aba6b57..8fde075c7c 100644 --- a/media/css/seahub.css +++ b/media/css/seahub.css @@ -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; +} diff --git a/seahub/api2/endpoints/wikis.py b/seahub/api2/endpoints/wikis.py index def04ee4f9..3416cd710c 100644 --- a/seahub/api2/endpoints/wikis.py +++ b/seahub/api2/endpoints/wikis.py @@ -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 diff --git a/seahub/templates/wiki/wiki_list.html b/seahub/templates/wiki/wiki_list.html index 552bb37d6b..a8538c51cb 100644 --- a/seahub/templates/wiki/wiki_list.html +++ b/seahub/templates/wiki/wiki_list.html @@ -9,7 +9,8 @@ {% block right_panel %}

{% trans "Wikis" %}

- +
+
@@ -37,6 +38,26 @@ + {% csrf_token %} +

{% trans "Create Wiki from a library" %}

+ +
+
+ + + + + + + + + +
{% trans "Name" %}{% trans "Last Update" %}
+ +

+ + + + + {% 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(); + {% endblock %}