chg: [setting] Support of themes in settings

pull/72/head
mokaddem 2021-09-18 11:21:50 +02:00
parent 652c59c597
commit b4fdc625da
8 changed files with 73 additions and 48 deletions

View File

@ -4,6 +4,6 @@ return [
'open' => [], 'open' => [],
'app.baseurl' => 'http://localhost:8000/', 'app.baseurl' => 'http://localhost:8000/',
'app.uuid' => 'cc9b9358-7c4b-4464-9a2c-f0cb089ff974', 'app.uuid' => 'cc9b9358-7c4b-4464-9a2c-f0cb089ff974',
'ui.dark' => 0, 'ui.bsTheme' => 'default',
] ]
]; ];

View File

@ -131,8 +131,7 @@ class AppController extends Controller
$this->set('ajax', $this->request->is('ajax')); $this->set('ajax', $this->request->is('ajax'));
$this->request->getParam('prefix'); $this->request->getParam('prefix');
$this->set('baseurl', Configure::read('App.fullBaseUrl')); $this->set('baseurl', Configure::read('App.fullBaseUrl'));
Configure::write('app.bsTheme', 'default'); $this->set('bsTheme', Configure::read('Cerebrate')['ui.bsTheme']);
$this->set('bsTheme',Configure::read('app.bsTheme'));
if ($this->modelClass == 'Tags.Tags') { if ($this->modelClass == 'Tags.Tags') {
$this->set('metaGroup', !empty($this->isAdmin) ? 'Administration' : 'Cerebrate'); $this->set('metaGroup', !empty($this->isAdmin) ? 'Administration' : 'Cerebrate');

View File

@ -7,6 +7,7 @@ use Cake\ORM\Table;
use Cake\ORM\TableRegistry; use Cake\ORM\TableRegistry;
use Cake\Validation\Validator; use Cake\Validation\Validator;
use Migrations\Migrations; use Migrations\Migrations;
use Cake\Filesystem\Folder;
use Cake\Http\Exception\MethodNotAllowedException; use Cake\Http\Exception\MethodNotAllowedException;
class InstanceTable extends AppTable class InstanceTable extends AppTable
@ -167,4 +168,22 @@ class InstanceTable extends AppTable
'success' => true 'success' => true
]; ];
} }
public function getAvailableThemes()
{
$themesPath = ROOT . '/webroot/css/themes';
$dir = new Folder($themesPath);
$filesRegex = 'bootstrap-(?P<themename>\w+)\.css';
$themeRegex = '/' . 'bootstrap-(?P<themename>\w+)\.css' . '/';
$files = $dir->find($filesRegex);
$themes = [];
foreach ($files as $filename) {
$matches = [];
$themeName = preg_match($themeRegex, $filename, $matches);
if (!empty($matches['themename'])) {
$themes[] = $matches['themename'];
}
}
return $themes;
}
} }

View File

@ -3,6 +3,7 @@ namespace App\Model\Table;
use App\Model\Table\AppTable; use App\Model\Table\AppTable;
use Cake\Validation\Validator; use Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
class SettingsProviderTable extends AppTable class SettingsProviderTable extends AppTable
{ {
@ -140,14 +141,17 @@ class SettingsProviderTable extends AppTable
], ],
'UI' => [ 'UI' => [
'General' => [ 'General' => [
'ui.dark' => [ 'ui.bsTheme' => [
'name' => __('Dark theme'), 'description' => 'The Bootstrap theme to use for the application',
'type' => 'boolean', 'default' => 'default',
'description' => __('Enable the dark theme of the application'), 'name' => 'UI Theme',
'default' => false, 'options' => function($settingsProviders) {
'test' => function() { $instanceTable = TableRegistry::getTableLocator()->get('Instance');
return 'Fake error'; $themes = $instanceTable->getAvailableThemes();
return array_combine($themes, $themes);
}, },
'severity' => 'info',
'type' => 'select'
], ],
], ],
], ],
@ -174,6 +178,17 @@ class SettingsProviderTable extends AppTable
] ]
], ],
'Features' => [ 'Features' => [
'Demo Settings' => [
'demo.switch' => [
'name' => __('Switch'),
'type' => 'boolean',
'description' => __('A switch acting as a checkbox'),
'default' => false,
'test' => function() {
return 'Fake error';
},
],
]
], ],
]; ];
} }

View File

@ -190,8 +190,10 @@ class BootstrapGeneric
{ {
$html = ''; $html = '';
foreach ($params as $k => $v) { foreach ($params as $k => $v) {
if (!empty($k) && !empty($v)) {
$html .= BootstrapGeneric::genHTMLParam($k, $v) . ' '; $html .= BootstrapGeneric::genHTMLParam($k, $v) . ' ';
} }
}
return $html; return $html;
} }
@ -1269,7 +1271,9 @@ class BoostrapSwitch extends BootstrapGeneric {
'variant' => 'primary', 'variant' => 'primary',
'disabled' => false, 'disabled' => false,
'checked' => false, 'checked' => false,
'title' => '' 'title' => '',
'class' => [],
'attrs' => [],
]; ];
function __construct($options) { function __construct($options) {
@ -1299,15 +1303,15 @@ class BoostrapSwitch extends BootstrapGeneric {
], ],
'title' => $this->options['title'] 'title' => $this->options['title']
], implode('', [ ], implode('', [
$this->genNode('input', [ $this->genNode('input', array_merge([
'type' => "checkbox", 'type' => "checkbox",
'class' => 'orm-check-input', 'class' => 'form-check-input',
'id' => $tmpId, 'id' => $tmpId,
($this->options['disabled'] ? 'disabled' : '') => '', ($this->options['disabled'] ? 'disabled' : '') => '',
($this->options['checked'] ? 'checked' : '') => $this->options['checked'] ? 'checked' : '' ($this->options['checked'] ? 'checked' : '') => $this->options['checked'] ? 'checked' : '',
]), ], $this->options['attrs'])),
$this->genNode('label', [ $this->genNode('label', [
'class' => 'orm-check-label', 'class' => 'form-check-label',
'for' => $tmpId, 'for' => $tmpId,
], h($this->options['label'])) ], h($this->options['label']))
])); ]));

