Browse Source

Merge branch 'feature/tabler-ui'

experimental
Paweł Jedwabny 3 years ago
parent
commit
78d901d18c
68 changed files with 2374 additions and 2248 deletions
  1. +0
    -6
      README.md
  2. BIN
      images/epesi_logo_RGB_Solid.png
  3. BIN
      images/epesi_logo_RGB_Solid_main.png
  4. +3
    -3
      index.php
  5. +1
    -1
      modules/Apps/Shoutbox/Shoutbox_0.php
  6. +19
    -4
      modules/Apps/Shoutbox/refresh.php
  7. +0
    -3
      modules/Base/ActionBar/ActionBarCommon_0.php
  8. +64
    -96
      modules/Base/ActionBar/ActionBar_0.php
  9. +5
    -16
      modules/Base/ActionBar/theme/default.css
  10. +14
    -83
      modules/Base/ActionBar/theme/default.tpl
  11. +12
    -0
      modules/Base/ActionBar/theme/quickaccess.twig
  12. +3
    -3
      modules/Base/Admin/theme/default.tpl
  13. +11
    -12
      modules/Base/Box/Box_0.php
  14. +1
    -8
      modules/Base/Box/default.ini
  15. +0
    -271
      modules/Base/Box/theme/default.css
  16. +6
    -189
      modules/Base/Box/theme/default.js
  17. +63
    -69
      modules/Base/Box/theme/default.tpl
  18. +0
    -2
      modules/Base/Dashboard/Dashboard_0.php
  19. +0
    -4
      modules/Base/Dashboard/ab.js
  20. +11
    -5
      modules/Base/Dashboard/theme/default.css
  21. +29
    -32
      modules/Base/Dashboard/theme/default.tpl
  22. +2
    -2
      modules/Base/Lang/LangCommon_0.php
  23. +3
    -1
      modules/Base/MainModuleIndicator/theme/logo.tpl
  24. +4
    -0
      modules/Base/Menu/Menu_0.php
  25. +22
    -0
      modules/Base/Menu/libs/LICENSE-MIT
  26. +122
    -0
      modules/Base/Menu/libs/jquery.smartmenus.bootstrap.css
  27. +174
    -0
      modules/Base/Menu/libs/jquery.smartmenus.bootstrap.js
  28. +3
    -0
      modules/Base/Menu/libs/jquery.smartmenus.bootstrap.min.js
  29. +1223
    -0
      modules/Base/Menu/libs/jquery.smartmenus.js
  30. +3
    -0
      modules/Base/Menu/libs/jquery.smartmenus.min.js
  31. +31
    -20
      modules/Base/Menu/theme/default.twig
  32. +9
    -3
      modules/Base/Search/theme/Search.tpl
  33. +68
    -32
      modules/Base/User/Login/Login_0.php
  34. +1
    -86
      modules/Base/User/Login/theme/default.css
  35. +11
    -49
      modules/Base/User/Login/theme/default.tpl
  36. +28
    -0
      modules/Base/User/Login/theme/indicator.twig
  37. +3
    -3
      modules/Base/User/Settings/theme/default.tpl
  38. +3
    -3
      modules/CRM/Contacts/Photo/theme/Contact.tpl
  39. +3
    -3
      modules/CRM/Contacts/theme/Contact.tpl
  40. +8
    -1
      modules/CRM/Filters/Filters_0.php
  41. +6
    -3
      modules/CRM/Filters/theme/button.tpl
  42. +3
    -3
      modules/CRM/Filters/theme/default.tpl
  43. +2
    -2
      modules/CRM/LoginAudit/theme/template.twig
  44. +3
    -3
      modules/CRM/Meeting/theme/default.tpl
  45. +3
    -3
      modules/CRM/PhoneCall/theme/default.tpl
  46. +3
    -3
      modules/CRM/Roundcube/theme/mails.tpl
  47. +4
    -4
      modules/Libs/Leightbox/theme/default.tpl
  48. +3
    -3
      modules/Libs/QuickForm/theme/simple_form.twig
  49. +3
    -3
      modules/Utils/Attachment/theme/View_entry.tpl
  50. +3
    -3
      modules/Utils/CommonData/theme/panel.twig
  51. +22
    -23
      modules/Utils/GenericBrowser/GenericBrowser_0.php
  52. +12
    -0
      modules/Utils/GenericBrowser/theme/actions.twig
  53. +6
    -673
      modules/Utils/GenericBrowser/theme/default.css
  54. +104
    -94
      modules/Utils/GenericBrowser/theme/default.tpl
  55. +2
    -2
      modules/Utils/RecordBrowser/CustomRecordsets/CustomRecordsets_0.php
  56. +1
    -1
      modules/Utils/RecordBrowser/RecordBrowserCommon_0.php
  57. +146
    -164
      modules/Utils/RecordBrowser/theme/Browsing_records.css
  58. +22
    -23
      modules/Utils/RecordBrowser/theme/Browsing_records.tpl
  59. +4
    -4
      modules/Utils/RecordBrowser/theme/View_entry.tpl
  60. +1
    -0
      modules/Utils/TabbedBrowser/TabbedBrowser_0.php
  61. +3
    -166
      modules/Utils/TabbedBrowser/theme/default.css
  62. +13
    -12
      modules/Utils/TabbedBrowser/theme/default.twig
  63. +7
    -6
      modules/Utils/Watchdog/Watchdog_0.php
  64. +0
    -28
      modules/Utils/Watchdog/theme/default.tpl
  65. +19
    -0
      modules/Utils/Watchdog/theme/indicator.twig
  66. +4
    -3
      package.json
  67. +1
    -2
      src/index.js
  68. +11
    -7
      yarn.lock

+ 0
- 6
README.md View File

@@ -39,12 +39,6 @@ It requires properly configured HTTP server with PHP and MySQL or PostgreSQL dat
- Use Easy Install Script: http://sourceforge.net/projects/epesi/files/easy%20installer/
- Github: https://github.com/Telaxus/epesi

Install composer asset plugin (https://github.com/fxpio/composer-asset-plugin/blob/master/Resources/doc/index.md):
- composer global require "fxp/composer-asset-plugin:~1.2"

Install Epesi dependencies with composer:
- composer install

<b>Reviews</b>
- Users reviews collected from our support forum: http://epe.si/reviews/
- Sourceforge: https://sourceforge.net/projects/epesi/reviews/


BIN
images/epesi_logo_RGB_Solid.png View File

Before After
Width: 300  |  Height: 64  |  Size: 7.0 KiB Width: 300  |  Height: 64  |  Size: 21 KiB

BIN
images/epesi_logo_RGB_Solid_main.png View File

Before After
Width: 307  |  Height: 80  |  Size: 7.3 KiB

+ 3
- 3
index.php View File

@@ -207,10 +207,10 @@ ob_start();
</style>
<?php print(TRACKING_CODE); ?>
</head>
<body class="nav-md<?php if (DIRECTION_RTL) print(' epesi_rtl'); ?>" >
<body class="<?php if (DIRECTION_RTL) print(' epesi_rtl'); ?>" >

<div id="body_content" class="container body">
<div id="main_content" class="main_container" style="display:none;"></div>
<div id="body_content" class="page">
<div id="main_content" class="page-main" style="display:none;"></div>
<div id="debug_content" style="padding-top:97px;display:none;">
<div class="button" onclick="jq('#error_box').html('');jq('#debug_content').hide();">Hide</div>
<div id="debug"></div>


+ 1
- 1
modules/Apps/Shoutbox/Shoutbox_0.php View File

@@ -269,7 +269,7 @@ class Apps_Shoutbox extends Module {
return;
}

$theme->assign('board',$big?'<div style=\'height: 500px\' id=\'shoutbox_board\'></div>':'<div id=\'shoutbox_board\'></div>');
$theme->assign('board',$big?'<div style=\'height: 500px\' id=\'shoutbox_board\'></div>':'<ul id="shoutbox_board" class="list-group card-list-group"></ul>');
$theme->assign('header', __('Shoutbox'));
$theme->display('chat_form');



+ 19
- 4
modules/Apps/Shoutbox/refresh.php View File

@@ -42,12 +42,27 @@ foreach($arr as $row) {
$color = $color[$row['base_user_login_id'] % 6];

$html = <<<HTML
<div class="bs-callout bs-callout-$color">
<h4>$user_label<span class="label label-default pull-right">$time</span></h4>
<span class="shoutbox_textbox"style="color:$fcolor;">$message</span>
</div>
<li class="list-group-item py-5">
<div class="media">
<!--<div class="media-object avatar avatar-md mr-4" style="background-image: url(demo/faces/male/16.jpg)"></div>-->
<div class="media-body">
<div class="media-heading">
<small class="float-right text-muted">$time</small>
<h5>$user_label</h5>
</div>
<div>
$message
</div>
</div>
</div>
</li>
HTML;

// <div class="bs-callout bs-callout-$color">
// <h4>$user_label<span class="label label-default pull-right">$time</span></h4>
// <span class="shoutbox_textbox"style="color:$fcolor;">$message</span>
// </div>

print($html);
}



+ 0
- 3
modules/Base/ActionBar/ActionBarCommon_0.php View File

@@ -92,9 +92,6 @@ class Base_ActionBarCommon extends ModuleCommon {
self::$icons = array();
}
public static function show_quick_access_shortcuts($value = true) {
self::$quick_access_shortcuts = $value;
}
}
on_exit(array('Base_ActionBarCommon','clean'));
?>

