From a30fced34cd3f4228e4facf631277fe440fbb097 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Thu, 20 Feb 2020 09:58:39 +0100
Subject: [PATCH] [TASK] Improve visual appearance of feature toggles

This extends and improves the visual appearance of
the feature toggle card in the settings module.

Furthermore the card now reload its content after saving.
This was not the case before and one had to close and reopen
the card to see changes made.

Resolves: #89844
Releases: master
Change-Id: I342a0719609dbd086a454bdd7f11e160284c22d6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63330
Tested-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Michael Schams <typo3@2018.schams.net>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../TypeScript/Module/Settings/Features.ts    |  1 +
 .../Classes/Controller/SettingsController.php |  1 +
 .../Settings/FeaturesGetContent.html          | 52 ++++++++++++-------
 .../JavaScript/Module/Settings/Features.js    |  2 +-
 4 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/Build/Sources/TypeScript/install/Resources/Public/TypeScript/Module/Settings/Features.ts b/Build/Sources/TypeScript/install/Resources/Public/TypeScript/Module/Settings/Features.ts
index 0e4cb99960d2..ac4e7b52de40 100644
--- a/Build/Sources/TypeScript/install/Resources/Public/TypeScript/Module/Settings/Features.ts
+++ b/Build/Sources/TypeScript/install/Resources/Public/TypeScript/Module/Settings/Features.ts
@@ -74,6 +74,7 @@ class Features extends AbstractInteractableModule {
             data.status.forEach((element: any): void => {
               Notification.showMessage(element.title, element.message, element.severity);
             });
+            this.getContent();
           } else {
             Notification.error('Something went wrong');
           }
