[TASK] Install tool: Improve 'clear tables' view 43/53743/4
authorChristian Kuhn <lolli@schwarzbu.ch>
Sun, 20 Aug 2017 11:24:05 +0000 (13:24 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 22 Aug 2017 09:10:32 +0000 (11:10 +0200)
Refactor the 'clear tables' view of the install tool:
* Main content is loaded on opening the card via ajax
* Tables with 0 rows are no longer shown
* Refresh view after 'clear this table' ajax action has been clicked

Change-Id: I8608e6561eaf9d0ae06da8e27b25c5ce879a5b62
Resolves: #82136
Related: #76084
Releases: master
Reviewed-on: https://review.typo3.org/53743
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Reviewed-by: Mona Muzaffar <mona.muzaffar@gmx.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Jan Stockfisch <jan.stockfisch@googlemail.com>
Tested-by: Jan Stockfisch <jan.stockfisch@googlemail.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTable.php [deleted file]
typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTablesClear.php [new file with mode: 0644]
typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTablesStats.php [new file with mode: 0644]
typo3/sysext/install/Classes/Controller/Action/Tool/Maintenance.php
typo3/sysext/install/Classes/Controller/AjaxController.php
typo3/sysext/install/Resources/Private/Partials/Action/Tool/Maintenance/ClearTables.html
typo3/sysext/install/Resources/Private/Templates/Action/Tool/Maintenance.html
typo3/sysext/install/Resources/Public/JavaScript/Modules/ClearTable.js [deleted file]
typo3/sysext/install/Resources/Public/JavaScript/Modules/ClearTables.js [new file with mode: 0644]

diff --git a/typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTable.php b/typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTable.php
deleted file mode 100644 (file)
index f459823..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-declare(strict_types=1);
-namespace TYPO3\CMS\Install\Controller\Action\Ajax;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Install\Service\ClearTableService;
-use TYPO3\CMS\Install\Status\OkStatus;
-
-/**
- * Truncate a given table via ClearTableService
- */
-class ClearTable extends AbstractAjaxAction
-{
-    /**
-     * Executes the action
-     *
-     * @return array Rendered content
-     * @throws \RuntimeException
-     */
-    protected function executeAction(): array
-    {
-        if (empty($this->postValues['table'])) {
-            throw new \RuntimeException(
-                'No table name given',
-                1501944076
-            );
-        }
-
-        (new ClearTableService())->clearSelectedTable($this->postValues['table']);
-        $message = new OkStatus();
-        $message->setTitle('Cleared table');
-        $messages[] = $message;
-
-        $this->view->assignMultiple([
-            'success' => true,
-            'status' => $messages,
-        ]);
-
-        return $this->view->render();
-    }
-}
diff --git a/typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTablesClear.php b/typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTablesClear.php
new file mode 100644 (file)
index 0000000..d4213e4
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Install\Controller\Action\Ajax;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Install\Service\ClearTableService;
+use TYPO3\CMS\Install\Status\OkStatus;
+
+/**
+ * Truncate a given table via ClearTableService
+ */
+class ClearTablesClear extends AbstractAjaxAction
+{
+    /**
+     * Executes the action
+     *
+     * @return array Rendered content
+     * @throws \RuntimeException
+     */
+    protected function executeAction(): array
+    {
+        if (empty($this->postValues['table'])) {
+            throw new \RuntimeException(
+                'No table name given',
+                1501944076
+            );
+        }
+
+        (new ClearTableService())->clearSelectedTable($this->postValues['table']);
+        $message = new OkStatus();
+        $message->setTitle('Cleared table');
+        $messages[] = $message;
+
+        $this->view->assignMultiple([
+            'success' => true,
+            'status' => $messages,
+        ]);
+        return $this->view->render();
+    }
+}
diff --git a/typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTablesStats.php b/typo3/sysext/install/Classes/Controller/Action/Ajax/ClearTablesStats.php
new file mode 100644 (file)
index 0000000..8724e6b
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Install\Controller\Action\Ajax;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Install\Service\ClearTableService;
+
+/**
+ * Get "clear table" stats
+ */
+class ClearTablesStats extends AbstractAjaxAction
+{
+    /**
+     * Executes the action
+     *
+     * @return array Rendered content
+     * @throws \RuntimeException
+     */
+    protected function executeAction(): array
+    {
+        $this->view->assignMultiple([
+            'success' => true,
+            'stats' => (new ClearTableService())->getTableStatistics(),
+        ]);
+        return $this->view->render();
+    }
+}
index 19767e3..3b3520b 100644 (file)
@@ -19,7 +19,6 @@ use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
 use TYPO3\CMS\Core\FormProtection\InstallToolFormProtection;
 use TYPO3\CMS\Core\Service\OpcodeCacheService;
 use TYPO3\CMS\Install\Controller\Action\AbstractAction;
-use TYPO3\CMS\Install\Service\ClearTableService;
 use TYPO3\CMS\Install\Service\Typo3tempFileService;
 
 /**
@@ -37,8 +36,7 @@ class Maintenance extends AbstractAction
         $formProtection = FormProtectionFactory::get(InstallToolFormProtection::class);
         $this->view->assignMultiple([
             'clearAllCacheOpcodeCaches' => (new OpcodeCacheService())->getAllActive(),
-            'clearTableStats' => (new ClearTableService())->getTableStatistics(),
-            'clearTableToken' => $formProtection->generateToken('installTool', 'clearTable'),
+            'clearTablesClearToken' => $formProtection->generateToken('installTool', 'clearTablesClear'),
             'clearTypo3tempFilesStats' => (new Typo3tempFileService())->getDirectoryStatistics(),
             'clearTypo3tempFilesToken' => $formProtection->generateToken('installTool', 'clearTypo3tempFiles'),
             'createAdminToken' => $formProtection->generateToken('installTool', 'createAdmin'),
index 16f828e..ccf2b6a 100644 (file)
@@ -32,7 +32,8 @@ class AjaxController extends AbstractController
     protected $authenticationActions = [
         'changeInstallToolPassword',
         'clearAllCache',
-        'clearTable',
+        'clearTablesClear',
+        'clearTablesStats',
         'clearTypo3tempFiles',
 
         'coreUpdateActivate',
index 6db6faf..8a45f3a 100644 (file)
@@ -8,26 +8,32 @@
        Use with care! Clearing tables here can have a negative impact on your site functionality.
        You could log out all users, delete all their basket data, and lose logging information!
 </p>
+
+<div class="t3js-clearTables-output"></div>
+
+<button
+       class="btn btn-default t3js-clearTables-stats"
+       type="button"
+>
+       Scan again
+</button>
 <hr>
 
-<div style="display:none;">
-       <div id="t3js-clearTable-token">{clearTableToken}</div>
+<div class="form-group">
+       <div class="t3js-clearTables-stat-container"></div>
 </div>
 
-<div class="form-group">
-       <f:for each="{clearTableStats}" as="clearTableStatistic" iteration="iterator">
-               <div class="t3js-clearTable-container t3js-clearTable-container-{clearTableStatistic.name}">
-                       <p>{clearTableStatistic.description}</p>
-                       <div class="t3js-clearTable-output"></div>
-                       <button
-                               class="btn btn-default t3js-clearTable-clear" data-table="{clearTableStatistic.name}"
-                               type="button"
-                       >
-                               Delete {clearTableStatistic.rowCount} rows from "{clearTableStatistic.name}" table
-                       </button>
-                       <f:if condition="!{iterator.isLast}">
-                               <hr>
-                       </f:if>
-               </div>
-       </f:for>
+<div style="display:none;">
+       <div id="t3js-clearTables-clear-token">{clearTablesClearToken}</div>
+       <div class="t3js-clearTables-stat-template">
+               <p class="t3js-clearTables-stat-description">{clearTableStatistic.description}</p>
+               <button
+                       class="btn btn-default t3js-clearTables-clear"
+                       type="button"
+               >
+                       Delete <span class="t3js-clearTables-stat-rows"></span> rows
+                       from table "<span class="t3js-clearTables-stat-name"></span>" table
+               </button>
+               <hr class="t3js-clearTables-stat-lastRuler">
+       </div>
 </div>
index 5d9cc86..a20da8a 100644 (file)
@@ -37,8 +37,8 @@
                        description: 'Verify and update database status.'
                },
                4: {partial: 'Action/Tool/Maintenance/ClearTables',
-                       require: 'TYPO3/CMS/Install/ClearTable',
-                       baseClass: 't3js-clearTable',
+                       require: 'TYPO3/CMS/Install/ClearTables',
+                       baseClass: 't3js-clearTables',
                        title: 'Clear Tables',
                        category: 'Database',
                        description: 'Clears semi-temporary data from database tables.'
diff --git a/typo3/sysext/install/Resources/Public/JavaScript/Modules/ClearTable.js b/typo3/sysext/install/Resources/Public/JavaScript/Modules/ClearTable.js
deleted file mode 100644 (file)
index eb99ecb..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * Module: TYPO3/CMS/Install/ClearTable
- */
-define(['jquery', 'TYPO3/CMS/Install/FlashMessage', 'TYPO3/CMS/Install/ProgressBar', 'TYPO3/CMS/Install/InfoBox', 'TYPO3/CMS/Install/Severity'], function($, FlashMessage, ProgressBar, InfoBox, Severity) {
-       'use strict';
-
-       return {
-               selectorClearToken: '#t3js-clearTable-token',
-               selectorClearTrigger: '.t3js-clearTable-clear',
-               selectorOutputContainer: '.t3js-clearTable-output',
-
-               initialize: function() {
-                       var self = this;
-                       $(document).on('click', this.selectorClearTrigger, function(e) {
-                               var table = $(e.target).data('table');
-                               e.preventDefault();
-                               self.clear(table);
-                       });
-               },
-
-               clear: function(table) {
-                       var token = $(this.selectorClearToken).text();
-                       var url = location.href + '&install[controller]=ajax';
-                       var postData = {
-                               'install': {
-                                       'action': 'clearTable',
-                                       'token': token,
-                                       'table': table
-                               }
-                       };
-                       var $container = $('.t3js-clearTable-container-' + table);
-                       var $outputContainer = $container.find(this.selectorOutputContainer);
-                       var message = ProgressBar.render(Severity.loading, 'Loading...', '');
-                       $outputContainer.empty().html(message);
-                       $.ajax({
-                               method: 'POST',
-                               data: postData,
-                               url: url,
-                               cache: false,
-                               success: function(data) {
-                                       $outputContainer.empty();
-                                       if (data.success === true && Array.isArray(data.status)) {
-                                               data.status.forEach(function(element) {
-                                                       var message = InfoBox.render(element.severity, element.title, element.message);
-                                                       $outputContainer.html(message);
-                                               });
-                                       }
-                               },
-                               error: function () {
-                                       var message = FlashMessage.render(Severity.error, 'Something went wrong', '');
-                                       $outputContainer.empty().html(message);
-                               }
-                       });
-               }
-       };
-});
diff --git a/typo3/sysext/install/Resources/Public/JavaScript/Modules/ClearTables.js b/typo3/sysext/install/Resources/Public/JavaScript/Modules/ClearTables.js
new file mode 100644 (file)
index 0000000..b751a15
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Module: TYPO3/CMS/Install/ClearTable
+ */
+define([
+       'jquery',
+       'TYPO3/CMS/Install/FlashMessage',
+       'TYPO3/CMS/Install/ProgressBar',
+       'TYPO3/CMS/Install/InfoBox',
+       'TYPO3/CMS/Install/Severity'
+], function($, FlashMessage, ProgressBar, InfoBox, Severity) {
+       'use strict';
+
+       return {
+               selectorGridderOpener: '.t3js-clearTables-open',
+               selectorClearToken: '#t3js-clearTables-clear-token',
+               selectorClearTrigger: '.t3js-clearTables-clear',
+               selectorStatsTrigger: '.t3js-clearTables-stats',
+               selectorOutputContainer: '.t3js-clearTables-output',
+               selectorStatContainer: 't3js-clearTables-stat-container',
+               selectorStatTemplate: '.t3js-clearTables-stat-template',
+               selectorStatDescription: '.t3js-clearTables-stat-description',
+               selectorStatRows: '.t3js-clearTables-stat-rows',
+               selectorStatName: '.t3js-clearTables-stat-name',
+               selectorStatLastRuler: '.t3js-clearTables-stat-lastRuler',
+
+               initialize: function() {
+                       var self = this;
+
+                       // Load stats on first open
+                       $(document).on('click', this.selectorGridderOpener, function(event) {
+                               var $element = $(event.target).closest(self.selectorGridderOpener);
+                               if (!$element.data('isInitialized')) {
+                                       $element.data('isInitialized', true);
+                                       self.getStats();
+                               }
+                       });
+
+                       $(document).on('click', this.selectorStatsTrigger, function(e) {
+                               e.preventDefault();
+                               $(self.selectorOutputContainer).empty();
+                               self.getStats();
+                       });
+
+                       $(document).on('click', this.selectorClearTrigger, function(e) {
+                               var table = $(e.target).closest(self.selectorClearTrigger).data('table');
+                               e.preventDefault();
+                               self.clear(table);
+                               self.getStats();
+                       });
+               },
+
+               getStats: function() {
+                       var self = this;
+                       var url = location.href + '&install[controller]=ajax&install[action]=clearTablesStats';
+                       var $outputContainer = $(this.selectorOutputContainer);
+                       var $statContainer = $('.' + this.selectorStatContainer);
+                       $statContainer.empty();
+                       var $statTemplate = $(this.selectorStatTemplate);
+                       var message = ProgressBar.render(Severity.loading, 'Loading...', '');
+                       $outputContainer.append(message);
+                       $.ajax({
+                               url: url,
+                               cache: false,
+                               success: function (data) {
+                                       if (data.success === true) {
+                                               $outputContainer.find('.alert-loading').remove();
+                                               if (Array.isArray(data.stats) && data.stats.length > 0) {
+                                                       data.stats.forEach(function(element) {
+                                                               if (element.rowCount > 0) {
+                                                                       var $aStat = $statTemplate.clone();
+                                                                       $aStat.find(self.selectorStatDescription).text(element.description);
+                                                                       $aStat.find(self.selectorStatName).text(element.name);
+                                                                       $aStat.find(self.selectorStatRows).text(element.rowCount);
+                                                                       $aStat.find(self.selectorClearTrigger).data('table', element.name);
+                                                                       $statContainer.append($aStat);
+                                                               }
+                                                       });
+                                                       $statContainer.find(self.selectorStatLastRuler + ':last').remove();
+                                               }
+                                       }
+                               }
+                       });
+               },
+
+               clear: function(table) {
+                       var url = location.href + '&install[controller]=ajax';
+                       var postData = {
+                               'install': {
+                                       'action': 'clearTablesClear',
+                                       'token': $(this.selectorClearToken).text(),
+                                       'table': table
+                               }
+                       };
+                       var $outputContainer = $(this.selectorOutputContainer);
+                       var message = ProgressBar.render(Severity.loading, 'Loading...', '');
+                       $outputContainer.empty().append(message);
+                       $.ajax({
+                               method: 'POST',
+                               data: postData,
+                               url: url,
+                               cache: false,
+                               success: function(data) {
+                                       $outputContainer.empty();
+                                       if (data.success === true && Array.isArray(data.status)) {
+                                               data.status.forEach(function(element) {
+                                                       var message = InfoBox.render(element.severity, element.title, element.message);
+                                                       $outputContainer.append(message);
+                                               });
+                                       }
+                               },
+                               error: function () {
+                                       var message = FlashMessage.render(Severity.error, 'Something went wrong', '');
+                                       $outputContainer.append(message);
+                               }
+                       });
+               }
+       };
+});