Trash, restore and delete articles from edit page
authorAlexander Ebert <ebert@woltlab.com>
Tue, 21 Mar 2017 12:19:00 +0000 (13:19 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 21 Mar 2017 12:19:00 +0000 (13:19 +0100)
See #2209

wcfsetup/install/files/acp/templates/articleAdd.tpl
wcfsetup/install/files/acp/templates/articleList.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Article/InlineEditor.js
wcfsetup/install/files/lib/data/article/ArticleAction.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index ce6bcffd30ef135f0a546c33129080b28551185a..6f4cfd14e8bab16b63f915e731c90d3b4f0db40f 100644 (file)
@@ -19,8 +19,9 @@
 {/if}
 
 <script data-relocate="true">
-       require(['Language', 'WoltLabSuite/Core/Ui/User/Search/Input'], function(Language, UiUserSearchInput) {
+       require(['Language', 'WoltLabSuite/Core/Ui/User/Search/Input', 'WoltLabSuite/Core/Acp/Ui/Article/InlineEditor'], function(Language, UiUserSearchInput, AcpUiArticleInlineEditor) {
                Language.addObject({
+                       'wcf.message.status.deleted': '{lang}wcf.message.status.deleted{/lang}',
                        'wcf.page.search': '{lang}wcf.page.search{/lang}',
                        'wcf.page.search.error.tooShort': '{lang}wcf.page.search.error.tooShort{/lang}',
                        'wcf.page.search.error.noResults': '{lang}wcf.page.search.error.noResults{/lang}',
@@ -29,6 +30,7 @@
                });
                
                new UiUserSearchInput(elBySel('input[name="username"]'));
+               {if $action == 'edit'}new AcpUiArticleInlineEditor({@$article->articleID});{/if}
        });
 </script>
 
        <nav class="contentHeaderNavigation">
                <ul>
                        {if $action == 'edit'}
+                               {if $article->canDelete()}
+                                       <li><a href="#" class="button jsButtonRestore" data-confirm-message-html="{lang __encode=true isArticleEdit=true}wcf.acp.article.restore.confirmMessage{/lang}"{if !$article->isDeleted} style="display: none"{/if}><span class="icon icon16 fa-refresh"></span> <span>{lang}wcf.global.button.restore{/lang}</span></a></li>
+                                       <li><a href="#" class="button jsButtonDelete" data-confirm-message-html="{lang __encode=true isArticleEdit=true}wcf.acp.article.delete.confirmMessage{/lang}"{if !$article->isDeleted} style="display: none"{/if}><span class="icon icon16 fa-times"></span> <span>{lang}wcf.global.button.delete{/lang}</span></a></li>
+                                       <li><a href="#" class="button jsButtonTrash" data-confirm-message-html="{lang __encode=true isArticleEdit=true}wcf.acp.article.trash.confirmMessage{/lang}"{if $article->isDeleted} style="display: none"{/if}><span class="icon icon16 fa-times"></span> <span>{lang}wcf.global.button.trash{/lang}</span></a></li>
+                               {/if}
                                <li><a href="{$article->getLink()}" class="button"><span class="icon icon16 fa-search"></span> <span>{lang}wcf.acp.article.button.viewArticle{/lang}</span></a></li>
                        {/if}
                        <li><a href="{link controller='ArticleList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.menu.link.article.list{/lang}</span></a></li>
@@ -68,6 +75,8 @@
        <p class="success">{lang}wcf.global.success.{$action}{/lang}</p>
 {/if}
 
+{if $action == 'edit'}<p class="info jsArticleNoticeTrash"{if !$article->isDeleted} style="display: none;"{/if}>{lang}wcf.acp.article.trash.notice{/lang}</p>{/if}
+
 <form method="post" action="{if $action == 'add'}{link controller='ArticleAdd'}{/link}{else}{link controller='ArticleEdit' id=$articleID}{/link}{/if}">
        <div class="section">
                <dl{if $errorField == 'categoryID'} class="formError"{/if}>
index 56ad231587fdf4013148bff4b90a244f391a9c30..74d4bd24df476400435aa8ec5ef19ac341ca72e3 100644 (file)
@@ -7,7 +7,7 @@
                });
                
                new UiUserSearchInput(elBySel('input[name="username"]'));
-               new AcpUiArticleInlineEditor();
+               new AcpUiArticleInlineEditor(0);
        });
 </script>
 