diff --git a/typo3/sysext/install/Classes/Controller/SettingsController.php b/typo3/sysext/install/Classes/Controller/SettingsController.php
index 04d8876c208b..e3197f26efa5 100644
--- a/typo3/sysext/install/Classes/Controller/SettingsController.php
+++ b/typo3/sysext/install/Classes/Controller/SettingsController.php
@@ -450,6 +450,7 @@ class SettingsController extends AbstractController
             if (isset($configurationDescription['SYS']['items']['features']['items'][$featureName]['description'])) {
                 $default = $configurationManager->getDefaultConfigurationValueByPath('SYS/features/' . $featureName);
                 $features[] = [
+                    'label' => ucfirst(str_replace(['_', '.'], ' ', strtolower(GeneralUtility::camelCaseToLowerCaseUnderscored(preg_replace('/\./', ': ', $featureName, 1))))),
                     'name' => $featureName,
                     'description' => $configurationDescription['SYS']['items']['features']['items'][$featureName]['description'],
                     'default' => $default,
diff --git a/typo3/sysext/install/Resources/Private/Templates/Settings/FeaturesGetContent.html b/typo3/sysext/install/Resources/Private/Templates/Settings/FeaturesGetContent.html
index 376937221dba..9d272bd79013 100644
--- a/typo3/sysext/install/Resources/Private/Templates/Settings/FeaturesGetContent.html
+++ b/typo3/sysext/install/Resources/Private/Templates/Settings/FeaturesGetContent.html
@@ -5,29 +5,41 @@
     use new features of TYPO3 that may be activated on new installations but upgrading installations
     can still use the old behaviour.
 </p>
+<p>
+    <strong>Available features:</strong>
+</p>
 
 <div class="t3js-module-content" data-features-save-token="{featuresSaveToken}">
-    <strong>Available features:</strong>
     <form method="post" class="form-horizontal">
-        <f:for each="{features}" as="feature">
-            <div class="checkbox checkbox-type-labeled-toggle">
-                <input type="checkbox" class="checkbox-input"
-                    value="1"
-                    name="install[values][{feature.name}]"
-                    id="t3-install-tool-features-{feature.name}"
-                    {f:if(condition: '{feature.value} == 1', then: 'checked="checked"')}
-                >
-                <label class="checkbox-label" for="t3-install-tool-features-{feature.name}">
-                    <span class="checkbox-label-switch">
-                        <span class="checkbox-label-switch-checked">On</span>
-                        <span class="checkbox-label-switch-unchecked">Off</span>
-                    </span>
-                    <span class="checkbox-label-text">
-                        {feature.name} (default {f:if(condition: '{feature.default} == 1', then: 'on', else: 'off')}): {feature.description}
-                    </span>
-                </label>
-            </div>
-        </f:for>
+        <div class="card-container">
+            <f:for each="{features}" as="feature" iteration="iterator">
+                <div class="card card-size-large">
+                    <div class="card-header">
+                        <h4>{feature.label}</h4>
+                    </div>
+                    <div class="card-content">
+                        <div class="checkbox checkbox-type-toggle">
+                            <input
+                                type="checkbox"
+                                class="checkbox-input"
+                                value="1"
+                                name="install[values][{feature.name}]"
+                                id="t3-install-tool-features-{feature.name}"
+                                {f:if(condition: '{feature.value} == 1', then: 'checked="checked"')}
+                            />
+                            <label class="checkbox-label" for="t3-install-tool-features-{feature.name}">
+                                <span class="checkbox-label-text" style="margin-top: -4px; padding-left: 12px;">
+                                    <span>
+                                        {feature.description}<br/>
+                                        <strong>Default setting: {f:if(condition: '{feature.default} == 1', then: 'Enabled', else: 'Disabled')}</strong>
+                                    </span>
+                                </span>
+                            </label>
+                        </div>
+                    </div>
+                </div>
+            </f:for>
+        </div>
     </form>
 </div>
 </html>
diff --git a/typo3/sysext/install/Resources/Public/JavaScript/Module/Settings/Features.js b/typo3/sysext/install/Resources/Public/JavaScript/Module/Settings/Features.js
index 018d53764d29..d8cbd7a83bc0 100644
--- a/typo3/sysext/install/Resources/Public/JavaScript/Module/Settings/Features.js
+++ b/typo3/sysext/install/Resources/Public/JavaScript/Module/Settings/Features.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-define(["require","exports","jquery","../AbstractInteractableModule","TYPO3/CMS/Backend/Modal","TYPO3/CMS/Backend/Notification","TYPO3/CMS/Core/Ajax/AjaxRequest","../../Router"],(function(e,t,s,a,n,r,o,i){"use strict";class c extends a.AbstractInteractableModule{constructor(){super(...arguments),this.selectorSaveTrigger=".t3js-features-save"}initialize(e){this.currentModal=e,this.getContent(),e.on("click",this.selectorSaveTrigger,e=>{e.preventDefault(),this.save()})}getContent(){const e=this.getModalBody();new o(i.getUrl("featuresGetContent")).get({cache:"no-cache"}).then(async t=>{const s=await t.resolve();!0===s.success&&"undefined"!==s.html&&s.html.length>0?(e.empty().append(s.html),n.setButtons(s.buttons)):r.error("Something went wrong")},t=>{i.handleAjaxError(t,e)})}save(){const e=this.getModalBody(),t=this.getModuleContent().data("features-save-token"),a={};s(this.findInModal("form").serializeArray()).each((e,t)=>{a[t.name]=t.value}),a["install[action]"]="featuresSave",a["install[token]"]=t,new o(i.getUrl()).post(a).then(async e=>{const t=await e.resolve();!0===t.success&&Array.isArray(t.status)?t.status.forEach(e=>{r.showMessage(e.title,e.message,e.severity)}):r.error("Something went wrong")},t=>{i.handleAjaxError(t,e)})}}return new c}));
\ No newline at end of file
+define(["require","exports","jquery","../AbstractInteractableModule","TYPO3/CMS/Backend/Modal","TYPO3/CMS/Backend/Notification","TYPO3/CMS/Core/Ajax/AjaxRequest","../../Router"],(function(e,t,s,a,n,r,o,i){"use strict";class c extends a.AbstractInteractableModule{constructor(){super(...arguments),this.selectorSaveTrigger=".t3js-features-save"}initialize(e){this.currentModal=e,this.getContent(),e.on("click",this.selectorSaveTrigger,e=>{e.preventDefault(),this.save()})}getContent(){const e=this.getModalBody();new o(i.getUrl("featuresGetContent")).get({cache:"no-cache"}).then(async t=>{const s=await t.resolve();!0===s.success&&"undefined"!==s.html&&s.html.length>0?(e.empty().append(s.html),n.setButtons(s.buttons)):r.error("Something went wrong")},t=>{i.handleAjaxError(t,e)})}save(){const e=this.getModalBody(),t=this.getModuleContent().data("features-save-token"),a={};s(this.findInModal("form").serializeArray()).each((e,t)=>{a[t.name]=t.value}),a["install[action]"]="featuresSave",a["install[token]"]=t,new o(i.getUrl()).post(a).then(async e=>{const t=await e.resolve();!0===t.success&&Array.isArray(t.status)?(t.status.forEach(e=>{r.showMessage(e.title,e.message,e.severity)}),this.getContent()):r.error("Something went wrong")},t=>{i.handleAjaxError(t,e)})}}return new c}));
\ No newline at end of file
-- 
GitLab