Replace themes preview popup with a modal
Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
parent
af946c5e53
commit
12d662baa3
@ -4479,46 +4479,16 @@ $(window).on('popstate', function () {
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
AJAX.registerTeardown('functions.js', function () {
|
||||
$(document).off('click', 'a.themeselect');
|
||||
$(document).off('change', '.autosubmit');
|
||||
$('a.take_theme').off('click');
|
||||
});
|
||||
|
||||
AJAX.registerOnload('functions.js', function () {
|
||||
/**
|
||||
* Theme selector.
|
||||
*/
|
||||
$(document).on('click', 'a.themeselect', function (e) {
|
||||
window.open(
|
||||
e.target,
|
||||
'themes',
|
||||
'left=10,top=20,width=510,height=350,scrollbars=yes,status=yes,resizable=yes'
|
||||
);
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Automatic form submission on change.
|
||||
*/
|
||||
$(document).on('change', '.autosubmit', function () {
|
||||
$(this).closest('form').trigger('submit');
|
||||
});
|
||||
|
||||
/**
|
||||
* Theme changer.
|
||||
*/
|
||||
$('a.take_theme').on('click', function () {
|
||||
var what = this.name;
|
||||
/* eslint-disable compat/compat */
|
||||
if (window.opener && window.opener.document.forms.setTheme.elements.set_theme) {
|
||||
window.opener.document.forms.setTheme.elements.set_theme.value = what;
|
||||
window.opener.document.forms.setTheme.submit();
|
||||
window.close();
|
||||
return false;
|
||||
}
|
||||
/* eslint-enable compat/compat */
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
11
js/src/home.js
Normal file
11
js/src/home.js
Normal file
@ -0,0 +1,11 @@
|
||||
AJAX.registerTeardown('home.js', function () {
|
||||
$('#themesModal').off('show.bs.modal');
|
||||
});
|
||||
|
||||
AJAX.registerOnload('home.js', function () {
|
||||
$('#themesModal').on('show.bs.modal', function () {
|
||||
$.get('index.php?route=/themes', function (data) {
|
||||
$('#themesModal .modal-body').html(data.themes);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -21,7 +21,6 @@ use PhpMyAdmin\Server\Select;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\ThemeManager;
|
||||
use PhpMyAdmin\Url;
|
||||
use PhpMyAdmin\UserPreferences;
|
||||
use PhpMyAdmin\Util;
|
||||
use const E_USER_NOTICE;
|
||||
use const E_USER_WARNING;
|
||||
@ -68,6 +67,8 @@ class HomeController extends AbstractController
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addScriptFiles(['home.js']);
|
||||
|
||||
// This is for $cfg['ShowDatabasesNavigationAsTree'] = false;
|
||||
// See: https://github.com/phpmyadmin/phpmyadmin/issues/16520
|
||||
// The DB is defined here and sent to the JS front-end to refresh the DB tree
|
||||
@ -237,25 +238,13 @@ class HomeController extends AbstractController
|
||||
'show_php_info' => $cfg['ShowPhpInfo'],
|
||||
'is_version_checked' => $cfg['VersionCheck'],
|
||||
'phpmyadmin_version' => PMA_VERSION,
|
||||
'phpmyadmin_major_version' => PMA_MAJOR_VERSION,
|
||||
'config_storage_message' => $configStorageMessage ?? '',
|
||||
'has_theme_manager' => $cfg['ThemeManager'],
|
||||
'themes' => $this->themeManager->getThemesArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function setTheme(): void
|
||||
{
|
||||
$this->themeManager->setActiveTheme($_POST['set_theme']);
|
||||
$this->themeManager->setThemeCookie();
|
||||
|
||||
$userPreferences = new UserPreferences();
|
||||
$preferences = $userPreferences->load();
|
||||
$preferences['config_data']['ThemeDefault'] = $_POST['set_theme'];
|
||||
$userPreferences->save($preferences['config_data']);
|
||||
|
||||
$this->response->header('Location: index.php?route=/' . Url::getCommonRaw([], '&'));
|
||||
}
|
||||
|
||||
public function setCollationConnection(): void
|
||||
{
|
||||
$this->config->setUserValue(
|
||||
|
||||
@ -4,29 +4,52 @@ declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers;
|
||||
|
||||
use PhpMyAdmin\Response;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\ThemeManager;
|
||||
use function preg_replace;
|
||||
use PhpMyAdmin\Url;
|
||||
use PhpMyAdmin\UserPreferences;
|
||||
|
||||
/**
|
||||
* Displays list of themes.
|
||||
*/
|
||||
class ThemesController extends AbstractController
|
||||
{
|
||||
/** @var ThemeManager */
|
||||
private $themeManager;
|
||||
|
||||
/**
|
||||
* @param Response $response
|
||||
*/
|
||||
public function __construct($response, Template $template, ThemeManager $themeManager)
|
||||
{
|
||||
parent::__construct($response, $template);
|
||||
$this->themeManager = $themeManager;
|
||||
}
|
||||
|
||||
public function index(): void
|
||||
{
|
||||
$this->response->getFooter()->setMinimal();
|
||||
$header = $this->response->getHeader();
|
||||
$header->setBodyId('bodythemes');
|
||||
$header->setTitle('phpMyAdmin - ' . __('Theme'));
|
||||
$header->disableMenuAndConsole();
|
||||
$themes = $this->themeManager->getThemesArray();
|
||||
$themesList = $this->template->render('home/themes', ['themes' => $themes]);
|
||||
$this->response->setAjax(true);
|
||||
$this->response->addJSON('themes', $themesList);
|
||||
}
|
||||
|
||||
$this->render('themes', [
|
||||
'version' => preg_replace(
|
||||
'/([0-9]*)\.([0-9]*)\..*/',
|
||||
'\1_\2',
|
||||
PMA_VERSION
|
||||
),
|
||||
'previews' => ThemeManager::getInstance()->getPrintPreviews(),
|
||||
]);
|
||||
public function setTheme(): void
|
||||
{
|
||||
global $cfg;
|
||||
|
||||
if (! $cfg['ThemeManager'] || ! isset($_POST['set_theme'])) {
|
||||
$this->response->header('Location: index.php?route=/' . Url::getCommonRaw([], '&'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->themeManager->setActiveTheme($_POST['set_theme']);
|
||||
$this->themeManager->setThemeCookie();
|
||||
|
||||
$userPreferences = new UserPreferences();
|
||||
$preferences = $userPreferences->load();
|
||||
$preferences['config_data']['ThemeDefault'] = $_POST['set_theme'];
|
||||
$userPreferences->save($preferences['config_data']);
|
||||
|
||||
$this->response->header('Location: index.php?route=/' . Url::getCommonRaw([], '&'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,14 +93,6 @@ class Theme
|
||||
'icons',
|
||||
];
|
||||
|
||||
/** @var Template */
|
||||
public $template;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->template = new Template();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads theme information
|
||||
*
|
||||
@ -391,28 +383,4 @@ class Theme
|
||||
|
||||
return './themes/' . ThemeManager::FALLBACK_THEME . '/img/' . $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the preview for this theme
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getPrintPreview()
|
||||
{
|
||||
$url_params = ['set_theme' => $this->getId()];
|
||||
$screen = null;
|
||||
if (@file_exists($this->getFsPath() . 'screen.png')) {
|
||||
$screen = $this->getPath() . '/screen.png';
|
||||
}
|
||||
|
||||
return $this->template->render('theme_preview', [
|
||||
'url_params' => $url_params,
|
||||
'name' => $this->getName(),
|
||||
'version' => $this->getVersion(),
|
||||
'id' => $this->getId(),
|
||||
'screen' => $screen,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,21 +269,6 @@ class ThemeManager
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the previews for all themes
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getPrintPreviews(): string
|
||||
{
|
||||
$retval = '';
|
||||
foreach ($this->themes as $each_theme) {
|
||||
$retval .= $each_theme->getPrintPreview();
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
public static function initializeTheme(): ?Theme
|
||||
{
|
||||
$themeManager = self::getInstance();
|
||||
|
||||
@ -106,7 +106,6 @@ if (! defined('PHPMYADMIN')) {
|
||||
return static function (RouteCollector $routes): void {
|
||||
$routes->addGroup('', static function (RouteCollector $routes): void {
|
||||
$routes->addRoute(['GET', 'POST'], '[/]', [HomeController::class, 'index']);
|
||||
$routes->post('/set-theme', [HomeController::class, 'setTheme']);
|
||||
$routes->post('/collation-connection', [HomeController::class, 'setCollationConnection']);
|
||||
$routes->addRoute(['GET', 'POST'], '/recent-table', [HomeController::class, 'reloadRecentTablesList']);
|
||||
$routes->addRoute(['GET', 'POST'], '/git-revision', [HomeController::class, 'gitRevision']);
|
||||
@ -331,7 +330,10 @@ return static function (RouteCollector $routes): void {
|
||||
$routes->addRoute(['GET', 'POST'], '/zoom-search', [ZoomSearchController::class, 'index']);
|
||||
});
|
||||
$routes->post('/tables', [TableController::class, 'all']);
|
||||
$routes->get('/themes', [ThemesController::class, 'index']);
|
||||
$routes->addGroup('/themes', static function (RouteCollector $routes): void {
|
||||
$routes->get('', [ThemesController::class, 'index']);
|
||||
$routes->post('/set', [ThemesController::class, 'setTheme']);
|
||||
});
|
||||
$routes->addGroup('/transformation', static function (RouteCollector $routes): void {
|
||||
$routes->addRoute(['GET', 'POST'], '/overview', [TransformationOverviewController::class, 'index']);
|
||||
$routes->addRoute(['GET', 'POST'], '/wrapper', [TransformationWrapperController::class, 'index']);
|
||||
|
||||
@ -854,6 +854,7 @@ return [
|
||||
'arguments' => [
|
||||
'$response' => '@response',
|
||||
'$template' => '@template',
|
||||
'$themeManager' => '@theme_manager',
|
||||
],
|
||||
],
|
||||
PhpMyAdmin\Controllers\TransformationOverviewController::class => [
|
||||
|
||||
@ -98,12 +98,10 @@
|
||||
|
||||
{% if has_theme_manager %}
|
||||
<li id="li_select_theme" class="list-group-item">
|
||||
{{ get_image('s_theme') }}
|
||||
<form name="setTheme" method="post" action="{{ url('/set-theme') }}" class="disableAjax">
|
||||
<form method="post" action="{{ url('/themes/set') }}" class="disableAjax">
|
||||
{{ get_hidden_inputs() }}
|
||||
|
||||
<a href="{{ url('/themes') }}" target="themes" class="themeselect">
|
||||
{% trans 'Theme:' %}
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#themesModal" role="button">
|
||||
{{- get_icon('s_theme', 'Theme:'|trans) -}}
|
||||
</a>
|
||||
<select name="set_theme" lang="en" dir="ltr" class="autosubmit" aria-label="{% trans 'Theme' %}">
|
||||
{% for theme in themes %}
|
||||
@ -241,4 +239,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if has_theme_manager %}
|
||||
<div class="modal fade" id="themesModal" tabindex="-1" aria-labelledby="themesModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="themesModalLabel">{% trans 'phpMyAdmin Themes' %}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans 'Close' %}"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="spinner-border" role="status">
|
||||
<span class="visually-hidden">{% trans 'Loading…' %}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans 'Close' %}</button>
|
||||
<a href="{{ 'https://www.phpmyadmin.net/themes/'|link }}#pma_{{ phpmyadmin_major_version|replace({'.': '_'}) }}" class="btn btn-primary" rel="noopener noreferrer" target="_blank">
|
||||
{% trans 'Get more themes!' %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ config_storage_message|raw }}
|
||||
|
||||
18
templates/home/themes.twig
Normal file
18
templates/home/themes.twig
Normal file
@ -0,0 +1,18 @@
|
||||
<form method="post" action="{{ url('/themes/set') }}" class="disableAjax">
|
||||
{{ get_hidden_inputs() }}
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 g-4">
|
||||
{% for theme in themes %}
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<img src="./themes/{{ theme.id }}/screen.png" class="card-img-top" alt="{{ 'Screenshot of the %s theme.'|trans|format(theme.name) }}">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ theme.name }} <small>({{ theme.version }})</small></h5>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="btn btn-primary" name="set_theme" value="{{ theme.id }}">{% trans 'Take it' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</form>
|
||||
@ -1,16 +0,0 @@
|
||||
<div class="theme_preview">
|
||||
<h2>
|
||||
{{ name }} ({{ version }})
|
||||
</h2>
|
||||
<p>
|
||||
<a class="take_theme" name="{{ id }}" href="{{ url('/set-theme', url_params) }}">
|
||||
{% if screen is not empty %}
|
||||
<img src="{{ screen }}" alt="{{ name }}" title="{{ name }}">
|
||||
<br>
|
||||
{% else %}
|
||||
{% trans 'No preview available.' %}
|
||||
{% endif %}
|
||||
[ <strong>{% trans 'Take it' %}</strong> ]
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
@ -1,7 +0,0 @@
|
||||
<h1>phpMyAdmin - {% trans 'Theme' %}</h1>
|
||||
<p>
|
||||
<a href="{{ 'https://www.phpmyadmin.net/themes/'|link }}#pma_{{ version }}" rel="noopener noreferrer" target="_blank">
|
||||
{% trans 'Get more themes!' %}
|
||||
</a>
|
||||
</p>
|
||||
{{ previews|raw }}
|
||||
@ -71,18 +71,4 @@ class ThemeManagerTest extends AbstractTestCase
|
||||
$tm->setThemeCookie()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getPrintPreviews
|
||||
*/
|
||||
public function testGetPrintPreviews(): void
|
||||
{
|
||||
$tm = new ThemeManager();
|
||||
$preview = $tm->getPrintPreviews();
|
||||
$this->assertStringContainsString('<div class="theme_preview"', $preview);
|
||||
$this->assertStringContainsString('Original', $preview);
|
||||
$this->assertStringContainsString('set_theme=original', $preview);
|
||||
$this->assertStringContainsString('pmahomme', $preview);
|
||||
$this->assertStringContainsString('set_theme=pmahomme', $preview);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,26 +200,6 @@ class ThemeTest extends AbstractTestCase
|
||||
$this->assertEquals('/new/path', $this->object->getImgPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getPrintPreview().
|
||||
*/
|
||||
public function testGetPrintPreview(): void
|
||||
{
|
||||
parent::setLanguage();
|
||||
$this->assertStringContainsString(
|
||||
'<h2>' . "\n" . ' (0.0.0.0)',
|
||||
$this->object->getPrintPreview()
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
'name="" href="index.php?route=/set-theme&set_theme=&server=99&lang=en">',
|
||||
$this->object->getPrintPreview()
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
'No preview available.',
|
||||
$this->object->getPrintPreview()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getImgPath
|
||||
*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user