index e61d3ad38e4eb1cd51dc6c47883709c617c13aa7..51683027e1d7860453c178fb7ef432793a4ea9cd 100644 (file)
@@ -11,26 +11,41 @@ define(['Ajax', 'Dictionary', 'Language', 'Ui/Confirmation', 'Ui/Notification'],
        
        var _articles = new Dictionary();
        
-       /**     
+       /**
         * @constructor
         */
-       function AcpUiArticleInlineEditor() { this.init(); }
+       function AcpUiArticleInlineEditor(objectId) { this.init(objectId); }
        AcpUiArticleInlineEditor.prototype = {
                /**
                 * Initializes the ACP inline editor for articles.
+                * 
+                * @param       {int}   objectId        article id, equals 0 on the article list, but is non-zero when editing a single article
                 */
-               init: function () {
-                       elBySelAll('.jsArticleRow', undefined, this._initArticle.bind(this));
+               init: function (objectId) {
+                       if (objectId) {
+                               this._initArticle(null, objectId);
+                       }
+                       else {
+                               elBySelAll('.jsArticleRow', undefined, this._initArticle.bind(this));
+                       }
                },
                
                /**
                 * Initializes an article row element.
                 * 
                 * @param       {Element}       article         article row element
+                * @param       {int}           objectId        optional article id
                 * @protected
                 */
-               _initArticle: function (article) {
-                       var objectId = ~~elData(article, 'object-id');
+               _initArticle: function (article, objectId) {
+                       var isArticleEdit = false;
+                       if (~~objectId > 0) {
+                               isArticleEdit = true;
+                               article = undefined;
+                       }
+                       else {
+                               objectId = ~~elData(article, 'object-id');
+                       }
                        
                        var buttonDelete = elBySel('.jsButtonDelete', article);
                        buttonDelete.addEventListener(WCF_CLICK_EVENT, this._prompt.bind(this, objectId, 'delete'));
@@ -47,7 +62,8 @@ define(['Ajax', 'Dictionary', 'Language', 'Ui/Confirmation', 'Ui/Notification'],
                                        restore: buttonRestore,
                                        trash: buttonTrash
                                },
-                               element: article
+                               element: article,
+                               isArticleEdit: isArticleEdit
                        });
                },
                
@@ -89,11 +105,17 @@ define(['Ajax', 'Dictionary', 'Language', 'Ui/Confirmation', 'Ui/Notification'],
                        var article = _articles.get(data.objectIDs[0]);
                        switch (data.actionName) {
                                case 'delete':
-                                       var tbody = article.element.parentNode;
-                                       elRemove(article.element);
-                                       
-                                       if (elBySel('tr', tbody) === null) {
-                                               window.location.reload();
+                                       if (article.isArticleEdit) {
+                                               //noinspection JSUnresolvedVariable
+                                               window.location = data.returnValues.redirectURL;
+                                       }
+                                       else {
+                                               var tbody = article.element.parentNode;
+                                               elRemove(article.element);
+                                               
+                                               if (elBySel('tr', tbody) === null) {
+                                                       window.location.reload();
+                                               }
                                        }
                                        break;
                                        
@@ -102,7 +124,12 @@ define(['Ajax', 'Dictionary', 'Language', 'Ui/Confirmation', 'Ui/Notification'],
                                        elHide(article.buttons.restore);
                                        elShow(article.buttons.trash);
                                        
-                                       elRemove(elBySel('.jsIconDeleted', article.element));
+                                       if (article.isArticleEdit) {
+                                               elHide(elBySel('.jsArticleNoticeTrash'));
+                                       }
+                                       else {
+                                               elRemove(elBySel('.jsIconDeleted', article.element));
+                                       }
                                        break;
                                        
                                case 'trash':
@@ -110,12 +137,17 @@ define(['Ajax', 'Dictionary', 'Language', 'Ui/Confirmation', 'Ui/Notification'],
                                        elShow(article.buttons.restore);
                                        elHide(article.buttons.trash);
                                        
-                                       var badge = elCreate('span');
-                                       badge.className = 'badge label red jsIconDeleted';
-                                       badge.textContent = Language.get('wcf.message.status.deleted');
-                                       
-                                       var h3 = elBySel('.containerHeadline > h3', article.element);
-                                       h3.insertBefore(badge, h3.firstChild);
+                                       if (article.isArticleEdit) {
+                                               elShow(elBySel('.jsArticleNoticeTrash'));
+                                       }
+                                       else {
+                                               var badge = elCreate('span');
+                                               badge.className = 'badge label red jsIconDeleted';
+                                               badge.textContent = Language.get('wcf.message.status.deleted');
+                                               
+                                               var h3 = elBySel('.containerHeadline > h3', article.element);
+                                               h3.insertBefore(badge, h3.firstChild);
+                                       }
                                        
                                        break;
                        }
index 29c6e256c82471cbb3fdf1061a8d3ee143767de0..c37db01bbaabe894a037ae1933a29da4822cd034 100644 (file)
@@ -8,6 +8,7 @@ use wcf\system\exception\UserInputException;
 use wcf\system\language\LanguageFactory;
 use wcf\system\like\LikeHandler;
 use wcf\system\message\embedded\object\MessageEmbeddedObjectManager;
+use wcf\system\request\LinkHandler;
 use wcf\system\search\SearchIndexManager;
 use wcf\system\tagging\TagEngine;
 use wcf\system\WCF;
@@ -219,6 +220,10 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                        // delete entry from search index
                        SearchIndexManager::getInstance()->delete('com.woltlab.wcf.article', $articleContentIDs);
                }
+               
+               return [
+                       'redirectURL' => LinkHandler::getInstance()->getLink('ArticleList', ['isACP' => true])
+               ];
        }
        
        /**
index 158f2b462fcb2b370f65790225e5de642f47fd48..323634fd4be276253435013f99cf3c87eb33b1f2 100644 (file)
@@ -76,7 +76,7 @@
                <item name="wcf.acp.article.button.viewArticle"><![CDATA[Vorschau anzeigen]]></item>
                <item name="wcf.acp.article.category"><![CDATA[Kategorie]]></item>
                <item name="wcf.acp.article.content"><![CDATA[Inhalt]]></item>
-               <item name="wcf.acp.article.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Artikel <span class="confirmationObject">{$article->getTitle()}</span> wirklich löschen?]]></item>
+               <item name="wcf.acp.article.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} {if $isArticleEdit|empty}den Artikel <span class="confirmationObject">{$article->getTitle()}</span>{else}diesen Artikel{/if} wirklich löschen?]]></item>
                <item name="wcf.acp.article.enableComments"><![CDATA[Kommentare aktivieren]]></item>
                <item name="wcf.acp.article.i18n"><![CDATA[Mehrsprachigkeit]]></item>
                <item name="wcf.acp.article.i18n.none"><![CDATA[Einsprachiger Artikel]]></item>
                <item name="wcf.acp.article.publicationStatus.unpublished"><![CDATA[Unveröffentlicht]]></item>
                <item name="wcf.acp.article.publicationStatus.published"><![CDATA[Veröffentlicht]]></item>
                <item name="wcf.acp.article.publicationStatus.delayed"><![CDATA[Zeitgesteuerte Veröffentlichung]]></item>
-               <item name="wcf.acp.article.restore.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Artikel <span class="confirmationObject">{$article->getTitle()}</span> wirklich wiederherstellen?]]></item>
+               <item name="wcf.acp.article.restore.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} {if $isArticleEdit|empty}den Artikel <span class="confirmationObject">{$article->getTitle()}</span>{else}diesen Artikel{/if} wirklich wiederherstellen?]]></item>
                <item name="wcf.acp.article.teaser"><![CDATA[Einleitungstext]]></item>
-               <item name="wcf.acp.article.trash.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} den Artikel <span class="confirmationObject">{$article->getTitle()}</span> wirklich in den Papierkorb verschieben?]]></item>
+               <item name="wcf.acp.article.trash.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} {if $isArticleEdit|empty}den Artikel <span class="confirmationObject">{$article->getTitle()}</span>{else}diesen Artikel{/if} wirklich in den Papierkorb verschieben?]]></item>
+               <item name="wcf.acp.article.trash.notice"><![CDATA[Dieser Artikel befindet sich im Papierkorb und wird gegenwärtig nicht angezeigt.]]></item>
                <item name="wcf.acp.article.views"><![CDATA[Zugriffe]]></item>
        </category>
        
index fcd2aa71fe8169912b9c1d495e7865d7a950eb2f..a433600359b391badbc65636b72d95a9938529d2 100644 (file)
@@ -76,7 +76,7 @@
                <item name="wcf.acp.article.button.viewArticle"><![CDATA[Show Preview]]></item>
                <item name="wcf.acp.article.category"><![CDATA[Category]]></item>
                <item name="wcf.acp.article.content"><![CDATA[Content]]></item>
-               <item name="wcf.acp.article.delete.confirmMessage"><![CDATA[Do you really want to delete the article <span class="confirmationObject">{$article->getTitle()}</span>?]]></item>
+               <item name="wcf.acp.article.delete.confirmMessage"><![CDATA[Do you really want to delete {if $isArticleEdit|empty}the article <span class="confirmationObject">{$article->getTitle()}</span>{else}this article{/if}?]]></item>
                <item name="wcf.acp.article.enableComments"><![CDATA[Enable comments]]></item>
                <item name="wcf.acp.article.i18n"><![CDATA[Multilingualism]]></item>
                <item name="wcf.acp.article.i18n.none"><![CDATA[Monolingual article]]></item>
                <item name="wcf.acp.article.publicationStatus.unpublished"><![CDATA[Unpublished]]></item>
                <item name="wcf.acp.article.publicationStatus.published"><![CDATA[Published]]></item>
                <item name="wcf.acp.article.publicationStatus.delayed"><![CDATA[Delayed publishing]]></item>
-               <item name="wcf.acp.article.restore.confirmMessage"><![CDATA[Do you really want to restore the article <span class="confirmationObject">{$article->getTitle()}</span>?]]></item>
+               <item name="wcf.acp.article.restore.confirmMessage"><![CDATA[Do you really want to restore {if $isArticleEdit|empty}the article <span class="confirmationObject">{$article->getTitle()}</span>{else}this article{/if}?]]></item>
                <item name="wcf.acp.article.teaser"><![CDATA[Teaser]]></item>
-               <item name="wcf.acp.article.trash.confirmMessage"><![CDATA[Do you really want to move the article <span class="confirmationObject">{$article->getTitle()}</span> to the trash bin?]]></item>
+               <item name="wcf.acp.article.trash.confirmMessage"><![CDATA[Do you really want to move {if $isArticleEdit|empty}the article <span class="confirmationObject">{$article->getTitle()}</span>{else}this article{/if} to the trash bin?]]></item>
+               <item name="wcf.acp.article.trash.notice"><![CDATA[This article has been moved to the trash bin and is currently hidden from view.]]></item>
                <item name="wcf.acp.article.views"><![CDATA[Views]]></item>
        </category>