+ 64
- 96
modules/Base/ActionBar/ActionBar_0.php View File

@@ -81,52 +81,69 @@ class Base_ActionBar extends Module

$launcher_left = [];

$launcher_left[] = array(
'label' => __('Watchdog'),
'description' => __('Watch your notifications'),
'icon' => 'bell',
'icon_url' => null,
'open' => '',
'close' => ''
);

$launcher_right = [];

if(!isset($_SESSION['client']['__history_id__'])){
History::set();
$_SESSION['client']['__history_id__'] = null;
}

$curr_hist = History::get_id();

$last_hist = $curr_hist == 1 ? $curr_hist : $this->get_module_variable('hist', 0);

if (0 !== $last_hist) {
$launcher_left[] = array(
'label' => __('Back'),
'description' => __('Get back'),
'icon' => 'arrow-left',
'icon_url' => null,
'open' => '<a ' . $this->create_back_href() . '>',
'close' => '</a>'
);
}

$this->set_module_variable('hist', $curr_hist);

if($this->is_back()){
History::back();
}


//display
$th = $this->pack_module(Base_Theme::module_name());
$th->assign('icons', $icons);
$th->assign('launcher_left', array_reverse($launcher_left));
$th->display();
}


public function quickaccess()
{
if(!Base_AclCommon::is_user()) {
return [];
}

$items = array_filter(Base_Menu_QuickAccessCommon::get_options(), function($item) {
return Base_User_SettingsCommon::get(Base_Menu_QuickAccessCommon::module_name(), $item['name'] . '_d');
});

$items = array_map(function($item) {
return [
'href' => Base_MenuCommon::create_href($this, $item['link']),
'icon' => isset($item['link']['__icon__']) ? (array_key_exists('fa-' . $item['link']['__icon__'], FontAwesome::get())) ? $item['link']['__icon__'] : null : null,
'label' => trim(substr(strrchr($item['label'], ':'), 1))?:$item['label'],
'description' => $item['label']
];
}, $items);
return $this->twig_render('quickaccess.twig', ['items' => $items]);

}

public function launchpad()
{
if (Base_AclCommon::is_user() && $opts = Base_Menu_QuickAccessCommon::get_options()) {
self::$launchpad = array();
foreach ($opts as $k => $v) {
if (Base_ActionBarCommon::$quick_access_shortcuts
&& Base_User_SettingsCommon::get(Base_Menu_QuickAccessCommon::module_name(), $v['name'] . '_d')
) {
$ii = array();
$trimmed_label = trim(substr(strrchr($v['label'], ':'), 1));
$ii['label'] = $trimmed_label ? $trimmed_label : $v['label'];
$ii['description'] = $v['label'];
$arr = $v['link'];
$icon = null;
$icon_url = null;
if (isset($v['link']['__icon__'])) {
if (array_key_exists('fa-' . $v['link']['__icon__'], $fa_icons))
$icon = $v['link']['__icon__'];
else
$icon_url = Base_ThemeCommon::get_template_file($v['module'], $v['link']['__icon__']);
} else
$icon_url = Base_ThemeCommon::get_template_file($v['module'], 'icon.png');
if (!$icon && !$icon_url) $icon_url = 'cog';
$ii['icon'] = $icon;
$ii['icon_url'] = $icon_url;

if (isset($arr['__url__']))
$ii['open'] = '<a href="' . $arr['__url__'] . '" target="_blank" class="icon-' . ($icon ? $icon : md5($icon_url)) . '">';
else
$ii['open'] = '<a ' . Base_MenuCommon::create_href($this, $arr) . ' class="icon-' . ($icon ? $icon : md5($icon_url)) . '">';
$ii['close'] = '</a>';

if ($ii['label'] == 'Launchpad') {
$launcher_left[] = $ii;
} else {
$launcher_right[] = $ii;
}
}
if (Base_User_SettingsCommon::get(Base_Menu_QuickAccessCommon::module_name(), $v['name'] . '_l')) {
$ii = array();
$trimmed_label = trim(substr(strrchr($v['label'], ':'), 1));
@@ -143,7 +160,7 @@ class Base_ActionBar extends Module
$icon = null;
$icon_url = null;
if (isset($v['link']['__icon__'])) {
if (array_key_exists('fa-' . $v['link']['__icon__'], $fa_icons))
if (array_key_exists('fa-' . $v['link']['__icon__'], FontAwesome::get()))
$icon = $v['link']['__icon__'];
else
$icon_url = Base_ThemeCommon::get_template_file($v['module'], $v['link']['__icon__']);
@@ -167,62 +184,13 @@ class Base_ActionBar extends Module
$lp_out = ob_get_clean();
$big = count(self::$launchpad) > 10;
Libs_LeightboxCommon::display('actionbar_launchpad', $lp_out, __('Launchpad'), $big);
array_unshift($launcher_left, array('label' => __('Launchpad'), 'description' => 'Quick modules launcher', 'open' => '<a ' . Libs_LeightboxCommon::get_open_href('actionbar_launchpad') . '>', 'close' => '</a>', 'icon' => 'th-large'));
}
}

if(!isset($_SESSION['client']['__history_id__'])){
History::set();
$_SESSION['client']['__history_id__'] = null;
}
return Libs_LeightboxCommon::get_open_href('actionbar_launchpad');

$curr_hist = History::get_id();

$last_hist = $curr_hist == 1 ? $curr_hist : $this->get_module_variable('hist', 0);

if (0 !== $last_hist) {
$launcher_left[] = array(
'label' => __('Back'),
'description' => __('Get back'),
'icon' => 'arrow-left',
'icon_url' => null,
'open' => '<a ' . $this->create_back_href() . '>',
'close' => '</a>'
);
}

$this->set_module_variable('hist', $curr_hist);

if($this->is_back()){
History::back();
}

$watchdog_value = '';
$launchpad_value = '';

foreach ($launcher_left as $key => $value){
if($value['label'] == 'Watchdog'){
$watchdog_value = $value;
}
if($value['label'] == 'Launchpad'){
$launchpad_value = $value;
array_unshift($launcher_left, array('label' => __('Launchpad'), 'description' => 'Quick modules launcher', 'open' => '<a ' . Libs_LeightboxCommon::get_open_href('actionbar_launchpad') . '>', 'close' => '</a>', 'icon' => 'th-large'));
}
}

if(is_array($watchdog_value)) {
$launcher_left['0'] = $watchdog_value;
}
if(is_array($launchpad_value)) {
$launcher_left['1'] = $launchpad_value;
return null;
}
unset($launchpad_value,$watchdog_value);

//display
$th = $this->pack_module(Base_Theme::module_name());
$th->assign('icons', $icons);
$th->assign('launcher_right', array_reverse($launcher_right));
$th->assign('launcher_left', array_reverse($launcher_left));
$th->display();
}

}


+ 5
- 16
modules/Base/ActionBar/theme/default.css View File

@@ -1,8 +1,5 @@
#Base_ActionBar .btn {
padding:5px 5px 0px;
margin:0px;
min-width: 60px;
width: auto;
margin-bottom:4px;
}

.nav.navbar-nav.navbar-left {
@@ -16,17 +13,9 @@
margin: 8px 9px 0;
}

#gradient {
height: 6px;
width: 100%;
margin-left: .1px;
opacity: 0.40;
background: linear-gradient(black,transparent);
}

#nano-bar {
height: 6px;
width: 100%;
margin-left: .1px;
margin-top: -4px;
height: 6px;
width: 100%;
margin-left: .1px;
margin-top: -4px;
}

+ 14
- 83
modules/Base/ActionBar/theme/default.tpl View File

@@ -1,97 +1,28 @@
<div id="Base_ActionBar">
<div class="row">

<div class="nav navbar-nav navbar-left">

<div>
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group btn-group-sm mr-2" role="group" aria-label="First group">
{foreach item=i from=$launcher_left}
{$i.open}
<div class="btn toggle">
{if $i.icon_url}
<img src="{$i.icon_url}" style="height:2em">
{else}
<i class="fa fa-{$i.icon} fa-2x"></i>
{/if}
<div>{$i.label}</div>
</div>
{$i.close}
{/foreach}
</div>

<div class="separating-line"></div>
<button class="btn btn-sm btn-secondary">
{if $i.icon}

<div>
{foreach item=i from=$icons}
{$i.open}
<div class="btn toggle" helpID="{$i.helpID}">
{if $i.icon_url}
<img src="{$i.icon_url}" style="height:2em">
{else}
<i class="fa fa-{$i.icon} fa-2x"></i>
{/if}
{*<a href="javascript:;" class="dropdown-toggle info-number" data-toggle="dropdown" aria-expanded="false">*}
{*<i class="fa fa-bell fa-2x"></i>*}
{*<span class="badge bg-green">{$records_qty}</span>*}
{*</a>*}


