chg: [layout:sidebar] Started integration of sidebar - WiP

pull/72/head
mokaddem 2021-09-07 15:51:21 +02:00
parent 256b39691c
commit 50c4a31a2e
10 changed files with 320 additions and 18 deletions

View File

@ -11,6 +11,7 @@ use Cake\ORM\TableRegistry;
use Cake\Core\Configure; use Cake\Core\Configure;
use Cake\Core\Configure\Engine\PhpConfig; use Cake\Core\Configure\Engine\PhpConfig;
use Cake\Utility\Inflector; use Cake\Utility\Inflector;
use Cake\Routing\Router;
class ACLComponent extends Component class ACLComponent extends Component
{ {
@ -458,6 +459,7 @@ class ACLComponent extends Component
'ContactDB' => [ 'ContactDB' => [
'Individuals' => [ 'Individuals' => [
'label' => __('Individuals'), 'label' => __('Individuals'),
'icon' => 'address-book',
'url' => '/individuals/index', 'url' => '/individuals/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -493,6 +495,7 @@ class ACLComponent extends Component
], ],
'Organisations' => [ 'Organisations' => [
'label' => __('Organisations'), 'label' => __('Organisations'),
'icon' => 'building',
'url' => '/organisations/index', 'url' => '/organisations/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -528,6 +531,7 @@ class ACLComponent extends Component
], ],
'EncryptionKeys' => [ 'EncryptionKeys' => [
'label' => __('Encryption keys'), 'label' => __('Encryption keys'),
'icon' => 'key',
'url' => '/encryptionKeys/index', 'url' => '/encryptionKeys/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -552,6 +556,7 @@ class ACLComponent extends Component
'Trust Circles' => [ 'Trust Circles' => [
'SharingGroups' => [ 'SharingGroups' => [
'label' => __('Sharing Groups'), 'label' => __('Sharing Groups'),
'icon' => 'user-friends',
'url' => '/sharingGroups/index', 'url' => '/sharingGroups/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -583,6 +588,7 @@ class ACLComponent extends Component
'Sync' => [ 'Sync' => [
'Broods' => [ 'Broods' => [
'label' => __('Broods'), 'label' => __('Broods'),
'icon' => 'network-wired',
'url' => '/broods/index', 'url' => '/broods/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -620,6 +626,7 @@ class ACLComponent extends Component
'Administration' => [ 'Administration' => [
'Roles' => [ 'Roles' => [
'label' => __('Roles'), 'label' => __('Roles'),
'icon' => 'id-badge',
'url' => '/roles/index', 'url' => '/roles/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -655,6 +662,7 @@ class ACLComponent extends Component
], ],
'Users' => [ 'Users' => [
'label' => __('Users'), 'label' => __('Users'),
'icon' => 'users',
'url' => '/users/index', 'url' => '/users/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -690,6 +698,7 @@ class ACLComponent extends Component
], ],
'Inbox' => [ 'Inbox' => [
'label' => __('Inbox'), 'label' => __('Inbox'),
'icon' => 'inbox',
'url' => '/inbox/index', 'url' => '/inbox/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -722,6 +731,7 @@ class ACLComponent extends Component
], ],
'Outbox' => [ 'Outbox' => [
'label' => __('Outbox'), 'label' => __('Outbox'),
'icon' => 'inbox',
'url' => '/outbox/index', 'url' => '/outbox/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -751,6 +761,7 @@ class ACLComponent extends Component
], ],
'MetaTemplates' => [ 'MetaTemplates' => [
'label' => __('Meta Field Templates'), 'label' => __('Meta Field Templates'),
'icon' => 'object-group',
'url' => '/metaTemplates/index', 'url' => '/metaTemplates/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -781,6 +792,7 @@ class ACLComponent extends Component
], ],
'LocalTools' => [ 'LocalTools' => [
'label' => __('Local Tools'), 'label' => __('Local Tools'),
'icon' => 'tools',
'url' => '/localTools/index', 'url' => '/localTools/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -810,6 +822,7 @@ class ACLComponent extends Component
'Instance' => [ 'Instance' => [
__('Instance'), __('Instance'),
'url' => '/instance/home', 'url' => '/instance/home',
'icon' => 'database',
'children' => [ 'children' => [
'migration' => [ 'migration' => [
'url' => '/instance/migrationIndex', 'url' => '/instance/migrationIndex',
@ -821,6 +834,7 @@ class ACLComponent extends Component
'Cerebrate' => [ 'Cerebrate' => [
'Roles' => [ 'Roles' => [
'label' => __('Roles'), 'label' => __('Roles'),
'icon' => 'id-badge',
'url' => '/roles/index', 'url' => '/roles/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -845,6 +859,7 @@ class ACLComponent extends Component
'Instance' => [ 'Instance' => [
__('Instance'), __('Instance'),
'url' => '/instance/home', 'url' => '/instance/home',
'icon' => 'home',
'children' => [ 'children' => [
'home' => [ 'home' => [
'url' => '/instance/home', 'url' => '/instance/home',
@ -854,6 +869,7 @@ class ACLComponent extends Component
], ],
'Users' => [ 'Users' => [
__('My Profile'), __('My Profile'),
'icon' => 'user-circle',
'children' => [ 'children' => [
'View My Profile' => [ 'View My Profile' => [
'url' => '/users/view', 'url' => '/users/view',
@ -872,6 +888,7 @@ class ACLComponent extends Component
'Open' => [ 'Open' => [
'Organisations' => [ 'Organisations' => [
'label' => __('Organisations'), 'label' => __('Organisations'),
'icon' => 'buildings',
'url' => '/open/organisations/index', 'url' => '/open/organisations/index',
'children' => [ 'children' => [
'index' => [ 'index' => [
@ -883,6 +900,7 @@ class ACLComponent extends Component
], ],
'Individuals' => [ 'Individuals' => [
'label' => __('Individuals'), 'label' => __('Individuals'),
'icon' => 'address-book',
'url' => '/open/individuals/index', 'url' => '/open/individuals/index',
'children' => [ 'children' => [
'index' => [ 'index' => [

View File

@ -1,4 +1,5 @@
<?php <?php
// return;
$children = ''; $children = '';
$backgroundColour = $darkMode ? 'bg-dark' : 'bg-light'; $backgroundColour = $darkMode ? 'bg-dark' : 'bg-light';
if (isset($menu[$metaGroup])) { if (isset($menu[$metaGroup])) {

View File

@ -0,0 +1,11 @@
<div class="container-fluid bg-success">
<div class="left-navbar">
<span class="navbar-brand">Logo</span>
</div>
<div class="center-navbar">
Breadcrumb
</div>
<div class="right-navbar">
right
</div>
</div>

View File

@ -0,0 +1,17 @@
<div class="sidebar-wrapper">
<div class="sidebar-scroll">
<div class="sidebar-content">
<ul class="sidebar-elements">
<?php foreach ($menu as $category => $categorized): ?>
<?= $this->element('layouts/sidebar/category', ['label' => $category]) ?>
<?php foreach ($categorized as $parentName => $parent): ?>
<?= $this->element('layouts/sidebar/entry', [
'parent' => $parent,
])
?>
<?php endforeach; ?>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>

View File

@ -0,0 +1,4 @@
<li class="category text-muted">
<span class="category-label"><?= h($label) ?></span>
<span class="category-divider"><hr /></span>
</li>

View File

@ -0,0 +1,44 @@
<?php
$seed = 'sb-' . mt_rand();
$icon = $parent['icon'] ?? '';
$label = $parent['label'] ?? '';
$children = $parent['children'] ?? [];
if ($label == 'List organisations') {
$children = [
[
'label' => 'level 1',
'children' => [
'Level 2' => [
'label' => 'level 2',
'children' => [
'Level 3' => [
'label' => 'level 3',
]
]
]
]
]
];
}
if (!empty($children)) {
$url = "#{$seed}";
} else {
$url = $parent['url'] ?? '#';
}
?>
<?php if (empty($parent['skipTopMenu'])): ?>
<li class="<?= !empty($children) ? 'parent collapsed' : '' ?>">
<a class="sidebar-link <?= !empty($children) ? 'collapsed' : '' ?>" href="<?= h($url) ?>" data-toggle="collapse">
<i class="sidebar-icon <?= $this->FontAwesome->getClass($icon) ?>"></i>
<span class="text"><?= h($label) ?></span>
</a>
<?php if (!empty($children)): ?>
<?= $this->element('layouts/sidebar/sub-menu', [
'seed' => $seed,
'children' => $children,
]);
?>
<?php endif; ?>
</li>
<?php endif; ?>

View File

@ -0,0 +1,12 @@
<?php
$seed = $seed ?? 'sd-' . mt_rand();
?>
<ul id="<?= $seed ?>" class="sub-menu collapse">
<?php foreach ($children as $child): ?>
<?= $this->element('layouts/sidebar/entry', [
'parent' => $child,
])
?>
<?php endforeach; ?>
</ul>

View File

@ -35,6 +35,7 @@ $cakeDescription = 'Cerebrate';
?> ?>
<?= $this->Html->css('main.css') ?> <?= $this->Html->css('main.css') ?>
<?= $this->Html->css('font-awesome') ?> <?= $this->Html->css('font-awesome') ?>
<?= $this->Html->css('layout.css') ?>
<?= $this->Html->script('jquery-3.5.1.min.js') ?> <?= $this->Html->script('jquery-3.5.1.min.js') ?>
<?= $this->Html->script('popper.min.js') ?> <?= $this->Html->script('popper.min.js') ?>
<?= $this->Html->script('bootstrap.bundle.js') ?> <?= $this->Html->script('bootstrap.bundle.js') ?>
@ -48,27 +49,25 @@ $cakeDescription = 'Cerebrate';
<?= $this->Html->meta('favicon.ico', '/img/favicon.ico', ['type' => 'icon']); ?> <?= $this->Html->meta('favicon.ico', '/img/favicon.ico', ['type' => 'icon']); ?>
</head> </head>
<body> <body>
<header> <div class="main-wrapper">
<?= $this->element('header') ?> <header class="navbar top-navbar">
<?= $this->element('layouts/header') ?>
</header> </header>
<main role="main"> <div class="sidebar">
<div class="container-fluid"> <?= $this->element('layouts/sidebar') ?>
<div class="row">
<div class="col-1 d-none d-xl-block sidebar p-0">
<?= $this->element('side_menu') ?>
</div> </div>
<div role="main" class="col-xl-11 col-lg-12 ml-sm-auto pt-3 px-4"> <main role="main" class="content">
<div class="col-12 d-xl-none px-0"><?= $this->element('side_menu', ['minimal' => 1]) ?></div> <div class="container-fluid">
<?= $this->Flash->render() ?> <?= $this->Flash->render() ?>
<?= $this->fetch('content') ?> <?= $this->fetch('content') ?>
</div> </div>
</div>
</div>
</main> </main>
</div>
<div id="mainModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mediumModalLabel" aria-hidden="true"></div> <div id="mainModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mediumModalLabel" aria-hidden="true"></div>
<div id="mainToastContainer" style="position: absolute; top: 15px; right: 15px; z-index: 1080"></div> <div id="mainToastContainer" style="position: absolute; top: 15px; right: 15px; z-index: 1080"></div>
<div id="mainModalContainer"></div> <div id="mainModalContainer"></div>
</body> </body>
<script> <script>
const darkMode = (<?= empty($darkMode) ? 'false' : 'true' ?>) const darkMode = (<?= empty($darkMode) ? 'false' : 'true' ?>)
</script> </script>

196
webroot/css/layout.css Normal file
View File

@ -0,0 +1,196 @@
/* layout */
:root {
--navbar-height: 60px;
--sidebar-width: 230px;
}
.main-wrapper {
min-height: 100%;
padding-top: var(--navbar-height);
}
.top-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
padding: 0;
margin-bottom: 0;
}
.content {
position: relative;
left: 0;
margin-left: var(--sidebar-width);
min-height: 100%;
background: red;
}
.sidebar {
height: 100%;
margin-top: var(--navbar-height);
position: fixed;
top: 0;
bottom: 0;
width: var(--sidebar-width);
left: 0;
}
.left-navbar {
}
.center-navbar {
display: flex;
flex: 1 1 auto;
line-height: var(--navbar-height);
padding: 0 20px;
}
.right-navbar {
display: flex;
flex: 0 0 auto;
padding-right: 20px;
}
/* sidebar */
.sidebar-wrapper {
width: 100%;
height: 100%;
}
.sidebar-scroll {
position: relative;
height: 100%;
width: 100%;
overflow: hidden;
}
.sidebar-content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding-top: 10px;
}
ul.sidebar-elements {
margin: 0;
padding: 0;
}
/* sidebar entry */
ul.sidebar-elements > li {
list-style: none;
}
li.parent {
}
ul.sidebar-elements li > a.sidebar-link {
display: block;
padding: 0 20px;
line-height: 35px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
text-decoration: none;
color: unset;
}
ul.sidebar-elements > li > a.sidebar-link:hover {
background-color: #f0f0f0;
}
ul.sidebar-elements > li > a.sidebar-link > * {
text-align: center;
vertical-align: middle;
}
ul.sidebar-elements > li > a.sidebar-link > i.sidebar-icon {
margin-right: 10px;
font-size: 19px;
min-width: 19px;
line-height: 19px;
}
ul.sidebar-elements > li > a.sidebar-link > span.text {
line-height: 40px;
white-space: nowrap;
}
/* sidebar sub-menu */
ul.sidebar-elements li.parent > a.sidebar-link::before {
content: "\f0d7";
float: right;
font-family: 'Font Awesome 5 Free';
font-weight: 900;
font-size: 1rem;
color: #bbb;
}
ul.sidebar-elements li.parent > a.sidebar-link:not(.collapsed)::before {
content: "\f0d8";
}
ul.sidebar-elements > li ul {
padding: 10px 0;
list-style: none;
line-height: 20px;
}
ul.sidebar-elements > li ul li > a.sidebar-link {
font-size: 0.9rem;
padding-left: 35px;
padding-right: 17px;
}
ul.sidebar-elements > li ul li > a.sidebar-link:hover {
background-color: #e0e0e0;
}
ul.sidebar-elements > li ul li > ul > li > a.sidebar-link {
font-size: 0.85rem;
padding-left: 50px;
padding-right: 14px;
}
ul.sidebar-elements > li ul li > ul > li > ul > li > a.sidebar-link {
font-size: 0.8rem;
padding-left: 65px;
padding-right: 11px;
}
ul.sidebar-elements > li ul li > ul > li > ul > li > ul > li > a.sidebar-link {
font-size: 0.78rem;
padding-left: 80px;
padding-right: 8px;
}
/* sidebar category */
ul.sidebar-elements > li.category {
padding: 15px 20px 0;
line-height: 30px;
display: flex;
}
ul.sidebar-elements > li.category > span.category-label {
text-transform: uppercase;
font-size: 0.75rem;
font-weight: 600;
display: flex;
margin-right: 15px;
}
ul.sidebar-elements > li.category > span.category-divider {
flex: 1 0 0%;
display: flex;
align-items: center;
}
ul.sidebar-elements > li.category > span.category-divider > hr {
margin: 0;
height: 1px;
flex: 1 0 auto;
}

View File

@ -17,7 +17,7 @@
color:black; color:black;
} }
.sidebar {} /* .sidebar {}
.side-bar-ul { .side-bar-ul {
top: 70px; top: 70px;
@ -87,7 +87,7 @@
.side-bar-ul>.sidebar-brand a:hover { .side-bar-ul>.sidebar-brand a:hover {
color: #fff; color: #fff;
background: none; background: none;
} } */
@media(min-width:768px) { @media(min-width:768px) {
#wrapper { #wrapper {