diff --git a/webroot/js/main.js b/webroot/js/main.js index f2a5293..4de4f5e 100644 --- a/webroot/js/main.js +++ b/webroot/js/main.js @@ -162,4 +162,18 @@ $(document).ready(() => { $('#globalSearch') .keydown(debouncedGlobalSearch) .keydown(focusSearchResults); -}) + + $('.lock-sidebar a.btn-lock-sidebar').click(() => { + const $sidebar = $('.sidebar') + let expanded = $sidebar.hasClass('expanded'); + if (expanded) { + $sidebar.removeClass('expanded') + } else { + $sidebar.addClass('expanded') + } + const settingName = 'ui.sidebar.expanded'; + const url = `/user-settings/setSetting/${settingName}` + AJAXApi.quickFetchAndPostForm(url, { + value: expanded ? 0 : 1 + }, { provideFeedback: false}) + }) From 29ca08ce608519f140e59ce0f4214c5f0893610f Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Fri, 8 Oct 2021 16:57:38 +0200 Subject: [PATCH 014/297] new: [sidebar:bookmarks] Added early version of user-defined bookmarks Bookmark configs are saved in their respective user setting for each users --- src/Controller/Component/ACLComponent.php | 3 ++ .../Component/NavigationComponent.php | 30 +++++++++++++++++- src/Controller/UserSettingsController.php | 16 ++++++++++ src/Model/Table/UserSettingsTable.php | 22 +++++++++++++ templates/UserSettings/save_bookmark.php | 30 ++++++++++++++++++ templates/element/layouts/sidebar.php | 31 +++++++++++++------ .../element/layouts/sidebar/bookmark-add.php | 11 +++++++ .../layouts/sidebar/bookmark-entry.php | 30 ++++++++++++++++++ .../element/layouts/sidebar/category.php | 2 +- webroot/css/layout.css | 19 ++++++++++++ webroot/js/main.js | 9 ++++++ 11 files changed, 192 insertions(+), 11 deletions(-) create mode 100644 templates/UserSettings/save_bookmark.php create mode 100644 templates/element/layouts/sidebar/bookmark-add.php create mode 100644 templates/element/layouts/sidebar/bookmark-entry.php diff --git a/src/Controller/Component/ACLComponent.php b/src/Controller/Component/ACLComponent.php index 58c19fc..1376d96 100644 --- a/src/Controller/Component/ACLComponent.php +++ b/src/Controller/Component/ACLComponent.php @@ -457,6 +457,9 @@ class ACLComponent extends Component { $menu = $this->Navigation->getSideMenu(); foreach ($menu as $group => $subMenu) { + if ($group == '__bookmarks') { + continue; + } foreach ($subMenu as $subMenuElementName => $subMenuElement) { if (!empty($subMenuElement['url']) && !$this->checkAccessUrl($subMenuElement['url'], true) === true) { unset($menu[$group][$subMenuElementName]); diff --git a/src/Controller/Component/NavigationComponent.php b/src/Controller/Component/NavigationComponent.php index b18a34b..f1ad538 100644 --- a/src/Controller/Component/NavigationComponent.php +++ b/src/Controller/Component/NavigationComponent.php @@ -50,9 +50,37 @@ class NavigationComponent extends Component public function getSideMenu(): array { $sidemenu = new Sidemenu($this->iconToTableMapping, $this->request); - return $sidemenu->get(); + $sidemenu = $sidemenu->get(); + $sidemenu = $this->addUserBookmarks($sidemenu); + return $sidemenu; } + + public function addUserBookmarks($sidemenu): array + { + $bookmarks = $this->getUserBookmarks(); + $sidemenu = array_merge([ + '__bookmarks' => $bookmarks + ], $sidemenu); + return $sidemenu; + } + + public function getUserBookmarks(): array + { + $userSettingTable = TableRegistry::getTableLocator()->get('UserSettings'); + $setting = $userSettingTable->getSettingByName($this->request->getAttribute('identity'), 'ui.sidebar.bookmarks'); + $bookmarks = is_null($setting) ? [] : json_decode($setting->value, true); + + $links = array_map(function($bookmark) { + return [ + 'name' => $bookmark['name'], + 'label' => $bookmark['label'], + 'url' => $bookmark['url'], + ]; + }, $bookmarks); + return $links; + } + public function getBreadcrumb(): array { $controller = $this->request->getParam('controller'); diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php index 4da2ed4..99c212e 100644 --- a/src/Controller/UserSettingsController.php +++ b/src/Controller/UserSettingsController.php @@ -136,4 +136,20 @@ class UserSettingsController extends AppController } $this->set('settingName', $settingsName); } + + public function saveBookmark() + { + if (!$this->request->is('get')) { + $result = $this->UserSettings->saveBookmark($this->ACL->getUser(), $this->request->getData()); + $success = !empty($result); + $message = $success ? __('Bookmark saved') : __('Could not save bookmark'); + $this->CRUD->setResponseForController('saveBookmark', $success, $message, $result); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + } + $this->set('user_id', $this->ACL->getUser()->id); + } + } \ No newline at end of file diff --git a/src/Model/Table/UserSettingsTable.php b/src/Model/Table/UserSettingsTable.php index b4168f9..1e34b17 100644 --- a/src/Model/Table/UserSettingsTable.php +++ b/src/Model/Table/UserSettingsTable.php @@ -57,3 +57,25 @@ class UserSettingsTable extends AppTable $savedData = $this->save($setting); return $savedData; } + + public function saveBookmark($user, $data) + { + $bookmarkSettingName = 'ui.sidebar.bookmarks'; + $setting = $this->getSettingByName($user, $bookmarkSettingName); + $bookmarkData = [ + 'label' => $data['bookmark_label'], + 'name' => $data['bookmark_name'], + 'url' => $data['bookmark_url'], + ]; + if (is_null($setting)) { // setting not found, create it + $bookmarksData = json_encode([$bookmarkData]); + $result = $this->createSetting($user, $bookmarkSettingName, $bookmarksData); + } else { + $bookmarksData = json_decode($setting->value); + $bookmarksData[] = $bookmarkData; + $bookmarksData = json_encode($bookmarksData); + $result = $this->editSetting($user, $bookmarkSettingName, $bookmarksData); + } + return $result; + } +} diff --git a/templates/UserSettings/save_bookmark.php b/templates/UserSettings/save_bookmark.php new file mode 100644 index 0000000..e48626e --- /dev/null +++ b/templates/UserSettings/save_bookmark.php @@ -0,0 +1,30 @@ +element('genericElements/Form/genericForm', [ + 'data' => [ + 'title' => __('Add a bookmark'), + 'description' => __('Specify the name and the URL of the bookmark which will be tied to your user profile.'), + 'model' => 'UserSettings', + 'fields' => [ + [ + 'field' => 'bookmark_name', + 'label' => __('Name'), + 'placeholder' => __('Home page'), + ], + [ + 'field' => 'bookmark_label', + 'label' => __('Label'), + 'placeholder' => __('Home'), + ], + [ + 'field' => 'bookmark_url', + 'label' => __('URL'), + 'placeholder' => '/instance/home', + ], + ], + 'submit' => [ + 'action' => $this->request->getParam('action') + ] + ], + ]); +?> + diff --git a/templates/element/layouts/sidebar.php b/templates/element/layouts/sidebar.php index 3c20ce7..4aeb15f 100644 --- a/templates/element/layouts/sidebar.php +++ b/templates/element/layouts/sidebar.php @@ -2,19 +2,32 @@ - - + + - + \ No newline at end of file diff --git a/templates/element/layouts/sidebar/bookmark-add.php b/templates/element/layouts/sidebar/bookmark-add.php new file mode 100644 index 0000000..8e906d2 --- /dev/null +++ b/templates/element/layouts/sidebar/bookmark-add.php @@ -0,0 +1,11 @@ +Bootstrap->button([ + 'nodeType' => 'a', + 'icon' => 'plus', + 'title' => __('Add new bookmark'), + 'variant' => 'primary', + 'size' => 'sm', + 'params' => [ + 'id' => 'btn-add-bookmark', + ] +]); diff --git a/templates/element/layouts/sidebar/bookmark-entry.php b/templates/element/layouts/sidebar/bookmark-entry.php new file mode 100644 index 0000000..f2d01c1 --- /dev/null +++ b/templates/element/layouts/sidebar/bookmark-entry.php @@ -0,0 +1,30 @@ +Bootstrap->button([ + 'nodeType' => 'a', + 'text' => h($label), + 'title' => h($name), + 'variant' => 'dark', + 'outline' => !$active, + 'size' => 'sm', + 'icon' => h($icon), + 'class' => ['mb-1'], + 'params' => [ + 'href' => h($url), + ] + ]); +?> diff --git a/templates/element/layouts/sidebar/category.php b/templates/element/layouts/sidebar/category.php index 7c2be88..eaa4d00 100644 --- a/templates/element/layouts/sidebar/category.php +++ b/templates/element/layouts/sidebar/category.php @@ -1,4 +1,4 @@ -
  • +

  • diff --git a/webroot/css/layout.css b/webroot/css/layout.css index bd7e88d..1e62241 100644 --- a/webroot/css/layout.css +++ b/webroot/css/layout.css @@ -243,11 +243,30 @@ ul.sidebar-elements > li { list-style: none; } +ul.sidebar-elements li.bookmarks { + padding: 0 calc((var(--sidebar-width-collapsed) - 25px) / 2); +} + .sidebar.expanded ul.sidebar-elements li > a.sidebar-link, .sidebar:hover ul.sidebar-elements li > a.sidebar-link { text-overflow: ellipsis; } +.sidebar ul.sidebar-elements li.bookmark-categ, +.sidebar ul.sidebar-elements li.bookmarks { + display: none; +} + +.sidebar.expanded ul.sidebar-elements li.bookmark-categ, +.sidebar:hover ul.sidebar-elements li.bookmark-categ { + display: flex; +} + +.sidebar.expanded ul.sidebar-elements li.bookmarks, +.sidebar:hover ul.sidebar-elements li.bookmarks { + display: list-item; +} + ul.sidebar-elements li > a.sidebar-link { position: relative; display: block; diff --git a/webroot/js/main.js b/webroot/js/main.js index 4de4f5e..5f6bd46 100644 --- a/webroot/js/main.js +++ b/webroot/js/main.js @@ -177,3 +177,12 @@ $(document).ready(() => { value: expanded ? 0 : 1 }, { provideFeedback: false}) }) + + $('.sidebar #btn-add-bookmark').click(() => { + const url = '/user-settings/saveBookmark'; + UI.submissionModal(url).then(([modalFactory, ajaxApi]) => { + const $input = modalFactory.$modal.find('input[name="bookmark_url"]') + $input.val(window.location.pathname) + }) + }) +}) From 0d6e6aa7a4875a07e0192dae662a86a985b20994 Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Tue, 12 Oct 2021 10:16:36 +0200 Subject: [PATCH 015/297] chg: [userSettings] Initial version of template - WiP --- src/Controller/UsersController.php | 5 ++ src/Model/Entity/Individual.php | 10 +++ templates/Instance/settings.php | 2 - templates/Users/settings.php | 80 +++++++++++++++++++ .../element/layouts/header/header-profile.php | 5 +- 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 templates/Users/settings.php diff --git a/src/Controller/UsersController.php b/src/Controller/UsersController.php index 4b13df6..ec17d6b 100644 --- a/src/Controller/UsersController.php +++ b/src/Controller/UsersController.php @@ -148,6 +148,11 @@ class UsersController extends AppController } } + public function settings() + { + $this->set('user', $this->ACL->getUser()); + } + public function register() { $this->InboxProcessors = TableRegistry::getTableLocator()->get('InboxProcessors'); diff --git a/src/Model/Entity/Individual.php b/src/Model/Entity/Individual.php index a14e339..15ea1f2 100644 --- a/src/Model/Entity/Individual.php +++ b/src/Model/Entity/Individual.php @@ -16,4 +16,14 @@ class Individual extends AppModel protected $_accessibleOnNew = [ 'uuid' => true, ]; + + protected $_virtual = ['full_name']; + + protected function _getFullName() + { + if (empty($this->first_name) && empty($this->last_name)) { + return $this->username; + } + return sprintf("%s %s", $this->first_name, $this->last_name); + } } diff --git a/templates/Instance/settings.php b/templates/Instance/settings.php index 0e9adf6..5e85df6 100644 --- a/templates/Instance/settings.php +++ b/templates/Instance/settings.php @@ -42,8 +42,6 @@ function genNavcard($settingsProvider, $appView) ]); array_unshift($cardContent, $notice); $tabsOptions0 = [ - // 'vertical' => true, - // 'vertical-size' => 2, 'card' => false, 'pills' => false, 'justify' => 'center', diff --git a/templates/Users/settings.php b/templates/Users/settings.php new file mode 100644 index 0000000..22222bf --- /dev/null +++ b/templates/Users/settings.php @@ -0,0 +1,80 @@ + [ + 'ui.bsTheme' => [ + 'description' => 'The Bootstrap theme to use for the application', + 'default' => 'default', + 'name' => 'UI Theme', + 'options' => (function () { + $instanceTable = TableRegistry::getTableLocator()->get('Instance'); + $themes = $instanceTable->getAvailableThemes(); + return array_combine($themes, $themes); + })(), + 'severity' => 'info', + 'type' => 'select' + ], + ], + __('Bookmarks') => 'Bookmarks', + __('Account Security') => 'Account Security', +]; + +$cardNavs = array_keys($settings); +$cardContent = []; + +$sectionHtml = ''; +foreach ($settings[__('Appearance')] as $sectionName => $sectionContent) { + $sectionHtml .= $this->element('Settings/panel', [ + 'sectionName' => $sectionName, + 'panelName' => $sectionName, + 'panelSettings' => $sectionContent, + ]); +} +$cardContent[] = $sectionHtml; +$cardContent[] = $settings[__('Bookmarks')]; +$cardContent[] = $settings[__('Account Security')]; + +$tabsOptions = [ + 'vertical' => true, + 'vertical-size' => 2, + 'card' => true, + 'pills' => true, + 'justify' => 'center', + 'nav-class' => ['settings-tabs'], + 'data' => [ + 'navs' => $cardNavs, + 'content' => $cardContent + ] +]; +$tabs = $this->Bootstrap->tabs($tabsOptions); +?> + +

    +
    +
    +
    + username) ?> + individual->full_name) ?> +
    +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/templates/element/layouts/header/header-profile.php b/templates/element/layouts/header/header-profile.php index 27c5b8d..bcc0fbf 100644 --- a/templates/element/layouts/header/header-profile.php +++ b/templates/element/layouts/header/header-profile.php @@ -19,7 +19,10 @@ use Cake\Routing\Router; - + From 3ea877fe10965f03550d97b5ccc678c61c4f7b9c Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Tue, 12 Oct 2021 10:21:12 +0200 Subject: [PATCH 016/297] chg: [ui:settings] Refactored setting factory to be more generic --- templates/Instance/settings.php | 144 +++++--------------- templates/element/Settings/category.php | 61 +++++++++ templates/element/Settings/panel.php | 17 +++ templates/element/Settings/scrollspyNav.php | 13 ++ templates/element/Settings/section.php | 46 +++++++ 5 files changed, 169 insertions(+), 112 deletions(-) create mode 100644 templates/element/Settings/category.php create mode 100644 templates/element/Settings/section.php diff --git a/templates/Instance/settings.php b/templates/Instance/settings.php index 5e85df6..20215c6 100644 --- a/templates/Instance/settings.php +++ b/templates/Instance/settings.php @@ -5,8 +5,24 @@ $variantFromSeverity = [ 'warning' => 'warning', 'info' => 'info', ]; -$this->set('variantFromSeverity', $variantFromSeverity); -$settingTable = genNavcard($settingsProvider, $this); + +$navLinks = []; +$tabContents = []; + +foreach ($settingsProvider as $settingTitle => $settingContent) { + $navLinks[] = h($settingTitle); + $tabContents[] = $this->element('Settings/category', [ + 'settings' => $settingContent, + 'includeScrollspy' => true, + ]); +} + +array_unshift($navLinks, __('Settings Diagnostic')); +$notice = $this->element('Settings/notice', [ + 'variantFromSeverity' => $variantFromSeverity, + 'notices' => $notices, +]); +array_unshift($tabContents, $notice); ?>
    element('Settings/search', [ - 'settingsFlattened' => $settingsFlattened, - ]); + $this->element('Settings/search', [ + 'settingsFlattened' => $settingsFlattened, + ]); ?>
    false, - 'pills' => false, - 'justify' => 'center', - 'nav-class' => ['settings-tabs'], - 'data' => [ - 'navs' => $navLinks, - 'content' => $tabContents - ] - ]; - echo $this->Bootstrap->tabs($tabsOptions); + $tabsOptions = [ + 'card' => false, + 'pills' => false, + 'justify' => 'center', + 'nav-class' => ['settings-tabs'], + 'data' => [ + 'navs' => $navLinks, + 'content' => $tabContents + ] + ]; + echo $this->Bootstrap->tabs($tabsOptions); + echo $this->Html->script('settings'); ?>
    - - \ No newline at end of file diff --git a/src/Controller/Component/ACLComponent.php b/src/Controller/Component/ACLComponent.php index 1376d96..5feae97 100644 --- a/src/Controller/Component/ACLComponent.php +++ b/src/Controller/Component/ACLComponent.php @@ -254,7 +254,7 @@ class ACLComponent extends Component */ public function setPublicInterfaces(): void { - $this->Authentication->allowUnauthenticated(['login']); + $this->Authentication->allowUnauthenticated(['login', 'register']); } private function checkAccessInternal($controller, $action, $soft): bool diff --git a/src/Controller/UsersController.php b/src/Controller/UsersController.php index 2205f08..d2235a6 100644 --- a/src/Controller/UsersController.php +++ b/src/Controller/UsersController.php @@ -6,6 +6,8 @@ use Cake\Utility\Hash; use Cake\Utility\Text; use Cake\ORM\TableRegistry; use \Cake\Database\Expression\QueryExpression; +use Cake\Http\Exception\UnauthorizedException; +use Cake\Core\Configure; class UsersController extends AppController { @@ -160,19 +162,27 @@ class UsersController extends AppController public function register() { - $this->InboxProcessors = TableRegistry::getTableLocator()->get('InboxProcessors'); - $processor = $this->InboxProcessors->getProcessor('User', 'Registration'); - $data = [ - 'origin' => '127.0.0.1', - 'comment' => 'Hi there!, please create an account', - 'data' => [ - 'username' => 'foobar', - 'email' => 'foobar@admin.test', - 'first_name' => 'foo', - 'last_name' => 'bar', - ], - ]; - $processorResult = $processor->create($data); - return $processor->genHTTPReply($this, $processorResult, ['controller' => 'Inbox', 'action' => 'index']); + if (empty(Configure::read('Cerebrate')['security.registration.self-registration'])) { + throw new UnauthorizedException(__('User self-registration is not open.')); + } + if ($this->request->is('post')) { + $data = $this->request->getData(); + $this->InboxProcessors = TableRegistry::getTableLocator()->get('InboxProcessors'); + $processor = $this->InboxProcessors->getProcessor('User', 'Registration'); + $data = [ + 'origin' => $this->request->clientIp(), + 'comment' => '-no comment-', + 'data' => [ + 'username' => $data['username'], + 'email' => $data['email'], + 'first_name' => $data['first_name'], + 'last_name' => $data['last_name'], + 'password' => $data['password'], + ], + ]; + $processorResult = $processor->create($data); + return $processor->genHTTPReply($this, $processorResult, ['controller' => 'Inbox', 'action' => 'index']); + } + $this->viewBuilder()->setLayout('login'); } } diff --git a/src/Model/Table/SettingProviders/CerebrateSettingsProvider.php b/src/Model/Table/SettingProviders/CerebrateSettingsProvider.php index d06bd43..d4e02f5 100644 --- a/src/Model/Table/SettingProviders/CerebrateSettingsProvider.php +++ b/src/Model/Table/SettingProviders/CerebrateSettingsProvider.php @@ -240,6 +240,16 @@ class CerebrateSettingsProvider extends BaseSettingsProvider ] ], 'Security' => [ + 'Registration' => [ + 'Registration' => [ + 'security.registration.self-registration' => [ + 'name' => __('Allow self-registration'), + 'type' => 'boolean', + 'description' => __('Enable the self-registration feature where user can request account creation. Admin can view the request and accept it in the application inbox.'), + 'default' => false, + ], + ] + ], 'Development' => [ 'Debugging' => [ 'security.debug' => [ diff --git a/templates/Users/login.php b/templates/Users/login.php index 7cc35d0..1be50cd 100644 --- a/templates/Users/login.php +++ b/templates/Users/login.php @@ -1,53 +1,58 @@ '; - echo sprintf( - '
    %s
    ', - $this->Html->image('logo-purple.png', [ - 'alt' => __('Cerebrate logo'), - 'width' => 100, 'height' => 100, - 'style' => ['filter: drop-shadow(4px 4px 4px #924da666);'] - ]) - ); - echo sprintf('

    %s

    ', __('Sign in')); - $template = [ - 'inputContainer' => '
    {{content}}
    ', - 'formGroup' => '{{input}}{{label}}', - 'submitContainer' => '
    {{content}}
    ', - ]; - $this->Form->setTemplates($template); - echo $this->Form->create(null, ['url' => ['controller' => 'users', 'action' => 'login']]); - echo $this->Form->control('username', ['label' => 'Username', 'class' => 'form-control mb-2', 'placeholder' => __('Username')]); - echo $this->Form->control('password', ['type' => 'password', 'label' => 'Password', 'class' => 'form-control mb-3', 'placeholder' => __('Password')]); - echo $this->Form->control(__('Submit'), ['type' => 'submit', 'class' => 'btn btn-primary']); - echo $this->Form->end(); - - if (!empty(Configure::read('keycloak'))) { - echo sprintf('

    %s
    ', __('Or')); - echo $this->Form->create(null, [ - 'url' => Cake\Routing\Router::url([ - 'prefix' => false, - 'plugin' => 'ADmad/SocialAuth', - 'controller' => 'Auth', - 'action' => 'login', - 'provider' => 'keycloak', - '?' => ['redirect' => $this->request->getQuery('redirect')] - ]), - ]); - echo $this->Bootstrap->button([ - 'type' => 'submit', - 'text' => __('Login with Keycloak'), - 'variant' => 'secondary', - 'class' => ['d-block', 'w-100'], - 'image' => [ - 'path' => '/img/keycloak_logo.png', - 'alt' => 'Keycloak' - ] - ]); - echo $this->Form->end(); - } - echo ''; - +use Cake\Core\Configure; ?> - + +', + $this->Html->image('logo-purple.png', [ + 'alt' => __('Cerebrate logo'), + 'width' => 100, 'height' => 100, + 'style' => ['filter: drop-shadow(4px 4px 4px #924da666);'] + ]) + ); + echo sprintf('

    %s

    ', __('Sign up')); + $template = [ + 'inputContainer' => '
    {{content}}
    ', + 'formGroup' => '{{input}}{{label}}', + 'submitContainer' => '
    {{content}}
    ', + ]; + $this->Form->setTemplates($template); + echo $this->Form->create(null, ['url' => ['controller' => 'users', 'action' => 'login']]); + echo $this->Form->control('username', ['label' => 'Username', 'class' => 'form-control mb-2', 'placeholder' => __('Username')]); + echo $this->Form->control('password', ['type' => 'password', 'label' => 'Password', 'class' => 'form-control mb-3', 'placeholder' => __('Password')]); + echo $this->Form->control(__('Login'), ['type' => 'submit', 'class' => 'btn btn-primary']); + echo $this->Form->end(); + if (!empty(Configure::read('Cerebrate')['security.registration.self-registration'])) { + echo '
    '; + echo sprintf('%s %s', __('Doesn\'t have an account?'), __('Sign up')); + echo '
    '; + } + + if (!empty(Configure::read('keycloak'))) { + echo sprintf('

    %s
    ', __('Or')); + echo $this->Form->create(null, [ + 'url' => Cake\Routing\Router::url([ + 'prefix' => false, + 'plugin' => 'ADmad/SocialAuth', + 'controller' => 'Auth', + 'action' => 'login', + 'provider' => 'keycloak', + '?' => ['redirect' => $this->request->getQuery('redirect')] + ]), + ]); + echo $this->Bootstrap->button([ + 'type' => 'submit', + 'text' => __('Login with Keycloak'), + 'variant' => 'secondary', + 'class' => ['d-block', 'w-100'], + 'image' => [ + 'path' => '/img/keycloak_logo.png', + 'alt' => 'Keycloak' + ] + ]); + echo $this->Form->end(); + } + ?> + \ No newline at end of file diff --git a/templates/Users/register.php b/templates/Users/register.php new file mode 100644 index 0000000..1831bbe --- /dev/null +++ b/templates/Users/register.php @@ -0,0 +1,42 @@ + + +', + $this->Html->image('logo-purple.png', [ + 'alt' => __('Cerebrate logo'), + 'width' => 100, 'height' => 100, + 'style' => ['filter: drop-shadow(4px 4px 4px #924da666);'] + ]) + ); + echo sprintf('

    %s

    ', __('Sign in')); + $template = [ + 'inputContainer' => '
    {{content}}
    ', + 'formGroup' => '{{label}}{{input}}', + 'submitContainer' => '
    {{content}}
    ', + 'label' => '' + ]; + $this->Form->setTemplates($template); + echo $this->Form->create(null, ['url' => ['controller' => 'users', 'action' => 'register']]); + + echo $this->Form->control('username', ['label' => __('Username'), 'class' => 'form-control mb-2']); + echo $this->Form->control('email', ['label' => __('E-mail Address'), 'class' => 'form-control mb-3']); + + echo '
    '; + echo '
    '; + echo $this->Form->control('first_name', ['label' => __('First Name'), 'class' => 'form-control']); + echo '
    '; + echo '
    '; + echo $this->Form->control('last_name', ['label' => __('Last Name'), 'class' => 'form-control mb-2']); + echo '
    '; + echo '
    '; + + echo $this->Form->control('password', ['type' => 'password', 'label' => __('Password'), 'class' => 'form-control mb-4']); + + echo $this->Form->control(__('Sign up'), ['type' => 'submit', 'class' => 'btn btn-primary']); + echo $this->Form->end(); + ?> + \ No newline at end of file diff --git a/webroot/css/main.css b/webroot/css/main.css index a4715a0..def9e0f 100644 --- a/webroot/css/main.css +++ b/webroot/css/main.css @@ -167,4 +167,12 @@ input[type="checkbox"]:disabled.change-cursor { -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat; -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8' standalone='no'%3F%3E%3Csvg xmlns='http://www.w3.org/2000/svg' height='223.995' width='383.98752' viewBox='0 0 383.98752 223.995' role='img'%3E%3Cpath d='m 367.9975,0 h -118.06 c -21.38,0 -32.09,25.85 -16.97,40.97 l 32.4,32.4 -73.37,73.38 -73.37,-73.37 c -12.5,-12.5 -32.76,-12.5 -45.25,0 l -68.69,68.69 c -6.25,6.25 -6.25,16.38 0,22.63 l 22.62,22.62 c 6.25,6.25 16.38,6.25 22.63,0 l 46.06,-46.07 73.37,73.37 c 12.5,12.5 32.76,12.5 45.25,0 l 96,-96 32.4,32.4 c 15.12,15.12 40.97,4.41 40.97,-16.97 V 16 c 0.01,-8.84 -7.15,-16 -15.99,-16 z' /%3E%3C/svg%3E%0A"); +} + +.fs-7 { + font-size: .875rem !important; +} + +.fs-8 { + font-size: .7rem !important; } \ No newline at end of file From e1b066143cf6f0160b04491d092cd798a3d913c4 Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Thu, 21 Oct 2021 08:47:13 +0200 Subject: [PATCH 041/297] fix: [ui:login] Typo in tittle --- templates/Users/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/Users/login.php b/templates/Users/login.php index 1be50cd..d5cab0e 100644 --- a/templates/Users/login.php +++ b/templates/Users/login.php @@ -12,7 +12,7 @@ use Cake\Core\Configure; 'style' => ['filter: drop-shadow(4px 4px 4px #924da666);'] ]) ); - echo sprintf('

    %s

    ', __('Sign up')); + echo sprintf('

    %s

    ', __('Sign In')); $template = [ 'inputContainer' => '
    {{content}}
    ', 'formGroup' => '{{input}}{{label}}', From 740c28a01e97e35fb6b2c62647f2694719672fe9 Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Thu, 21 Oct 2021 08:47:51 +0200 Subject: [PATCH 042/297] fix: [register] Fix login in title --- templates/Users/register.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/Users/register.php b/templates/Users/register.php index 1831bbe..66cf287 100644 --- a/templates/Users/register.php +++ b/templates/Users/register.php @@ -12,7 +12,7 @@ use Cake\Core\Configure; 'style' => ['filter: drop-shadow(4px 4px 4px #924da666);'] ]) ); - echo sprintf('

    %s

    ', __('Sign in')); + echo sprintf('

    %s

    ', __('Sign up')); $template = [ 'inputContainer' => '
    {{content}}
    ', 'formGroup' => '{{label}}{{input}}', From 49ec327923e6c0548dd2637f0a6fbb3431b1737a Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Thu, 21 Oct 2021 09:16:51 +0200 Subject: [PATCH 043/297] chg: [ui:register] Added sign-in link --- templates/Users/register.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/Users/register.php b/templates/Users/register.php index 66cf287..b013218 100644 --- a/templates/Users/register.php +++ b/templates/Users/register.php @@ -37,6 +37,9 @@ use Cake\Core\Configure; echo $this->Form->control('password', ['type' => 'password', 'label' => __('Password'), 'class' => 'form-control mb-4']); echo $this->Form->control(__('Sign up'), ['type' => 'submit', 'class' => 'btn btn-primary']); + echo '
    '; + echo sprintf('%s %s', __('Have an account?'), __('Sign in')); + echo '
    '; echo $this->Form->end(); ?> \ No newline at end of file From 1fc583c9aa98b78b1670d130a61bcffd165b4c1e Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Thu, 21 Oct 2021 09:17:53 +0200 Subject: [PATCH 044/297] fix: [registter] Typo in login link --- templates/Users/register.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/Users/register.php b/templates/Users/register.php index b013218..dd1cba4 100644 --- a/templates/Users/register.php +++ b/templates/Users/register.php @@ -38,7 +38,7 @@ use Cake\Core\Configure; echo $this->Form->control(__('Sign up'), ['type' => 'submit', 'class' => 'btn btn-primary']); echo '
    '; - echo sprintf('%s %s', __('Have an account?'), __('Sign in')); + echo sprintf('%s %s', __('Have an account?'), __('Sign in')); echo '
    '; echo $this->Form->end(); ?> From d21bad721a284f2430c1dda51b2b3e2380e8c1ce Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Thu, 21 Oct 2021 10:20:07 +0200 Subject: [PATCH 045/297] fix: [genericTemplate:filters] Correctly takes filter fields and simplified UI --- src/Controller/Component/CRUDComponent.php | 2 +- templates/genericTemplates/filters.php | 151 +++++++-------------- 2 files changed, 48 insertions(+), 105 deletions(-) diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index 585eeba..64b5777 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -90,7 +90,7 @@ class CRUDComponent extends Component $this->Controller->set('taggingEnabled', true); $this->setAllTags(); } - $filters = !empty($this->Controller->filters) ? $this->Controller->filters : []; + $filters = !empty($this->Controller->filterFields) ? $this->Controller->filterFields : []; $this->Controller->set('filters', $filters); $this->Controller->viewBuilder()->setLayout('ajax'); $this->Controller->render('/genericTemplates/filters'); diff --git a/templates/genericTemplates/filters.php b/templates/genericTemplates/filters.php index d51a0b2..bc9698d 100644 --- a/templates/genericTemplates/filters.php +++ b/templates/genericTemplates/filters.php @@ -1,6 +1,13 @@ $fieldName, + ]; +}, $filters); + $filteringForm = $this->Bootstrap->table( [ 'small' => true, @@ -9,19 +16,36 @@ $filteringForm = $this->Bootstrap->table( 'tableClass' => ['indexFilteringTable'], ], [ - 'fields' => [ - __('Field'), - __('Operator'), - [ - 'labelHtml' => sprintf('%s %s', - __('Value'), - sprintf('', __('Supports strict matches and LIKE matches with the `%` character. Example: `%.com`')) - ) + 'fields' => [ + [ + 'key' => 'fieldname', 'label' => __('Field'), 'formatter' => function ($field, $row) { + return sprintf('%s', h($field), h($field)); + } + ], + [ + 'key' => 'operator', 'label' => __('Operator'), 'formatter' => function ($field, $row) { + $options = [ + sprintf('', '=', '='), + sprintf('', '!=', '!='), + ]; + return sprintf('', implode('', $options)); + } + ], + [ + 'key' => 'value', + 'labelHtml' => sprintf( + '%s %s', + __('Value'), + sprintf('', __('Supports strict matches and LIKE matches with the `%` character. Example: `%.com`')) + ), + 'formatter' => function ($field, $row) { + return sprintf(''); + } + ], ], - __('Action') - ], - 'items' => [] -]); + 'items' => $tableItems + ] +); if ($taggingEnabled) { $helpText = $this->Bootstrap->genNode('sup', [ @@ -40,7 +64,6 @@ if ($taggingEnabled) { } $modalBody = sprintf('%s%s', $filteringForm, $filteringTags); - echo $this->Bootstrap->modal([ 'title' => __('Filtering options for {0}', Inflector::singularize($this->request->getParam('controller'))), 'size' => 'lg', @@ -69,7 +92,9 @@ echo $this->Bootstrap->modal([ if (rowData['operator'] == '!=') { fullFilter += ' !=' } - activeFilters[fullFilter] = rowData['value'] + if (rowData['value'].length > 0) { + activeFilters[fullFilter] = rowData['value'] + } }) $select = modalObject.$modal.find('select.tag-input') activeFilters['filteringTags'] = $select.select2('data').map(tag => tag.text) @@ -85,8 +110,6 @@ echo $this->Bootstrap->modal([ function initFilteringTable($filteringTable) { const $controlRow = $filteringTable.find('#controlRow') - $filteringTable.find('tbody').empty() - addControlRow($filteringTable) const randomValue = getRandomValue() const activeFilters = Object.assign({}, $(`#toggleFilterButton-${randomValue}`).data('activeFilters')) const tags = activeFilters['filteringTags'] !== undefined ? Object.assign({}, activeFilters)['filteringTags'] : [] @@ -100,7 +123,7 @@ echo $this->Bootstrap->modal([ } else if (fieldParts.length > 2) { console.error('Field contains multiple spaces. ' + field) } - addFilteringRow($filteringTable, field, value, operator) + setFilteringValues($filteringTable, field, value, operator) } $select = $filteringTable.closest('.modal-body').find('select.tag-input') let passedTags = [] @@ -118,97 +141,17 @@ echo $this->Bootstrap->modal([ .trigger('change') } - function addControlRow($filteringTable) { - const availableFilters = ; - const $selectField = $('').addClass('fieldOperator form-select form-select-sm') - .append([ - $('