{*<ul id="menu1" class="dropdown-menu list-unstyled msg_list" role="menu">*}
{*{foreach item=event from=$events}*}
{*<li>*}
{*<a {$event.view_href}>*}
{*<span class="image">*}
{*<span class="fa fa-{if $event.icon}{$event.icon}{else}home{/if} fa-3x"></span>*}
{*</span>*}
{*<span>*}
{*<span>{$event.category}</span>*}
{*<span class="time">{$event.time}</span>*}
{*</span>*}
{*</a>*}
{*<span class="message">*}
{*{$event.title}*}
{*</span>*}
{*</li>*}
{*{/foreach}*}
{*<li>*}
{*<div class="text-center">*}
{*<a {$href}>*}
{*<strong>{$status}</strong>*}
{*<i class="fa fa-angle-right"></i>*}
{*</a>*}
{*</div>*}
{*</li>*}
{*</ul>*}

<div>{$i.label}</div>
</div>
{$i.label}
</button>
{$i.close}
{/foreach}
</div>


</div>
<div class="nav navbar-nav navbar-right" style="margin-right: 10px">

{foreach item=i from=$launcher_right}
<div class="btn-group btn-group-sm mr-2" role="group" aria-label="Second group">
{foreach item=i from=$icons}
{$i.open}
<div class="btn toggle">
{if $i.icon_url}
<img src="{$i.icon_url}" style="height:2em">
{else}
<i class="fa fa-{$i.icon} fa-2x"></i>
<button class="btn btn-sm btn-secondary" helpID="{$i.helpID}">
{if $i.icon}
<i class="fa fa-{$i.icon} fa-3x"></i>
{/if}
<div>{$i.label}</div>
</div>
{$i.label}
</button>
{$i.close}
{/foreach}

</div>

</div>

<div id="gradient" class="row">
</div>
<div id="nano-bar" class="nano-bar"></div>

</div>

</div>

+ 12
- 0
modules/Base/ActionBar/theme/quickaccess.twig View File

@@ -0,0 +1,12 @@
<div class="dropdown d-none d-md-flex">
<a class="nav-link icon" data-toggle="dropdown">
<i class="fa fa-paper-plane"></i>
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
{% for item in items %}
<a {{ item.href | raw }} title="{{ item.description }}" class="dropdown-item d-flex">
<span class="mr-3 align-self-center"><span class="fa fa-{{ item.icon|default('home') }}"></span></span>{{ item.label }}
</a>
{% endfor %}
</div>
</div>

+ 3
- 3
modules/Base/Admin/theme/default.tpl View File

@@ -1,8 +1,8 @@
<div id="Base_Admin">
{foreach from=$sections key=sk item=s}
<div class="panel panel-default">
<div class="panel-heading" style="clear:both;">{$s.header}</div>
<div class="panel-body btn-toolbar">
<div class="card">
<div class="card-header" style="clear:both;">{$s.header}</div>
<div class="card-body btn-toolbar">
{foreach key=key item=button from=$s.buttons}
<div class="btn btn-default col-xs-4 col-sm-3 col-md-2 col-lg-1">
{$__link.sections.$sk.buttons.$key.link.open}


+ 11
- 12
modules/Base/Box/Box_0.php View File

@@ -28,7 +28,7 @@ class Base_Box extends Module {
}

$theme = $this->pack_module(Base_Theme::module_name());
$ini = Base_BoxCommon::get_ini_file();
$ini = Base_BoxCommon::get_ini_file();

if (!$ini) {
print(__('Unable to read Base/Box/default.ini file! Please create one, or change theme.'));
@@ -150,26 +150,25 @@ class Base_Box extends Module {
$version_no = Base_BoxCommon::update_version_check_indicator();

if (SUGGEST_DONATION)
$theme->assign('donate',Utils_TooltipCommon::create('<a target="_blank" href="http://epe.si/donate/" class="btn btn-warning">'.__('Support EPESI!').'</a>', '<center>'.__('If you find our software useful, please support us by making a %s.', array(__('donation'))).'<br/>'.__('Your funding will help to ensure continued development of this project.').'<br/>'.__('Click for details.').'</center>', false, 500));
$theme->assign('donate',Utils_TooltipCommon::create('<a target="_blank" href="http://epe.si/donate/" class="btn btn-sm btn-outline-warning">'.__('Support EPESI!').'</a>', '<center>'.__('If you find our software useful, please support us by making a %s.', array(__('donation'))).'<br/>'.__('Your funding will help to ensure continued development of this project.').'<br/>'.__('Click for details.').'</center>', false, 500));

// Consider moving this code properly as initated module by *.ini file
$theme->assign('home', array('href'=>Base_HomePageCommon::get_href(), 'label'=>__('Home')));
// Consider moving this code properly as initated module by *.ini file
$theme->assign('home', array('href'=>Base_HomePageCommon::get_href(), 'label'=>__('Home')));

if($this->get_unique_href_variable('logout')) {
Base_User_LoginCommon::logout();
eval_js('document.location=\'index.php\';',false);
}

$menu_tooltips = array(__('Modules menu'),__('User settings'),__('Administrator settings'));
$admin_access = ACL::i_am_admin();
$logo = __('Display logo');

$theme->assign('menu_tooltips',$menu_tooltips);
$theme->assign('admin_access',$admin_access);
$theme->assign('logout_href', $this->create_unique_href(array('logout'=>1)));
$theme->assign('settings_href', Base_BoxCommon::create_href($this,'Base_User_Settings'));
$theme->assign('logo_text',$logo);
$theme->assign('version_no',$version_no);
$theme->assign('indicator', $this->init_module(Base_User_Login::module_name())->indicator());
$theme->assign('watchdog', $this->init_module(Utils_Watchdog::module_name())->indicator());
$theme->assign('filter', $this->init_module(CRM_Filters::module_name())->button());
$theme->assign('quickaccess', $this->init_module(Base_ActionBar::module_name())->quickaccess());
$theme->assign('launchpad_href', $this->init_module(Base_ActionBar::module_name())->launchpad());


$theme->assign('help',Base_MainModuleIndicatorCommon::get_href());
$theme->display();



+ 1
- 8
modules/Base/Box/default.ini View File

@@ -20,14 +20,7 @@ display = "logged"
[moduleindicator]
module = "Base/MainModuleIndicator"
display = "logged"
[filter]
module = "CRM/Filters"
display = "logged"
[logo]
module = "Base/MainModuleIndicator"
function = "logo"
display = "logged"
[watchdog]
module = "Utils/Watchdog"
function = "indicator"
display = "logged"
display = "logged"

+ 0
- 271
modules/Base/Box/theme/default.css View File

@@ -1,271 +0,0 @@
header > div .panel-heading {
min-height: 57px;
}
header > div .panel-body {
min-height: 106px;
}
header > div .panel-heading.vertical-align-middle {
line-height:36px;
}
header .logo-container img {
max-height: 76px;
max-width: 100%;
}
/* Global */

.nonselectable {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}

table {
table-layout: fixed;
}

#content_body {
padding-bottom:20px;
padding-top: 75px;
}

#debug {
width: 90%;
z-index: 99;
padding: 5px;
color: black;
}

#error_box {
width: 90%;
z-index: 99;
padding: 5px;
color: black;
}

pre.wrap {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}

.module_indicator {
margin: 5px 10px 20px;
text-align:center;
}

/* override gentalella defaults */
.top_nav .navbar-right {
width: auto !important;
}

.nav_title {
min-height: 57px;
}

.nav.navbar-nav>li>span>a {
color: #5A738E !important;
}
.navbar-brand, .navbar-nav>li>span>a {
font-weight: 500;
color: #ECF0F1 !important;
margin-left: 0 !important;
line-height: 32px;
}
.nav>li>span>a {
position: relative;
display: block;
padding: 13px 15px 12px;
}
.navbar-nav>li>span>a, .navbar-brand, .navbar-nav>li>span>a {
color: #fff !important;
}
.nav>li>span>a:hover,
.nav>li>span>a:focus {
color: #515356 !important;
}

td span {
line-height: inherit;
}

button, .buttons, .btn, .modal-footer .btn+.btn {
margin-bottom:0px;
}

.nav-sm.nav_title a {
background: #2A3F54;
}

#home-glyph-a {
color: #819ab7;
}

#login-div a:hover {
color: #e1e1e2;
}

#login-div a > span > ul > li:hover {
color: black;
}

#home-glyph-a span:hover {
color: #e1e1e2;
}

.nav_title {
width: 230px;
background: #2A3F54;
z-index:999;
display: block;
clear: both;
}

.nav_title a {
padding: 16px 0 16px 0;
text-align: center;
width: 25%;
font-size: 17px;
display: block;
float: left;
background: #172D44;
cursor: pointer;
}

.sidebar-footer {
max-height: 250px;
background: #172D44;
}

.sidebar-footer a {
background: #172D44;
text-align: center;
width: 100%;
display: block;
float: left;
cursor: pointer;
padding: 1rem;
}

.watchdog {
padding: 0rem 1rem 0 2.3rem;
background: #2A3F54;

}
.watchdog i.fa.fa-bell.fa-2x {
color: #e1e1e2;
}

