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' => [],
'app.baseurl' => 'http://localhost:8000/',
'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->request->getParam('prefix');
$this->set('baseurl', Configure::read('App.fullBaseUrl'));
Configure::write('app.bsTheme', 'default');
$this->set('bsTheme',Configure::read('app.bsTheme'));
$this->set('bsTheme', Configure::read('Cerebrate')['ui.bsTheme']);
if ($this->modelClass == 'Tags.Tags') {
$this->set('metaGroup', !empty($this->isAdmin) ? 'Administration' : 'Cerebrate');

View File

@ -7,6 +7,7 @@ use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
use Cake\Validation\Validator;
use Migrations\Migrations;
use Cake\Filesystem\Folder;
use Cake\Http\Exception\MethodNotAllowedException;
class InstanceTable extends AppTable
@ -167,4 +168,22 @@ class InstanceTable extends AppTable
'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 Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
class SettingsProviderTable extends AppTable
{
@ -140,14 +141,17 @@ class SettingsProviderTable extends AppTable
],
'UI' => [
'General' => [
'ui.dark' => [
'name' => __('Dark theme'),
'type' => 'boolean',
'description' => __('Enable the dark theme of the application'),
'default' => false,
'test' => function() {
return 'Fake error';
'ui.bsTheme' => [
'description' => 'The Bootstrap theme to use for the application',
'default' => 'default',
'name' => 'UI Theme',
'options' => function($settingsProviders) {
$instanceTable = TableRegistry::getTableLocator()->get('Instance');
$themes = $instanceTable->getAvailableThemes();
return array_combine($themes, $themes);
},
'severity' => 'info',
'type' => 'select'
],
],
],
@ -174,6 +178,17 @@ class SettingsProviderTable extends AppTable
]
],
'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,7 +190,9 @@ class BootstrapGeneric
{
$html = '';
foreach ($params as $k => $v) {
$html .= BootstrapGeneric::genHTMLParam($k, $v) . ' ';
if (!empty($k) && !empty($v)) {
$html .= BootstrapGeneric::genHTMLParam($k, $v) . ' ';
}
}
return $html;
}
@ -1269,7 +1271,9 @@ class BoostrapSwitch extends BootstrapGeneric {
'variant' => 'primary',
'disabled' => false,
'checked' => false,
'title' => ''
'title' => '',
'class' => [],
'attrs' => [],
];
function __construct($options) {
@ -1299,15 +1303,15 @@ class BoostrapSwitch extends BootstrapGeneric {
],
'title' => $this->options['title']
], implode('', [
$this->genNode('input', [
$this->genNode('input', array_merge([
'type' => "checkbox",
'class' => 'orm-check-input',
'class' => 'form-check-input',
'id' => $tmpId,
($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', [
'class' => 'orm-check-label',
'class' => 'form-check-label',
'for' => $tmpId,
], h($this->options['label']))
]));

View File

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

View File

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