From 6f4f628c7cac3effceae5e443374ef5cf7d82aad Mon Sep 17 00:00:00 2001 From: mokaddem Date: Wed, 21 Jul 2021 16:07:30 +0200 Subject: [PATCH] chg: [instance:settings] UI Improvements and framework to save settings - WiP --- src/Controller/InstanceController.php | 27 +++++ src/Model/Table/SettingsTable.php | 15 +++ templates/Instance/save_setting.php | 17 +++ templates/Instance/settings.php | 146 ++++++++++++++++++++++---- webroot/css/bootstrap-additional.css | 16 +++ webroot/js/api-helper.js | 1 + 6 files changed, 204 insertions(+), 18 deletions(-) create mode 100644 templates/Instance/save_setting.php diff --git a/src/Controller/InstanceController.php b/src/Controller/InstanceController.php index 11ea1c9..10604a2 100644 --- a/src/Controller/InstanceController.php +++ b/src/Controller/InstanceController.php @@ -111,4 +111,31 @@ class InstanceController extends AppController $this->set('settingsFlattened', $all['settingsFlattened']); $this->set('notices', $all['notices']); } + + public function saveSetting() + { + if ($this->request->is('post')) { + $data = $this->ParamHandler->harvestParams([ + 'name', + 'value' + ]); + $this->Settings = $this->getTableLocator()->get('Settings'); + $errors = $this->Settings->saveSetting($data['name'], $data['value']); + $message = __('Could not save setting `{0}`', $data['name']); + if (empty($errors)) { + $message = __('Setting `{0}` saved', $data['name']); + $data = $this->Settings->getSetting($data['name']); + // TO DEL + $data['errorMessage'] = 'Test test test'; + $data['error'] = true; + $data['error'] = false; + // TO DEL + } + $this->CRUD->setResponseForController('saveSetting', empty($errors), $message, $data, $errors); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + } + } } diff --git a/src/Model/Table/SettingsTable.php b/src/Model/Table/SettingsTable.php index 7a7d130..cdc1796 100644 --- a/src/Model/Table/SettingsTable.php +++ b/src/Model/Table/SettingsTable.php @@ -33,4 +33,19 @@ class SettingsTable extends AppTable ]; } } + + public function getSetting($name=false): array + { + $settings = Configure::read()['Cerebrate']; + $settingsProvider = $this->SettingsProvider->getSettingsConfiguration($settings); + $settingsFlattened = $this->SettingsProvider->flattenSettingsConfiguration($settingsProvider); + return $settingsFlattened[$name] ?? []; + } + + public function saveSetting(string $name, string $value): array + { + $errors = []; + // Save setting here! + return $errors; + } } diff --git a/templates/Instance/save_setting.php b/templates/Instance/save_setting.php new file mode 100644 index 0000000..6609749 --- /dev/null +++ b/templates/Instance/save_setting.php @@ -0,0 +1,17 @@ +element('genericElements/Form/genericForm', [ + 'data' => [ + 'description' => __('Authkeys are used for API access. A user can have more than one authkey, so if you would like to use separate keys per tool that queries Cerebrate, add additional keys. Use the comment field to make identifying your keys easier.'), + 'fields' => [ + [ + 'field' => 'name', + ], + [ + 'field' => 'value' + ], + ], + 'submit' => [ + 'action' => $this->request->getParam('action') + ] + ] +]); diff --git a/templates/Instance/settings.php b/templates/Instance/settings.php index 07d963b..a40e216 100644 --- a/templates/Instance/settings.php +++ b/templates/Instance/settings.php @@ -92,7 +92,7 @@ function genLevel0($settingsProvider, $appView) $content0[] = __('No Settings available yet'); } } - array_unshift($level0, __('Setting Diagnostic')); + array_unshift($level0, __('Settings Diagnostic')); array_unshift($content0, $appView->get('settingNotice')); $tabsOptions0 = [ // 'vertical' => true, @@ -178,6 +178,7 @@ function genLevel3($level2Name, $settingGroupName, $setting, $appView) 'p-2', 'mb-4', 'rounded', + 'settings-group', (!empty($groupIssueSeverity) ? "callout callout-${groupIssueSeverity}" : ''), ($appView->get('darkMode') ? 'bg-dark' : 'bg-light') ], @@ -211,56 +212,75 @@ function genSingleSetting($settingName, $setting, $appView) 'id' => "{$settingId}Help" ], h($setting['description'])); } - $error = ''; - if (!empty($setting['error'])) { - $textColor = ''; + $textColor = 'text-warning'; + if (!empty($setting['severity'])) { $textColor = "text-{$appView->get('variantFromSeverity')[$setting['severity']]}"; - $error = $appView->Bootstrap->genNode('div', [ - 'class' => ['d-block', 'invalid-feedback', $textColor], - ], h($setting['errorMessage'])); } + $error = $appView->Bootstrap->genNode('div', [ + 'class' => ['d-block', 'invalid-feedback', $textColor], + ], (!empty($setting['error']) ? h($setting['errorMessage']) : '')); if (empty($setting['type'])) { $setting['type'] = 'string'; } if ($setting['type'] == 'string') { - $input = genInputString($settingId, $setting, $appView); + $input = genInputString($settingName, $setting, $appView); } elseif ($setting['type'] == 'boolean') { - $input = genInputCheckbox($settingId, $setting, $appView); + $input = genInputCheckbox($settingName, $setting, $appView); $description = ''; } elseif ($setting['type'] == 'integer') { - $input = genInputInteger($settingId, $setting, $appView); + $input = genInputInteger($settingName, $setting, $appView); } elseif ($setting['type'] == 'select') { - $input = genInputSelect($settingId, $setting, $appView); + $input = genInputSelect($settingName, $setting, $appView); } elseif ($setting['type'] == 'multi-select') { - $input = genInputMultiSelect($settingId, $setting, $appView); + $input = genInputMultiSelect($settingName, $setting, $appView); } else { - $input = genInputString($settingId, $setting, $appView); + $input = genInputString($settingName, $setting, $appView); } + + $inputGroupSave = $appView->Bootstrap->genNode('div', [ + 'class' => ['input-group-append', 'd-none', 'position-relative', 'input-group-actions'], + ], implode('', [ + $appView->Bootstrap->genNode('a', [ + 'class' => ['position-absolute', 'fas fa-times', 'p-abs-center-y', 'text-reset text-decoration-none', 'btn-reset-setting'], + 'href' => '#', + 'style' => 'left: -1.25em; z-index: 5;' + ]), + $appView->Bootstrap->genNode('button', [ + 'class' => ['btn', 'btn-success', 'btn-save-setting'], + 'type' => 'button' + ], __('save')), + ])); + $inputGroup = $appView->Bootstrap->genNode('div', [ + 'class' => ['input-group'], + ], implode('', [$input, $inputGroupSave])); + $container = $appView->Bootstrap->genNode('div', [ 'class' => ['form-group', 'mb-2'] - ], implode('', [$label, $input, $description, $error])); + ], implode('', [$label, $inputGroup, $description, $error])); return $container; } -function genInputString($settingId, $setting, $appView) +function genInputString($settingName, $setting, $appView) { + $settingId = str_replace('.', '_', $settingName); return $appView->Bootstrap->genNode('input', [ 'class' => [ 'form-control', - "xxx-{$appView->get('variantFromSeverity')[$setting['severity']]} yyy-{$setting['severity']}", (!empty($setting['error']) ? 'is-invalid' : ''), (!empty($setting['error']) ? "border-{$appView->get('variantFromSeverity')[$setting['severity']]}" : ''), (!empty($setting['error']) && $setting['severity'] == 'warning' ? 'warning' : ''), ], 'type' => 'text', 'id' => $settingId, + 'data-setting-name' => $settingName, 'value' => isset($setting['value']) ? $setting['value'] : "", 'placeholder' => $setting['default'] ?? '', 'aria-describedby' => "{$settingId}Help" ]); } -function genInputCheckbox($settingId, $setting, $appView) +function genInputCheckbox($settingName, $setting, $appView) { + $settingId = str_replace('.', '_', $settingName); $switch = $appView->Bootstrap->genNode('input', [ 'class' => [ 'custom-control-input' @@ -269,6 +289,7 @@ function genInputCheckbox($settingId, $setting, $appView) 'value' => !empty($setting['value']) ? 1 : 0, 'checked' => !empty($setting['value']) ? 'checked' : '', 'id' => $settingId, + 'data-setting-name' => $settingName, ]); $label = $appView->Bootstrap->genNode('label', [ 'class' => [ @@ -284,8 +305,9 @@ function genInputCheckbox($settingId, $setting, $appView) ], implode('', [$switch, $label])); return $container; } -function genInputInteger($settingId, $setting, $appView) +function genInputInteger($settingName, $setting, $appView) { + $settingId = str_replace('.', '_', $settingName); return $appView->Bootstrap->genNode('input', [ 'class' => [ 'form-control' @@ -294,6 +316,7 @@ function genInputInteger($settingId, $setting, $appView) 'min' => '0', 'step' => 1, 'id' => $settingId, + 'data-setting-name' => $settingName, 'aria-describedby' => "{$settingId}Help" ]); } @@ -330,6 +353,7 @@ function isLeaf($setting)