.watchdog span {
padding-right: 0.5rem;
/*color: #e1e1e2;*/
}

.login {
text-align: center;
padding: 0 1rem 0 1rem;
background: transparent;
}

div.login > span > a > span {
color: #e1e1e2;
}

div.login > span > a > i {
color: black;
}

.nav-sm .container.body .col-md-3.left_col,
.nav-md .container.body .col-md-3.left_col{
position: fixed;
height: 100%;
}

.nav-sm .container.body .left_col.scroll-view #sidebar-menu .menu_section {
margin-bottom: 50px;
}

.left_col.scroll-view {
width: 100%;
height: 100%;
overflow-y: scroll;
padding-top: 1rem;
}
.left_col.scroll-view #sidebar-menu .menu_section {
margin-bottom: 0px;
}
.nav-md .container.body .col-md-3.left_col {
flex-direction: column;
}

.col-md-3.left_col .sidebar-footer {
position: relative;
}

.nav_menu {
opacity: 0.96;
height: 58px;
text-align: center;
}
.top-navigation {
margin-top: 0px;
display: block;
}

.search-bar {
background: #172D44;
}

#hidden-home-div {
display: none;
background: #172D44;
height: 56px;
z-index: 99;
cursor: pointer;
}

div#hidden-home-box:hover a > span {
color: white;
}

#hidden-home-box {
height: 56px;
background: #172D44;
text-align: center;
font-size: 30px;
padding: 10px 0;
}

#hidden-home-gradient {
height: 9px;
width: 100%;
opacity: 0.5;
background: linear-gradient(black,transparent);
}

#left-gradient {
width: 6px;
background: linear-gradient(to right, black, transparent);
height: 100%;
position: fixed;
padding-left: 0;
margin-left: -20px;
z-index: 99;
margin-top: 47px;
opacity: 0.40;
}

div.sidebar-footer.hidden-small:hover {
/*background: #5d7286;*/
z-index: 999999;
}

div.sidebar-footer.hidden-small {
padding: 0;
}

body.nav-md .container.body .right_col {
background: #fbfbfb;
}

+ 6
- 189
modules/Base/Box/theme/default.js View File

@@ -1,190 +1,7 @@
/**
* Resize function without multiple trigger
*
* Usage:
* $(window).smartresize(function(){
* // code here
* });
*/
(function($,sr){
// debouncing function from John Hann
// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
var debounce = function (func, threshold, execAsap) {
var timeout;

return function debounced () {
var obj = this, args = arguments;
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
}

if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);

timeout = setTimeout(delayed, threshold || 100);
};
};

// smartresize
jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };

})(jQuery,'smartresize');

var setContentHeight = function () {
var $BODY = $('body'),
$MENU_TOGGLE = $('#menu_toggle'),
$SIDEBAR_MENU = $('#sidebar-menu'),
$SIDEBAR_FOOTER = $('.sidebar-footer'),
$LEFT_COL = $('.left_col'),
$RIGHT_COL = $('.right_col'),
$NAV_MENU = $('.nav_menu'),
$FOOTER = $('footer');

// reset height
$RIGHT_COL.css('min-height', $(window).height());

var bodyHeight = $BODY.outerHeight(),
footerHeight = $BODY.hasClass('footer_fixed') ? -10 : $FOOTER.height(),
leftColHeight = $LEFT_COL.eq(1).height() + $SIDEBAR_FOOTER.height(),
contentHeight = bodyHeight < leftColHeight ? leftColHeight : bodyHeight;

// normalize content
contentHeight -= $NAV_MENU.height() + footerHeight;

$RIGHT_COL.css('min-height', contentHeight);
};


// recompute content when resizing
$(window).smartresize(function(){
setContentHeight();
});