View File

@ -25,31 +25,18 @@
} elseif ($setting['type'] == 'boolean') { } elseif ($setting['type'] == 'boolean') {
$input = (function ($settingName, $setting, $appView) { $input = (function ($settingName, $setting, $appView) {
$settingId = str_replace('.', '_', $settingName); $settingId = str_replace('.', '_', $settingName);
$switch = $appView->Bootstrap->genNode('input', [ return $this->Bootstrap->switch([
'label' => h($setting['description']),
'checked' => !empty($setting['value']),
'id' => $settingId,
'class' => [ 'class' => [
'custom-control-input',
(!empty($setting['error']) ? 'is-invalid' : ''), (!empty($setting['error']) ? 'is-invalid' : ''),
(!empty($setting['error']) ? $appView->get('variantFromSeverity')[$setting['severity']] : ''), (!empty($setting['error']) ? $appView->get('variantFromSeverity')[$setting['severity']] : ''),
], ],
'type' => 'checkbox', 'attrs' => [
'value' => !empty($setting['value']) ? 1 : 0, 'data-setting-name' => $settingName
(!empty($setting['value']) ? 'checked' : '') => !empty($setting['value']) ? 'checked' : '', ]
'id' => $settingId,
'data-setting-name' => $settingName,
]); ]);
$label = $appView->Bootstrap->genNode('label', [
'class' => [
'custom-control-label'
],
'for' => $settingId,
], h($setting['description']));
$container = $appView->Bootstrap->genNode('div', [
'class' => [
'custom-control',
'form-switch',
],
], implode('', [$switch, $label]));
return $container;
})($settingName, $setting, $this); })($settingName, $setting, $this);
$description = ''; $description = '';

View File

@ -159,34 +159,34 @@ div.progress-timeline .progress-line.progress-inactive {
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2317a2b8' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%2317a2b8' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2317a2b8' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%2317a2b8' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
} }
.custom-control-input.is-invalid.warning ~ .custom-control-label { .form-check-input.is-invalid.warning ~ .form-check-label {
color: unset; color: unset;
} }
.custom-control-input.is-invalid.warning ~ .custom-control-label::before { .form-check-input.is-invalid.warning ~ .form-check-label::before {
border-color: #ffc107; border-color: #ffc107;
} }
.custom-control-input.is-invalid.warning:checked ~ .custom-control-label::before { .form-check-input.is-invalid.warning:checked ~ .form-check-label::before {
background-color: #ffc107; background-color: #ffc107;
} }
.custom-control-input.is-invalid.warning:focus:not(:checked) ~ .custom-control-label::before { .form-check-input.is-invalid.warning:focus:not(:checked) ~ .form-check-label::before {
border-color: #ffc107; border-color: #ffc107;
} }
.custom-control-input.is-invalid.warning:focus ~ .custom-control-label::before { .form-check-input.is-invalid.warning:focus ~ .form-check-label::before {
box-shadow: 0 0 0 0.2rem #ffc10740; box-shadow: 0 0 0 0.2rem #ffc10740;
} }
.custom-control-input.is-invalid.info ~ .custom-control-label { .form-check-input.is-invalid.info ~ .form-check-label {
color: unset; color: unset;
} }
.custom-control-input.is-invalid.info ~ .custom-control-label::before { .form-check-input.is-invalid.info ~ .form-check-label::before {
border-color: #17a2b8; border-color: #17a2b8;
} }
.custom-control-input.is-invalid.info:checked ~ .custom-control-label::before { .form-check-input.is-invalid.info:checked ~ .form-check-label::before {
background-color: #17a2b8; background-color: #17a2b8;
} }
.custom-control-input.is-invalid.info:focus:not(:checked) ~ .custom-control-label::before { .form-check-input.is-invalid.info:focus:not(:checked) ~ .form-check-label::before {
border-color: #17a2b8; border-color: #17a2b8;
} }
.custom-control-input.is-invalid.info:focus ~ .custom-control-label::before { .form-check-input.is-invalid.info:focus ~ .form-check-label::before {
box-shadow: 0 0 0 0.2rem #17a2b840; box-shadow: 0 0 0 0.2rem #17a2b840;
} }

View File

@ -170,7 +170,8 @@ input[type="checkbox"]:disabled.change-cursor {
} }
.select2-container { .select2-container {
z-index: 1060; /* z-index: 1060; */
z-index: 1038;
} }
.grow-on-hover { .grow-on-hover {