Commit 11c55be2 authored by Philipp Hamid's avatar Philipp Hamid Committed by Frank Nägler
Browse files

[TASK] Improve Install Tool UX

Implemented card layout and modals instead of gridder.
Action buttons like clear all cache trigger it's action now directly.
Upcomming Notfications are displayed via backend notifications.
Content for modals is completly loaded via ajax calls. The icon api
is now available for the standalone mode of the install tool.
"libs/chosen" is imported in backend.scss to display proper styling of
chosen selects in modals.

Releases: master
Resolves: #84772
Change-Id: Ib5efbcd45c00b9c3dc973446e3fc1ef39c1f1146
Reviewed-on: https://review.typo3.org/56065


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Benjamin Kott's avatarBenjamin Kott <benjamin.kott@outlook.com>
Tested-by: Benjamin Kott's avatarBenjamin Kott <benjamin.kott@outlook.com>
Reviewed-by: Frank Nägler's avatarFrank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Nägler's avatarFrank Naegler <frank.naegler@typo3.org>
parent 6a020f16
......@@ -33,6 +33,11 @@
//
@import "bootstrap-datetimepicker";
//
// Include chosen CSS file
//
@import "libs/chosen";
//
// Image Manipulation Wizard base styles
//
......@@ -80,6 +85,7 @@
@import "typo3/main_form";
@import "typo3/main_new_content_element_wizard";
@import "typo3/module_database";
@import "typo3/module_install";
@import "typo3/module_recycler";
@import "typo3/module_scheduler";
@import "typo3/module_tstemplate";
......
......@@ -14,6 +14,11 @@ $grid-float-breakpoint: $screen-md-min;
//
@import "minimal";
//
// Components
//
@import "component/modal";
//
// Include chosen CSS file
//
......@@ -27,11 +32,15 @@ $grid-float-breakpoint: $screen-md-min;
//
// Include elements
//
@import "typo3/element_docheader";
@import "typo3/element_message";
@import "typo3/element_table";
//
// Include modules
//
@import "typo3/module_install";
body.backend .module {
background: $gray-lighter;
}
......@@ -110,32 +119,6 @@ h1:first-child {
}
}
.item {
margin: 1em;
border: 1px solid $panel-default-heading-bg;
}
.item .item-heading {
padding: 1em;
background-color: $panel-default-heading-bg;
}
.item .item-body {
padding: 1em;
}
.list-group-item {
a {
display: block;
}
&.active {
a {
color: #fff;
}
}
}
.caret {
border: 0;
padding-left: 10px;
......@@ -297,147 +280,10 @@ hr {
}
}
@mixin panel-risk-levels($high-color, $medium-color) {
&.risk-high > .panel-heading {
background: $high-color;
color: $gray-lighter;
}
&.risk-medium > .panel-heading {
background: $medium-color;
color: $gray-darker;
}
&.risk-low > .panel-heading {
background: white;
color: $gray-darker;
}
}
a[data-toggle="collapse"] {
text-decoration: none;
}
.panel-group-flat,
.panel-group-rst {
.panel-body {
padding-right: 0;
}
}
.panel-flat,
.panel-rst,
.panel-version {
border: 0;
border-left: 2px solid $gray-light;
border-radius: 0;
margin: 0;
.panel-collapse {
position: relative;
}
&.panel-default .panel-heading {
background: $gray-lighter;
}
&.panel-breaking,
&.panel-danger {
@include panel-variant($brand-danger, #fff, $brand-danger, $brand-danger);
@include panel-risk-levels($brand-danger, lighten($brand-danger, 40));
.panel-progress .panel-progress-bar {
background-color: $brand-danger;
}
.label {
@include label-variant($label-danger-bg);
}
}
&.panel-deprecation,
&.panel-warning {
@include panel-variant($brand-warning, #fff, $brand-warning, $brand-warning);
@include panel-risk-levels($brand-warning, lighten($brand-warning, 30));
.panel-progress .panel-progress-bar {
background-color: $brand-warning;
}
.label {
@include label-variant($label-warning-bg);
}
}
&.panel-feature,
&.panel-success {
@include panel-variant($brand-success, #fff, $brand-success, $brand-success);
@include panel-risk-levels($brand-success, lighten($brand-success, 40));
.panel-progress .panel-progress-bar {
background-color: $brand-success;
}
.label {
@include label-variant($label-success-bg);
}
}
&.panel-important,
&.panel-info {
@include panel-variant($brand-info, #fff, $brand-info, $brand-info);
@include panel-risk-levels($brand-info, lighten($brand-info, 30));
.panel-progress .panel-progress-bar {
background-color: $brand-info;
}
.label {
@include label-variant($label-info-bg);
}
}
.panel-heading {
position: relative;
a.link-action {
cursor: pointer;
}
strong {
line-height: 1.5em;
}
}
.rst-tags {
position: absolute;
top: 0.75em;
right: 1em;
.label {
margin: 0 0.25em;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
}
}
pre {
margin: 0;
border-radius: 0;
border: 0;
border-top: 1px solid $gray-light;
white-space: pre-wrap;
word-break: normal;
word-wrap: normal;
}
}
.upgrade_analysis_item_to_filter pre a {
text-decoration: underline;
}
......
@mixin panel-risk-levels($high-color, $medium-color) {
&.risk-high > .panel-heading {
background: $high-color;
color: $gray-lighter;
}
&.risk-medium > .panel-heading {
background: $medium-color;
color: $gray-darker;
}
&.risk-low > .panel-heading {
background: white;
color: $gray-darker;
}
}
.panel-group-flat,
.panel-group-rst {
.panel-body {
padding-right: 0;
}
}
.panel-flat,
.panel-rst,
.panel-version {
border: 0;
border-left: 2px solid $gray-light;
border-radius: 0;
margin: 0;
.panel-collapse {
position: relative;
}
&.panel-default .panel-heading {
background: $gray-lighter;
}
&.panel-breaking,
&.panel-danger {
@include panel-variant($brand-danger, #fff, $brand-danger, $brand-danger);
@include panel-risk-levels($brand-danger, lighten($brand-danger, 40));
.panel-progress .panel-progress-bar {
background-color: $brand-danger;
}
.label {
@include label-variant($label-danger-bg);
}
}
&.panel-deprecation,
&.panel-warning {
@include panel-variant($brand-warning, #fff, $brand-warning, $brand-warning);
@include panel-risk-levels($brand-warning, lighten($brand-warning, 30));
.panel-progress .panel-progress-bar {
background-color: $brand-warning;
}
.label {
@include label-variant($label-warning-bg);
}
}
&.panel-feature,
&.panel-success {
@include panel-variant($brand-success, #fff, $brand-success, $brand-success);
@include panel-risk-levels($brand-success, lighten($brand-success, 40));
.panel-progress .panel-progress-bar {
background-color: $brand-success;
}
.label {
@include label-variant($label-success-bg);
}
}
&.panel-important,
&.panel-info {
@include panel-variant($brand-info, #fff, $brand-info, $brand-info);
@include panel-risk-levels($brand-info, lighten($brand-info, 30));
.panel-progress .panel-progress-bar {
background-color: $brand-info;
}
.label {
@include label-variant($label-info-bg);
}
}
.panel-heading {
position: relative;
a.link-action {
cursor: pointer;
}
strong {
line-height: 1.5em;
}
}
.rst-tags {
position: absolute;
top: 0.75em;
right: 1em;
.label {
margin: 0 0.25em;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
}
}
pre {
margin: 0;
border-radius: 0;
border: 0;
border-top: 1px solid $gray-light;
white-space: pre-wrap;
word-break: normal;
word-wrap: normal;
}
}
.item {
margin: 1em;
border: 1px solid $panel-default-heading-bg;
}
.item .item-heading {
padding: 1em;
background-color: $panel-default-heading-bg;
}
.item .item-body {
padding: 1em;
}
.list-group-item {
a {
display: block;
}
&.active {
a {
color: #fff;
}
}
}
......@@ -73,13 +73,50 @@ class EnvironmentController extends AbstractController
]);
}
/**
* System Information Get Data action
*
* @param $request ServerRequestInterface
* @return ResponseInterface
*/
public function systemInformationGetDataAction(ServerRequestInterface $request): ResponseInterface
{
$view = $this->initializeStandaloneView($request, 'Environment/SystemInformation.html');
$view->assignMultiple([
'systemInformationCgiDetected', GeneralUtility::isRunningOnCgiServerApi(),
'systemInformationDatabaseConnections' => $this->getDatabaseConnectionInformation(),
'systemInformationOperatingSystem' => TYPO3_OS === 'WIN' ? 'Windows' : 'Unix',
]);
return new JsonResponse([
'success' => true,
'html' => $view->render(),
]);
}
/**
* System Information Get Data action
*
* @param $request ServerRequestInterface
* @return ResponseInterface
*/
public function phpInfoGetDataAction(ServerRequestInterface $request): ResponseInterface
{
$view = $this->initializeStandaloneView($request, 'Environment/PhpInfo.html');
return new JsonResponse([
'success' => true,
'html' => $view->render(),
]);
}
/**
* Get environment status
*
* @param $request ServerRequestInterface
* @return ResponseInterface
*/
public function environmentCheckGetStatusAction(): ResponseInterface
public function environmentCheckGetStatusAction(ServerRequestInterface $request): ResponseInterface
{
$view = $this->initializeStandaloneView($request, 'Environment/EnvironmentCheck.html');
$messageQueue = new FlashMessageQueue('install');
$checkMessages = (new Check())->getStatus();
foreach ($checkMessages as $message) {
......@@ -102,16 +139,19 @@ class EnvironmentController extends AbstractController
'information' => $messageQueue->getAllMessages(FlashMessage::INFO),
'notice' => $messageQueue->getAllMessages(FlashMessage::NOTICE),
],
'html' => $view->render(),
]);
}
/**
* Get folder structure status
*
* @param $request ServerRequestInterface
* @return ResponseInterface
*/
public function folderStructureGetStatusAction(): ResponseInterface
public function folderStructureGetStatusAction(ServerRequestInterface $request): ResponseInterface
{
$view = $this->initializeStandaloneView($request, 'Environment/FolderStructure.html');
$folderStructureFactory = GeneralUtility::makeInstance(DefaultFactory::class);
$structureFacade = $folderStructureFactory->getStructure();
......@@ -136,6 +176,7 @@ class EnvironmentController extends AbstractController
'okStatus' => $okQueue,
'folderStructureFilePermissionStatus' => $permissionCheck->getMaskStatus('fileCreateMask'),
'folderStructureDirectoryPermissionStatus' => $permissionCheck->getMaskStatus('folderCreateMask'),
'html' => $view->render(),
]);
}
......@@ -155,6 +196,26 @@ class EnvironmentController extends AbstractController
]);
}
/**
* System Information Get Data action
*
* @param $request ServerRequestInterface
* @return ResponseInterface
*/
public function mailTestGetDataAction(ServerRequestInterface $request): ResponseInterface
{
$view = $this->initializeStandaloneView($request, 'Environment/MailTest.html');
$formProtection = FormProtectionFactory::get(InstallToolFormProtection::class);
$view->assignMultiple([
'mailTestToken' => $formProtection->generateToken('installTool', 'mailTest'),
'mailTestSenderAddress' => $this->getSenderEmailAddress(),
]);
return new JsonResponse([
'success' => true,
'html' => $view->render(),
]);
}
/**
* Send a test mail
*
......@@ -190,6 +251,31 @@ class EnvironmentController extends AbstractController
]);
}
/**
* System Information Get Data action
*
* @param $request ServerRequestInterface
* @return ResponseInterface
*/
public function imageProcessingGetDataAction(ServerRequestInterface $request): ResponseInterface
{
$view = $this->initializeStandaloneView($request, 'Environment/ImageProcessing.html');
$view->assignMultiple([
'imageProcessingProcessor' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor'] === 'GraphicsMagick' ? 'GraphicsMagick' : 'ImageMagick',
'imageProcessingEnabled' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'],
'imageProcessingPath' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'],
'imageProcessingVersion' => $this->determineImageMagickVersion(),
'imageProcessingEffects' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_effects'],
'imageProcessingGdlibEnabled' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'],
'imageProcessingGdlibPng' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'],
'imageProcessingFileFormats' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
]);
return new JsonResponse([
'success' => true,
'html' => $view->render(),
]);
}
/**
* Create true type font test image
*
......
<?php
declare(strict_types = 1);
namespace TYPO3\CMS\Install\Controller;
/*
* 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 Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\IconRegistry;
use TYPO3\CMS\Core\Type\Icon\IconState;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Controller for icon handling
*/
class IconController extends AbstractController
{
/**
* @var IconRegistry
*/
protected $iconRegistry;
/**
* @var IconFactory
*/
protected $iconFactory;
/**
* Set up dependencies
*/
public function __construct()
{
$this->iconRegistry = GeneralUtility::makeInstance(IconRegistry::class);
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
}
/**
* @return ResponseInterface
* @internal
*/
public function getCacheIdentifierAction(): ResponseInterface
{
return new HtmlResponse($this->iconRegistry->getCacheIdentifier());
}
/**
* @param ServerRequestInterface $request
* @return ResponseInterface
* @internal
*/
public function getIconAction(ServerRequestInterface $request): ResponseInterface
{
$parsedBody = $request->getParsedBody();
$queryParams = $request->getQueryParams();
$requestedIcon = json_decode($parsedBody['icon'] ?? $queryParams['icon'], true);