// fixed sidebar
if ($.fn.mCustomScrollbar) {
$('.menu_fixed').mCustomScrollbar({
autoHideScrollbar: true,
theme: 'minimal',
mouseWheel:{ preventDefault: true }
});
full_screen = function(URL) {
//window.open(URL,"","fullscreen,scrollbars");
var width = screen.width;
var height = screen.height;
win = window.open(URL, 'epesi', 'fullscreen=yes, scrollbars, menubar=no, toolbar=no, location=no, directories=no, resizable=yes, status=no, left=0, top=0, width=' + width + ', height=' + height);
win.focus();
}


$(window).on('e:load',function() {
var $BODY = $('body'),
$MENU_TOGGLE = $('#menu_toggle'),
$SIDEBAR_MENU = $('#sidebar-menu'),
$SIDEBAR_FOOTER = $('.sidebar-footer'),
$LEFT_COL = $('.left_col'),
$RIGHT_COL = $('.right_col'),
$NAV_MENU = $('.nav_menu'),
$FOOTER = $('footer');


var $active_class = $BODY.hasClass('nav-md')?'active':'active-sm';
$SIDEBAR_MENU.find('li.current-page').removeClass('current-page');
$SIDEBAR_MENU.find('li.current-page-next').addClass('current-page').removeClass('current-page-next');

$SIDEBAR_MENU.find('a').off('click').on('click', function(ev) {
var $li = $(this).parent();
if (!$li.is('.active') && !$li.is('.expanded')) {
$SIDEBAR_MENU.find('li.'+$active_class)
.removeClass($active_class)
.removeClass('current-page-next')
.find('ul.child-menu').slideUp()
.parents('ul.child-menu').slideUp();
$li.addClass($active_class)
.addClass('current-page-next')
.addClass('expanded')
.parents('ul').slideDown(function() {
setContentHeight();
})
.parent().addClass($active_class);
$('ul:first', $li).slideDown(function() {
setContentHeight();
});
} else if($li.is('.active.current-page-next')) {
$li.removeClass('active')
.removeClass('current-page-next')
.removeClass('expanded')
.find('ul:first').slideUp();
} else if($li.is('.expanded')) {
$li.removeClass('active')
.removeClass('expanded')
.find('ul:first').slideUp();
}
});

// toggle small or large menu
$MENU_TOGGLE.not('.menu_toggle_active').on('click', function() {

if ($BODY.hasClass('nav-md')) {
$SIDEBAR_MENU.find('li.active ul').hide();
$SIDEBAR_MENU.find('li.active').addClass('active-sm').removeClass('active');

$('.search-bar').hide();
$('#login-box').hide();
$('#login-div').hide();
$('.sidebar-footer.hidden-small').hide();

$('#hidden-home-div').show();
$('#sidebar-menu').css('margin-top','40px');
$('#debug_content').css('padding-left','70px');

} else {
$SIDEBAR_MENU.find('li.active-sm ul').show();
$SIDEBAR_MENU.find('li.active-sm').addClass('active').removeClass('active-sm');

$('.search-bar').show();
$('#login-box').show();
$('#login-div').show();
$('.sidebar-footer.hidden-small').show();

$('#hidden-home-div').hide();
$('#sidebar-menu').css('margin-top','0px');
$('#debug_content').css('padding-left','230px');
}

$BODY.toggleClass('nav-md nav-sm');

setContentHeight();
}).addClass('menu_toggle_active');

setContentHeight();

$('.collapse-link').not('.collapse-link-active').on('click', function() {
var $BOX_PANEL = $(this).closest('.x_panel'),
$ICON = $(this).find('i'),
$BOX_CONTENT = $BOX_PANEL.find('.x_content');

// fix for some div with hardcoded fix class
if ($BOX_PANEL.attr('style')) {
$BOX_CONTENT.slideToggle(200, function(){
$BOX_PANEL.removeAttr('style');
});
} else {
$BOX_CONTENT.slideToggle(200);
$BOX_PANEL.css('height', 'auto');
}

$ICON.toggleClass('fa-chevron-up fa-chevron-down');
}).addClass('collapse-link-active');

$('.close-link').not('.close-link-active').click(function () {
var $BOX_PANEL = $(this).closest('.x_panel');

$BOX_PANEL.remove();
}).addClass('close-link-active');

});

$(document).ready(function () {
$('#debug_content').css('padding-left','240px');
$('#error_box').css('width','100%');
});

+ 63
- 69
modules/Base/Box/theme/default.tpl View File

@@ -4,87 +4,81 @@
<div class="entry">{$login}</div>
</div>
{else}
<div class="col-md-3 left_col">

<div id="hidden-home-div" data-toggle="tooltip" data-placement="bottom" title="{$home.label|escape:html|escape:quotes}" {$home.href}>
<div id="hidden-home-box">
<a id="home-glyph-a" >
<span class="glyphicon glyphicon-home" aria-hidden="true"></span>
</a>
</div>
<div id="hidden-home-gradient"></div>
</div>

<div id="login-div" class="navbar nav_title" style="border: 0">
<a id="login-box" style="width: 75%; max-height: 57px">
{$login}
</a>
<a id="home-glyph-a" data-toggle="tooltip" data-placement="bottom" title="{$home.label|escape:html|escape:quotes}" {$home.href}>
<span class="glyphicon glyphicon-home" aria-hidden="true"></span>
</a>
</div>
<header class="header py-4">
<div class="container-fluid">
<div class="d-flex">
{$logo}
<div class="nav-item d-none d-md-flex"><a class="btn btn-sm btn-secondary" title="{$home.label|escape:html|escape:quotes}" {$home.href}><i class="fa fa-home"></i> {$home.label}</a></div>
<div class="nav-item d-none d-md-flex"><div id="module-indicator">{if $moduleindicator}{$moduleindicator}{else}&nbsp;{/if}</div></div>
<div class="nav-item d-none d-md-flex">{$actionbar}</div>
<div class="d-flex order-lg-2 ml-auto">
<div class="nav-item d-none d-md-flex">
{if isset($donate)}
{$donate}
{/if}
</div>
<div class="nav-item d-none d-md-flex">
<a {$launchpad_href} title="{'Launchpad'|t}" class="nav-link icon">
<i class="fa fa-th"></i>
</a>
</div>
{$watchdog}
{$quickaccess}
{$filter}
{$indicator}
</div>

<div class="search-bar">
{$search}
</div>
</div>

<div class="left_col scroll-view" id="leftside-menu">
<br/>
<!-- sidebar menu -->
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
{$menu}
</header>
<header class="header collapse d-lg-flex p-0" id="headerMenuCollapse">
<div class="container-fluid">
<div class="row align-items-center">
<div class="col-lg-2 ml-auto">
{$search}
</div>
<div class="col-lg order-lg-first">
{$menu}
</div>
</div>
</div>
</header>

<div class="sidebar-footer hidden-small" data-toggle="tooltip" data-placement="top" title="Soft-refresh">
{$logo}
<!-- -->
<div id="content" class="my-3 my-md-5">
<div id="content_body" class="container-fluid">
{$main}
</div>
</div>


<!-- top navigation -->
<div class="top_nav navbar-fixed-top">

<div class="nav_menu" style="padding-top: 0; margin-top: 0">
<nav class="top-navigation">
<div class="nav toggle">
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
<footer class="footer">
<div class="container-fluid">
<div class="row align-items-center flex-row-reverse">
<div class="col-auto ml-lg-auto">
<div class="row align-items-center">
<div class="col-auto">
<ul class="list-inline list-inline-dots mb-0">
<li class="list-inline-item"><a href="https://forum.epesibim.com/">Forum</a></li>
<li class="list-inline-item"><a href="http://epe.si/support/">Support</a></li>
</ul>
</div>
<div class="col-auto">
{if isset($donate)}
<span style="float: right; margin-right: 30px">{$donate}</span>
{/if}
</div>
<div class="col-auto">
<a href="https://github.com/Telaxus/EPESI" class="btn btn-outline-primary btn-sm">Source code</a>
</div>
</div>
</div>
<div class="col-12 col-lg-auto mt-3 mt-lg-0 text-center">
<a href="http://epe.si" target="_blank"><b>EPESI</b> powered</a> {$version_no}
</div>

<ul class="nav navbar-nav navbar-right">

</ul>

{$actionbar}

</nav>
</div>
</div>
<!-- /top navigation -->


<div class="right_col" role="main">
<div id="left-gradient" style=""> </div>
<!-- -->
<div id="content">
<div id="content_body" style="padding-top: 70px">
{$main}
</div>
</div>
</div>

{*<footer>*}
{*<div class="pull-left">*}
{*<a href="http://epe.si" target="_blank"><b>EPESI</b> powered</a>*}
{*</div>*}
{*<div class="pull-right">*}
{*<span style="float: right">{$version_no}</span>*}
{*{if isset($donate)}*}
{*<span style="float: right; margin-right: 30px">{$donate}</span>*}
{*{/if}*}
{*</div>*}
{*<div class="clearfix"></div>*}
{*</footer>*}
</footer>

{$status}



+ 0
- 2
modules/Base/Dashboard/Dashboard_0.php View File

@@ -16,7 +16,6 @@ class Base_Dashboard extends Module {

public function construct() {
$this->tb = $this->init_module(Utils_TabbedBrowser::module_name());
on_init(array('Base_ActionBarCommon', 'show_quick_access_shortcuts'), array(false));
}

public function body() {
@@ -27,7 +26,6 @@ class Base_Dashboard extends Module {
if(Utils_RecordBrowserCommon::check_for_jump()) return;

$this->dashboard();
Base_ActionBarCommon::show_quick_access_shortcuts(true);
}

private function dashboard() {


+ 0
- 4
modules/Base/Dashboard/ab.js View File

@@ -128,7 +128,3 @@ dashboard_filter_applets = function() {
if(node.attr('searchkey').indexOf(str)!=-1) node.show(); else node.hide();
});
}

$(document).on('click','.applet-actions-icon',function(){
$(this).parent().find('.applet-actions').toggle('slow');
});

+ 11
- 5
modules/Base/Dashboard/theme/default.css View File

@@ -3,9 +3,15 @@
width:auto;
float:none;
}
.pull-right.action-buttons .applet-actions-icon {
position: relative;
}
.pull-right.action-buttons .applet-actions {
display: none;

.card-options-left {
margin-left: inherit;
/*display: -ms-flexbox;*/
/*display: flex;*/
/*-ms-flex-order: 100;*/
/*order: 100;*/
margin-right: -.5rem;
/*color: #9aa0ac;*/
/*-ms-flex-item-align: center;*/
/*align-self: center;*/
}

+ 29
- 32
modules/Base/Dashboard/theme/default.tpl View File

@@ -1,45 +1,42 @@
<div class="panel panel-default">
<div class="handle panel-heading clearfix">
<span class="panel-title">{$caption}</span>
<div class="card">
<div class="handle card-header">

{if !empty($actions)}
<div class="pull-left action-buttons">
<div class="card-options card-options-left">
{foreach item=action from=$actions}
{$action}
{/foreach}
</div>
{/if}

<div class="pull-right action-buttons">
<button type="button" class="btn btn-default dropdown-toggle btn-xs applet-actions-icon" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="border-radius: 65px">
<span class="glyphicon glyphicon-option-vertical"></span>
</button>
<div class="pull-right applet-actions">
{if isset($href)}
{$__link.href.open}
<button class="btn btn-success btn-xs"><i class="fa fa-arrows-alt"></i></button>
{$__link.href.close}
{/if}
{if isset($toggle)}
{$__link.toggle.open}
<button class="btn btn-info btn-xs"><i class="fa fa-caret-square-o-down"></i></button>
{$__link.toggle.close}
{/if}
{if isset($configure)}
{$__link.configure.open}
<button class="btn btn-warning btn-xs"><i class="fa fa-cog"></i></button>
{$__link.configure.close}
{/if}
{if isset($remove)}
{$__link.remove.open}
<button class="btn btn-danger btn-xs"><i class="fa fa-times"></i></button>
{$__link.remove.close}
{/if}
</div>
<h3 class="card-title">{$caption}</h3>

<div class="card-options">
{if isset($href)}
{$__link.href.open}
<span class="card-options-fullscreen"><i class="fa fa-arrows-alt"></i></span>
{$__link.href.close}
{/if}
{if isset($toggle)}
{$__link.toggle.open}
<span class="card-options-collapse"><i class="fa fa-caret-square-o-down"></i></span>
{$__link.toggle.close}
{/if}
{if isset($configure)}
{$__link.configure.open}
<span class="card-options-collapse"><i class="fa fa-cog"></i></span>
{$__link.configure.close}
{/if}
{if isset($remove)}
{$__link.remove.open}
<span class="card-options-remove"><i class="fa fa-times"></i></span>
{$__link.remove.close}
{/if}
</div>

</div>
<div class="panel-body">
<div class="card-body">
{$content}
</div>
</div>
</div>

+ 2
- 2
modules/Base/Lang/LangCommon_0.php View File

@@ -68,8 +68,8 @@ class Base_LangCommon extends ModuleCommon {
$html = <<<HTML
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2 clearfix">
<a $href>
<div class="panel panel-default clearfix">
<div class="panel-heading" title="$label">
<div class="card clearfix">
<div class="card-header" title="$label">
{$label}
</div>
<img style="width: 100%" src="{$file}" alt="{$code}"/>


+ 3
- 1
modules/Base/MainModuleIndicator/theme/logo.tpl View File

@@ -1 +1,3 @@
<a id="company-logo-a" href="#" style="height: 100%"><img src="{if $logo}{$logo}{else}images/epesi_logo_RGB_Solid_main.png{/if}" alt="logo" class="img-responsive center-block"></a>
<a class="header-brand" href="#">
<img src="{if $logo}{$logo}{else}images/epesi_logo_RGB_Solid.png{/if}" class="header-brand-img" alt="company-logo">
</a>

+ 4
- 0
modules/Base/Menu/Menu_0.php View File

@@ -113,6 +113,10 @@ class Base_Menu extends Module {

Base_MenuCommon::generate_urls($this, $modules_menu);

load_js($this->get_module_dir().'/libs/jquery.smartmenus.min.js');
load_js($this->get_module_dir().'/libs/jquery.smartmenus.bootstrap.min.js');
load_css($this->get_module_dir().'/libs/jquery.smartmenus.bootstrap.css');

return $this->twig_display('default.twig', array(
'menu' => Base_MenuCommon::build_menu($modules_menu),
'name' => __('Menu')


+ 22
- 0
modules/Base/Menu/libs/LICENSE-MIT View File

@@ -0,0 +1,22 @@
Copyright (c) Vasil Dinkov, Vadikom Web Ltd.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

+ 122
- 0
modules/Base/Menu/libs/jquery.smartmenus.bootstrap.css View File

@@ -0,0 +1,122 @@
/*
You probably do not need to edit this at all.

Add some SmartMenus required styles not covered in Bootstrap 3's default CSS.
These are theme independent and should work with any Bootstrap 3 theme mod.
*/
/* sub menus arrows on desktop */
.navbar-nav:not(.sm-collapsible) ul .caret {
position: absolute;
right: 0;
margin-top: 6px;
margin-right: 15px;
border-top: 4px solid transparent;
border-bottom: 4px solid transparent;
border-left: 4px dashed;
}
.navbar-nav:not(.sm-collapsible) ul a.has-submenu {
padding-right: 30px;
}
/* make sub menu arrows look like +/- buttons in collapsible mode */
.navbar-nav.sm-collapsible .caret, .navbar-nav.sm-collapsible ul .caret {
position: absolute;
right: 0;
margin: -3px 15px 0 0;
padding: 0;
width: 32px;
height: 26px;
line-height: 24px;
text-align: center;
border-width: 1px;
border-style: solid;
}
.navbar-nav.sm-collapsible .caret:before {
content: '+';
font-family: monospace;
font-weight: bold;
}
.navbar-nav.sm-collapsible .open > a > .caret:before {
content: '-';
}
.navbar-nav.sm-collapsible a.has-submenu {
padding-right: 50px;
}
/* revert to Bootstrap's default carets in collapsible mode when the "data-sm-skip-collapsible-behavior" attribute is set to the ul.navbar-nav */
.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] .caret, .navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] ul .caret {
position: static;
margin: 0 0 0 2px;
padding: 0;
width: 0;
height: 0;
border-top: 4px dashed;
border-right: 4px solid transparent;
border-bottom: 0;
border-left: 4px solid transparent;
}
.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] .caret:before {
content: '' !important;
}
.navbar-nav.sm-collapsible[data-sm-skip-collapsible-behavior] a.has-submenu {
padding-right: 15px;
}
/* scrolling arrows for tall menus */
.navbar-nav span.scroll-up, .navbar-nav span.scroll-down {
position: absolute;
display: none;
visibility: hidden;
height: 20px;
overflow: hidden;
text-align: center;
}
.navbar-nav span.scroll-up-arrow, .navbar-nav span.scroll-down-arrow {
position: absolute;
top: -2px;
left: 50%;
margin-left: -8px;
width: 0;
height: 0;
overflow: hidden;
border-top: 7px dashed transparent;
border-right: 7px dashed transparent;
border-bottom: 7px solid;
border-left: 7px dashed transparent;
}
.navbar-nav span.scroll-down-arrow {
top: 6px;
border-top: 7px solid;
border-right: 7px dashed transparent;
border-bottom: 7px dashed transparent;
border-left: 7px dashed transparent;
}
/* add more indentation for 2+ level sub in collapsible mode - Bootstrap normally supports just 1 level sub menus */
.navbar-nav.sm-collapsible ul .dropdown-menu > li > a,
.navbar-nav.sm-collapsible ul .dropdown-menu .dropdown-header {
padding-left: 35px;
}
.navbar-nav.sm-collapsible ul ul .dropdown-menu > li > a,
.navbar-nav.sm-collapsible ul ul .dropdown-menu .dropdown-header {
padding-left: 45px;
}
.navbar-nav.sm-collapsible ul ul ul .dropdown-menu > li > a,
.navbar-nav.sm-collapsible ul ul ul .dropdown-menu .dropdown-header {
padding-left: 55px;
}
.navbar-nav.sm-collapsible ul ul ul ul .dropdown-menu > li > a,
.navbar-nav.sm-collapsible ul ul ul ul .dropdown-menu .dropdown-header {
padding-left: 65px;
}
/* fix SmartMenus sub menus auto width (subMenusMinWidth and subMenusMaxWidth options) */
.navbar-nav .dropdown-menu > li > a {
white-space: normal;
}
.navbar-nav ul.sm-nowrap > li > a {
white-space: nowrap;
}
.navbar-nav.sm-collapsible ul.sm-nowrap > li > a {
white-space: normal;
}
/* fix .navbar-right subs alignment */
.navbar-right ul.dropdown-menu {
left: 0;
right: auto;
}

+ 174
- 0
modules/Base/Menu/libs/jquery.smartmenus.bootstrap.js View File

@@ -0,0 +1,174 @@
/*!
* SmartMenus jQuery Plugin Bootstrap Addon - v0.3.1 - November 1, 2016
* http://www.smartmenus.org/
*
* Copyright Vasil Dinkov, Vadikom Web Ltd.
* http://vadikom.com
*
* Licensed MIT
*/

(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery', 'jquery.smartmenus'], factory);
} else if (typeof module === 'object' && typeof module.exports === 'object') {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// Global jQuery
factory(jQuery);
}
} (function($) {

$.extend($.SmartMenus.Bootstrap = {}, {
keydownFix: false,
init: function() {
// init all navbars that don't have the "data-sm-skip" attribute set
var $navbars = $('ul.navbar-nav:not([data-sm-skip])');
$navbars.each(function() {
var $this = $(this),
obj = $this.data('smartmenus');
// if this navbar is not initialized
if (!obj) {
$this.smartmenus({

// these are some good default options that should work for all
// you can, of course, tweak these as you like
subMenusSubOffsetX: 2,
subMenusSubOffsetY: -6,
subIndicators: false,
collapsibleShowFunction: null,
collapsibleHideFunction: null,
rightToLeftSubMenus: $this.hasClass('navbar-right'),
bottomToTopSubMenus: $this.closest('.navbar').hasClass('navbar-fixed-bottom')
})
.bind({
// set/unset proper Bootstrap classes for some menu elements
'show.smapi': function(e, menu) {
var $menu = $(menu),
$scrollArrows = $menu.dataSM('scroll-arrows');
if ($scrollArrows) {
// they inherit border-color from body, so we can use its background-color too
$scrollArrows.css('background-color', $(document.body).css('background-color'));
}
$menu.parent().addClass('open');
},
'hide.smapi': function(e, menu) {
$(menu).parent().removeClass('open');
}
});

function onInit() {
// set Bootstrap's "active" class to SmartMenus "current" items (should someone decide to enable markCurrentItem: true)
$this.find('a.current').parent().addClass('active');
// remove any Bootstrap required attributes that might cause conflicting issues with the SmartMenus script
$this.find('a.has-submenu').each(function() {
var $this = $(this);
if ($this.is('[data-toggle="dropdown"]')) {
$this.dataSM('bs-data-toggle-dropdown', true).removeAttr('data-toggle');
}
if ($this.is('[role="button"]')) {
$this.dataSM('bs-role-button', true).removeAttr('role');
}
});
}

onInit();

function onBeforeDestroy() {
$this.find('a.current').parent().removeClass('active');
$this.find('a.has-submenu').each(function() {
var $this = $(this);
if ($this.dataSM('bs-data-toggle-dropdown')) {
$this.attr('data-toggle', 'dropdown').removeDataSM('bs-data-toggle-dropdown');
}
if ($this.dataSM('bs-role-button')) {
$this.attr('role', 'button').removeDataSM('bs-role-button');
}
});
}

obj = $this.data('smartmenus');

// custom "isCollapsible" method for Bootstrap
obj.isCollapsible = function() {
return !/^(left|right)$/.test(this.$firstLink.parent().css('float'));
};

// custom "refresh" method for Bootstrap
obj.refresh = function() {
$.SmartMenus.prototype.refresh.call(this);
onInit();
// update collapsible detection
detectCollapsible(true);
};

// custom "destroy" method for Bootstrap
obj.destroy = function(refresh) {
onBeforeDestroy();
$.SmartMenus.prototype.destroy.call(this, refresh);
};

// keep Bootstrap's default behavior for parent items when the "data-sm-skip-collapsible-behavior" attribute is set to the ul.navbar-nav
// i.e. use the whole item area just as a sub menu toggle and don't customize the carets
if ($this.is('[data-sm-skip-collapsible-behavior]')) {
$this.bind({
// click the parent item to toggle the sub menus (and reset deeper levels and other branches on click)
'click.smapi': function(e, item) {
if (obj.isCollapsible()) {
var $item = $(item),
$sub = $item.parent().dataSM('sub');
if ($sub && $sub.dataSM('shown-before') && $sub.is(':visible')) {
obj.itemActivate($item);
obj.menuHide($sub);
return false;
}
}
}
});
}

// onresize detect when the navbar becomes collapsible and add it the "sm-collapsible" class
var winW;
function detectCollapsible(force) {
var newW = obj.getViewportWidth();
if (newW != winW || force) {
var $carets = $this.find('.caret');
if (obj.isCollapsible()) {
$this.addClass('sm-collapsible');
// set "navbar-toggle" class to carets (so they look like a button) if the "data-sm-skip-collapsible-behavior" attribute is not set to the ul.navbar-nav
if (!$this.is('[data-sm-skip-collapsible-behavior]')) {
$carets.addClass('navbar-toggle sub-arrow');
}
} else {
$this.removeClass('sm-collapsible');
if (!$this.is('[data-sm-skip-collapsible-behavior]')) {
$carets.removeClass('navbar-toggle sub-arrow');
}
}
winW = newW;
}
}
detectCollapsible();
$(window).bind('resize.smartmenus' + obj.rootId, detectCollapsible);
}
});
// keydown fix for Bootstrap 3.3.5+ conflict
if ($navbars.length && !$.SmartMenus.Bootstrap.keydownFix) {
// unhook BS keydown handler for all dropdowns
$(document).off('keydown.bs.dropdown.data-api', '.dropdown-menu');
// restore BS keydown handler for dropdowns that are not inside SmartMenus navbars
if ($.fn.dropdown && $.fn.dropdown.Constructor) {
$(document).on('keydown.bs.dropdown.data-api', '.dropdown-menu:not([id^="sm-"])', $.fn.dropdown.Constructor.prototype.keydown);
}
$.SmartMenus.Bootstrap.keydownFix = true;
}
}
});

// init ondomready
$($.SmartMenus.Bootstrap.init);

return $;
}));

+ 3
- 0
modules/Base/Menu/libs/jquery.smartmenus.bootstrap.min.js View File

@@ -0,0 +1,3 @@
/*! SmartMenus jQuery Plugin Bootstrap Addon - v0.3.1 - November 1, 2016
* http://www.smartmenus.org/
* Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery","jquery.smartmenus"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function(t){return t.extend(t.SmartMenus.Bootstrap={},{keydownFix:!1,init:function(){var e=t("ul.navbar-nav:not([data-sm-skip])");e.each(function(){function e(){o.find("a.current").parent().addClass("active"),o.find("a.has-submenu").each(function(){var e=t(this);e.is('[data-toggle="dropdown"]')&&e.dataSM("bs-data-toggle-dropdown",!0).removeAttr("data-toggle"),e.is('[role="button"]')&&e.dataSM("bs-role-button",!0).removeAttr("role")})}function s(){o.find("a.current").parent().removeClass("active"),o.find("a.has-submenu").each(function(){var e=t(this);e.dataSM("bs-data-toggle-dropdown")&&e.attr("data-toggle","dropdown").removeDataSM("bs-data-toggle-dropdown"),e.dataSM("bs-role-button")&&e.attr("role","button").removeDataSM("bs-role-button")})}function i(t){var e=a.getViewportWidth();if(e!=n||t){var s=o.find(".caret");a.isCollapsible()?(o.addClass("sm-collapsible"),o.is("[data-sm-skip-collapsible-behavior]")||s.addClass("navbar-toggle sub-arrow")):(o.removeClass("sm-collapsible"),o.is("[data-sm-skip-collapsible-behavior]")||s.removeClass("navbar-toggle sub-arrow")),n=e}}var o=t(this),a=o.data("smartmenus");if(!a){o.smartmenus({subMenusSubOffsetX:2,subMenusSubOffsetY:-6,subIndicators:!1,collapsibleShowFunction:null,collapsibleHideFunction:null,rightToLeftSubMenus:o.hasClass("navbar-right"),bottomToTopSubMenus:o.closest(".navbar").hasClass("navbar-fixed-bottom")}).bind({"show.smapi":function(e,s){var i=t(s),o=i.dataSM("scroll-arrows");o&&o.css("background-color",t(document.body).css("background-color")),i.parent().addClass("open")},"hide.smapi":function(e,s){t(s).parent().removeClass("open")}}),e(),a=o.data("smartmenus"),a.isCollapsible=function(){return!/^(left|right)$/.test(this.$firstLink.parent().css("float"))},a.refresh=function(){t.SmartMenus.prototype.refresh.call(this),e(),i(!0)},a.destroy=function(e){s(),t.SmartMenus.prototype.destroy.call(this,e)},o.is("[data-sm-skip-collapsible-behavior]")&&o.bind({"click.smapi":function(e,s){if(a.isCollapsible()){var i=t(s),o=i.parent().dataSM("sub");if(o&&o.dataSM("shown-before")&&o.is(":visible"))return a.itemActivate(i),a.menuHide(o),!1}}});var n;i(),t(window).bind("resize.smartmenus"+a.rootId,i)}}),e.length&&!t.SmartMenus.Bootstrap.keydownFix&&(t(document).off("keydown.bs.dropdown.data-api",".dropdown-menu"),t.fn.dropdown&&t.fn.dropdown.Constructor&&t(document).on("keydown.bs.dropdown.data-api",'.dropdown-menu:not([id^="sm-"])',t.fn.dropdown.Constructor.prototype.keydown),t.SmartMenus.Bootstrap.keydownFix=!0)}}),t(t.SmartMenus.Bootstrap.init),t});

+ 1223
- 0
modules/Base/Menu/libs/jquery.smartmenus.js
File diff suppressed because it is too large
View File


+ 3
- 0
modules/Base/Menu/libs/jquery.smartmenus.min.js
File diff suppressed because it is too large
View File


+ 31
- 20
modules/Base/Menu/theme/default.twig View File

@@ -1,34 +1,45 @@
{% macro menu_links(links,level) %}
<ul class="nav {% if level==0 %}side-{% else %}child_{% endif %}menu" {% if level>0 %}style="display:none"{% endif %}>
{#<li class="nav-item dropdown">#}
{#<a href="javascript:void(0)" class="nav-link" data-toggle="dropdown"><i class="fe fe-calendar"></i> Components</a>#}
{#<div class="dropdown-menu dropdown-menu-arrow">#}
{#<a href="./maps.html" class="dropdown-item ">Maps</a>#}
{#<a href="./icons.html" class="dropdown-item ">Icons</a>#}
{#<a href="./store.html" class="dropdown-item ">Store</a>#}
{#<a href="./blog.html" class="dropdown-item ">Blog</a>#}
{#<a href="./carousel.html" class="dropdown-item ">Carousel</a>#}
{#</div>#}
{#</li>#}

{% macro menu_links(links, level) %}
{% for link in links %}
{% if link.type == 'split' %}
<li class="divider"></li>
<li class="divider"></li>
{% elseif link.type == 'submenu' %}
<li>
{% if link.icon is not null %}
<a tabindex="-1" href="javascript:void(0);"><i class="fa fa-{{ link.icon }}"></i>&nbsp;{{ link.label }} <span class="caret"></span></a>
{% else %}
<a tabindex="-1" href="javascript:void(0);">{{ link.label }} <span class="caret"></span></a>
{% endif %}

{{ _self.menu_links(link.items,level+1) }}
<li class="nav-item dropdown">
<a href="javascript:void(0)" class="nav-link" data-toggle="dropdown">{% if link.icon is not null %}<i
class="fa fa-{{ link.icon }}"></i>{% endif %}{{ link.label }}</a>
<div class="dropdown-menu dropdown-menu-arrow">
{{ _self.menu_links(link.items, level+1) }}
</div>
</li>
{% elseif link.type == 'item' %}
{% if link.icon is not null %}
<li><a href="{{ link.url }}"><i class="fa fa-{{ link.icon }}"></i>&nbsp;{{ link.label }}</a></li>
{% if level == 0 %}
<li class="nav-item">
<a href="{{ link.url }}" class="nav-link">{% if link.icon is not null %}<i class="fa fa-{{ link.icon }}"></i>{% endif %} {{ link.label }}</a>
</li>
{% else %}
<li><a href="{{ link.url }}">{{ link.label }}</a></li>
<a href="{{ link.url }}" class="dropdown-item ">{% if link.icon is not null %}<i class="fa fa-{{ link.icon }}"></i>{% endif %} {{ link.label }}</a>
{% endif %}
{% endif %}

{% endfor %}
</ul>
{% endmacro %}

{% import _self as macros %}
{% import _self as macros %}

<ul class="nav nav-tabs border-0 flex-column flex-lg-row">
{{ macros.menu_links(menu, 0) }}
</ul>

<div class="menu_section">
<h3>{{ name }}</h3>
{{ macros.menu_links(menu,0) }}
</div>
{#<a role="navigation" class="btn btn-primary" style="padding: 6px 12px;background-color:#337ab7">#}
{#{{ name }}&nbsp;<span class="caret hidden-xs"></span>#}
{#</a>#}

+ 9
- 3
modules/Base/Search/theme/Search.tpl View File

@@ -5,10 +5,16 @@
<!-- Display the fields -->
<div class="input-group" id="search_panel">
{$form_data.quick_search.html}
<span class="input-group-btn">
<button class="btn btn-success" type="button" {$submit_href}><span class="hidden-xs">{$submit_label}&nbsp;</span><i class="glyphicon glyphicon-search"></i></button>
</span>
<span class="input-group-append">
<button class="btn btn-success" type="button" {$submit_href}><span class="hidden-xs">{$submit_label}&nbsp;</span><i class="fa fa-search"></i></button>
</span>
</div>
{*<div class="input-group" >*}
{*{$form_data.quick_search.html}*}
{*<span class="input-group-btn">*}
{*<button class="btn btn-success" type="button" {$submit_href}><span class="hidden-xs">{$submit_label}&nbsp;</span><i class="fa fa-search"></i></button>*}
{*</span>*}
{*</div>*}
</form>
{else}
{$form_data.javascript}


+ 68
- 32
modules/Base/User/Login/Login_0.php View File

@@ -17,16 +17,24 @@ class Base_User_Login extends Module {
public $theme;

public function construct() {
$this->theme = $this->pack_module(Base_Theme::module_name());
$this->theme = $this->pack_module(Base_Theme::module_name());

$logo = $this->init_module(Base_MainModuleIndicator::module_name());
$logo->set_inline_display();
$this->theme->assign('logo', $this->get_html_of_module($logo,null,'login_logo'));
$this->theme->assign('is_logged_in', Acl::is_user());
$this->theme->assign('is_demo', DEMO_MODE);
if (SUGGEST_DONATION) {
$this->theme->assign('donation_note', __('If you find our software useful, please support us by making a %s.', array('<a href="http://epe.si/cost" target="_blank">'.__('donation').'</a>')).'<br>'.__('Your funding will help to ensure continued development of this project.'));
}
$this->theme->assign('is_logged_in', Acl::is_user());
$this->theme->assign('is_demo', DEMO_MODE);
$this->theme->assign('epesi_url', get_epesi_url());
if (SUGGEST_DONATION) {
$this->theme->assign('donation_note', __('If you find our software useful, please support us by making a %s.', array('<a href="http://epe.si/donate/" target="_blank">'.__('donation').'</a>')).' '.__('Your funding will help to ensure continued development of this project.'));
}

if(Acl::is_user()) {
if ($this->get_unique_href_variable('logout')) {
Base_User_LoginCommon::logout();
eval_js('document.location=\'index.php\';', false);
}
}
}

private function autologin() {
@@ -37,6 +45,39 @@ class Base_User_Login extends Module {
return false;
}

public function indicator()
{
//todo-pj: Add profile link
return $this->twig_render('indicator.twig', array(
'indicator' => array(
'label' => Base_UserCommon::get_my_user_label(1),
'login' => Base_UserCommon::get_my_user_login()
),
'logout' => array(
'href' => $this->create_unique_href(array('logout'=>1)),
'text' => __('Logout')
),
'contact' => [
'href' => Base_BoxCommon::create_href($this,'CRM_Contacts','body',array('my_contact')),
'label' => _('My Contact')
],
'company' => [
'href' => Base_BoxCommon::create_href($this,'CRM_Contacts','body',array('main_company')),
'label' => _('Main Company')
],
'settings' => [
'href' => Base_BoxCommon::create_href($this,'Base_User_Settings'),
'label' => _('User Settings')
],
'help' => [
'href' => Base_MainModuleIndicatorCommon::get_href(),
'label' => _('Help')
]
)
);

}

public function body($tpl=null) {
//check bans
if (!Acl::is_user() && Base_User_LoginCommon::is_banned()) {
@@ -50,14 +91,9 @@ class Base_User_Login extends Module {
Base_User_LoginCommon::logout();
eval_js('document.location=\'index.php\';',false);
} else {
$this->theme->assign('logged_as', Base_UserCommon::get_my_user_label(1));
if(ModuleManager::is_installed('CRM_Contacts')>=0) {
$this->theme->assign('my_contact_href', Base_BoxCommon::create_href($this,'CRM_Contacts','body',array('my_contact')));
if(CRM_ContactsCommon::get_main_company())
$this->theme->assign('main_company_href', Base_BoxCommon::create_href($this,'CRM_Contacts','body',array('main_company')));
}
$this->theme->assign('logged_as', '<div class="pull-left">'.__('Logged as %s',array('</br><b class="green">'.Base_UserCommon::get_my_user_login().'</b>')).'</div>');
$this->theme->assign('logout_href', $this->create_unique_href(array('logout'=>1)));
$this->theme->assign('settings_href', Base_BoxCommon::create_href($this,'Base_User_Settings'));
$this->theme->assign('logout_label',__('Logout'));
$this->theme->display();
}
return;
@@ -82,7 +118,7 @@ class Base_User_Login extends Module {
//else just login form
$form = $this->init_module(Libs_QuickForm::module_name(),__('Logging in'));
$form->addElement('header', 'login_header', __('Login'));
if(DEMO_MODE) {
global $demo_users;
$form->addElement('select', 'username', __('Username'), $demo_users, array('class'=>'form-control', 'id'=>'username', 'onChange'=>'this.form.elements["password"].value=this.options[this.selectedIndex].value;'));
@@ -93,19 +129,19 @@ class Base_User_Login extends Module {
}

// Display warning about storing a cookie
if (Base_User_LoginCommon::is_autologin_forbidden() == false) {
$warning=__('Keep this box unchecked if using a public computer');
$form->addElement('static','warning',null,$warning);
$form->addElement('checkbox', 'autologin', '',__('Remember me'));
}
if (Base_User_LoginCommon::is_autologin_forbidden() == false) {
$warning=__('Keep this box unchecked if using a public computer');
$form->addElement('static','warning',null,$warning);
$form->addElement('checkbox', 'autologin', '',__('Remember me'));
}

$form->addElement('static', 'recover_password', null, '<a '.$this->create_unique_href(array('mail_recover_pass'=>1)).'>'.__('Recover password').'</a>');
$form->addElement('submit', 'submit_button', __('Login'), array('class'=>'btn btn-primary btn-block'));

// register and add a rule to check if user is banned
$form->registerRule('check_user_banned', 'callback', 'rule_login_banned', 'Base_User_LoginCommon');
$form->addRule('username', __('You have exceeded the number of allowed login attempts for this username. Try again later.'), 'check_user_banned');
// register and add a rule to check if user is banned
$form->registerRule('check_user_banned', 'callback', 'rule_login_banned', 'Base_User_LoginCommon');
$form->addRule('username', __('You have exceeded the number of allowed login attempts for this username. Try again later.'), 'check_user_banned');
// register and add a rule to check if a username and password is ok
$form->registerRule('check_login', 'callback', 'submit_login', 'Base_User_LoginCommon');
$form->addRule(array('username','password'), __('Login or password incorrect'), 'check_login');
@@ -115,13 +151,13 @@ class Base_User_Login extends Module {

if($form->isSubmitted() && $form->validate()) {
$user = $form->exportValue('username');
Base_User_LoginCommon::set_logged($user);
Base_User_LoginCommon::set_logged($user);

if (Base_User_LoginCommon::is_autologin_forbidden() == false) {
$autologin = $form->exportValue('autologin');
if($autologin)
Base_User_LoginCommon::new_autologin_id();
}
if (Base_User_LoginCommon::is_autologin_forbidden() == false) {
$autologin = $form->exportValue('autologin');
if($autologin)
Base_User_LoginCommon::new_autologin_id();
}

location(array());
} else {
@@ -196,20 +232,20 @@ class Base_User_Login extends Module {
$username = $data['username'];

if(DEMO_MODE && $username=='admin') {
print('In demo you cannot recover \'admin\' user password. If you want to login please type \'admin\' as password.');
print('In demo you cannot recover \'admin\' user password. If you want to login please type \'admin\' as password.');
return false;
}

$user_id = Base_UserCommon::get_user_id($username);
DB::Execute('DELETE FROM user_reset_pass WHERE created_on<%T',array(time()-3600*2));
if($user_id===false) {
print('No such user!');
return false;
}
$hash = md5($user_id.''.openssl_random_pseudo_bytes(100));
DB::Execute('INSERT INTO user_reset_pass(user_login_id,hash_id,created_on) VALUES (%d,%s,%T)',array($user_id, $hash,time()));
$subject = __('Password recovery');
$message = __('A password recovery for the account with the e-mail address %s has been requested.',array($mail))."\n\n".
__('If you want to reset your password, visit the following URL:')."\n".


+ 1
- 86
modules/Base/User/Login/theme/default.css View File

@@ -5,89 +5,4 @@
#login-screen p {
margin-top: 0.75em;
text-align: center;
}

.top_nav .navbar-nav .user-profile {
padding: 10px 10px;
display:block;
}

.top_nav .navbar-nav .user-profile .fa-user {
vertical-align: middle;
margin-right:5px;
}

/* user container settings */

#user-container-a {
padding: 0;
width: 100%;
}

#user-container-a div:hover {
color: #e1e1e2;
}

#user-container {
padding: 0;
margin: 0;
max-height: 57px;
}

#user-row {
padding: 0;
margin: 0;
display: flex;
color: #819ab7;
}

#user-div {
width: 15%;
}

#user {
font-size: 20px;
text-align: center;
margin-left: 5px;
}

#logged-as-div {
width: 70%
}

.logged-as {
font-size: 11px; padding: 0; margin: 0
}

#arrow-div {
width: 15%
}

#arrow {
font-size: 10px;
padding: 0;
margin: 0;