mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-17 06:18:44 +02:00
N°2847 Add silo selector to navigation menu
This commit is contained in:
@@ -31,7 +31,17 @@ $ibo-navigation-menu--top-part--padding-y: $ibo-navigation-menu--body--padding-y
|
||||
$ibo-navigation-menu--top-part--padding-x: $ibo-navigation-menu--body--padding-x !default;
|
||||
$ibo-navigation-menu--top-part--elements-spacing: 20px !default;
|
||||
|
||||
$ibo-navigation-menu--middle-part--padding-top: 40px !default;
|
||||
$ibo-navigation-menu--silo-selection--width: 70% !default;
|
||||
$ibo-navigation-menu--silo-selection--margin-left: 15px !default;
|
||||
$ibo-navigation-menu--silo-selection--input--action-button--hierarchy--padding-right: -42px !default;
|
||||
$ibo-navigation-menu--silo-selection--input--padding-right: 38px !default;
|
||||
$ibo-navigation-menu--silo-selection--input--data-value--padding: 5px !default;
|
||||
$ibo-navigation-menu--silo-selection--input-select--action-button--hierarchy--margin-left: -42px !default;
|
||||
$ibo-navigation-menu--silo-selection--input-select-autocomplete--padding-left: 60px !default;
|
||||
$ibo-navigation-menu--silo-selection--input-select-autocomplete--action-button--search--margin-left: -42px !default;
|
||||
$ibo-navigation-menu--silo-selection--input-select-autocomplete--action-button--hierarchy--margin-left: -60px !default;
|
||||
|
||||
$ibo-navigation-menu--middle-part--padding-top: 24px !default;
|
||||
$ibo-navigation-menu--middle-part--padding-bottom: 16px !default;
|
||||
$ibo-navigation-menu--middle-part--padding-x: $ibo-navigation-menu--body--padding-x !default;
|
||||
$ibo-navigation-menu--middle-part--elements-spacing: 20px !default;
|
||||
@@ -183,6 +193,9 @@ $ibo-navigation-menu--menu-counter-color: $ibo-navigation-menu--menu-node--backg
|
||||
.ibo-navigation-menu--full-company-logo{
|
||||
display: flex;
|
||||
}
|
||||
.ibo-navigation-menu--silo-selection{
|
||||
display: inline-block;
|
||||
}
|
||||
.ibo-navigation-menu--body{
|
||||
width: $ibo-navigation-menu--body--width-expanded;
|
||||
|
||||
@@ -276,8 +289,8 @@ $ibo-navigation-menu--menu-counter-color: $ibo-navigation-menu--menu-node--backg
|
||||
}
|
||||
/* - Top part */
|
||||
.ibo-navigation-menu--top-part{
|
||||
z-index: 1;
|
||||
height: $ibo-navigation-menu--top-part--height;
|
||||
z-index: 2;
|
||||
min-height: $ibo-navigation-menu--top-part--height;
|
||||
padding: $ibo-navigation-menu--top-part--padding-y $ibo-navigation-menu--top-part--padding-x;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -348,7 +361,7 @@ $ibo-navigation-menu--menu-counter-color: $ibo-navigation-menu--menu-node--backg
|
||||
}
|
||||
/* - Toggler */
|
||||
.ibo-navigation-menu--toggler{
|
||||
display: flex;
|
||||
display: inline-flex;
|
||||
/* Width is define here in addition of the icon so we can fix its width whether the menu is collapsed or expanded */
|
||||
width: $ibo-navigation-menu--toggler--width;
|
||||
|
||||
@@ -386,6 +399,37 @@ $ibo-navigation-menu--menu-counter-color: $ibo-navigation-menu--menu-node--backg
|
||||
top: 16px;
|
||||
}
|
||||
}
|
||||
.ibo-navigation-menu--silo-selection {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: $ibo-navigation-menu--silo-selection--width;
|
||||
margin-left: $ibo-navigation-menu--silo-selection--margin-left;
|
||||
.ibo-input-wrapper
|
||||
{
|
||||
.ibo-input{
|
||||
padding-right: $ibo-navigation-menu--silo-selection--input--padding-right;
|
||||
overflow: hidden;
|
||||
>[data-value]
|
||||
{
|
||||
padding: $ibo-navigation-menu--silo-selection--input--data-value--padding;
|
||||
}
|
||||
}
|
||||
.ibo-input-select--action-button--hierarchy{
|
||||
margin-left: $ibo-navigation-menu--silo-selection--input--action-button--hierarchy--padding-right;
|
||||
}
|
||||
|
||||
.ibo-input-select-autocomplete{
|
||||
padding-right: $ibo-navigation-menu--silo-selection--input-select-autocomplete--padding-left;
|
||||
~ .ibo-input-select--action-button--search{
|
||||
margin-left: $ibo-navigation-menu--silo-selection--input-select-autocomplete--action-button--search--margin-left;
|
||||
}
|
||||
~ .ibo-input-select--action-button--hierarchy{
|
||||
margin-left: $ibo-navigation-menu--silo-selection--input-select-autocomplete--action-button--hierarchy--margin-left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* - Menu groups */
|
||||
.ibo-navigation-menu--menu-group{
|
||||
|
||||
@@ -23,12 +23,15 @@ namespace Combodo\iTop\Application\UI\Layout\NavigationMenu;
|
||||
use ApplicationContext;
|
||||
use ApplicationMenu;
|
||||
use appUserPreferences;
|
||||
use CMDBObjectSet;
|
||||
use Combodo\iTop\Application\Branding;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\NewsroomMenu\NewsroomMenu;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use DBObjectSearch;
|
||||
use Dict;
|
||||
use MetaModel;
|
||||
use UIExtKeyWidget;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
@@ -48,6 +51,8 @@ class NavigationMenu extends UIBlock
|
||||
public const JS_TEMPLATE_REL_PATH = 'layouts/navigation-menu/layout';
|
||||
public const JS_FILES_REL_PATH = [
|
||||
'js/layouts/navigation-menu.js',
|
||||
'js/extkeywidget.js',
|
||||
'js/forms-json-utils.js',
|
||||
];
|
||||
|
||||
/** @var string $sAppRevisionNumber */
|
||||
@@ -58,6 +63,8 @@ class NavigationMenu extends UIBlock
|
||||
protected $sAppFullIconUrl;
|
||||
/** @var string $sAppIconLink */
|
||||
protected $sAppIconLink;
|
||||
/** @var array $aSiloSelection */
|
||||
protected $aSiloSelection;
|
||||
/** @var array $aMenuGroups */
|
||||
protected $aMenuGroups;
|
||||
/** @var array $aUserData */
|
||||
@@ -92,12 +99,14 @@ class NavigationMenu extends UIBlock
|
||||
$this->sAppSquareIconUrl = Branding::GetCompactMainLogoAbsoluteUrl();
|
||||
$this->sAppFullIconUrl = Branding::GetFullMainLogoAbsoluteUrl();
|
||||
$this->sAppIconLink = MetaModel::GetConfig()->Get('app_icon_url');
|
||||
$this->aSiloSelection = array();
|
||||
$this->aMenuGroups = ApplicationMenu::GetMenuGroups($oAppContext->GetAsHash());
|
||||
$this->oUserMenu = $oUserMenu;
|
||||
$this->oNewsroomMenu = $oNewsroomMenu;
|
||||
|
||||
$this->ComputeExpandedState();
|
||||
$this->ComputeUserData();
|
||||
$this->ComputeSiloSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,6 +141,14 @@ class NavigationMenu extends UIBlock
|
||||
return $this->sAppIconLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetSiloSelection()
|
||||
{
|
||||
return $this->aSiloSelection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -189,6 +206,77 @@ class NavigationMenu extends UIBlock
|
||||
return MetaModel::GetConfig()->Get('newsroom_enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public function ComputeSiloSelection()
|
||||
{
|
||||
//TODO 3.0 Use components if we have the time to build select/autocomplete components before release
|
||||
// List of visible Organizations
|
||||
$iCount = 0;
|
||||
$oSet = null;
|
||||
if (MetaModel::IsValidClass('Organization'))
|
||||
{
|
||||
// Display the list of *favorite* organizations... but keeping in mind what is the real number of organizations
|
||||
$aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null);
|
||||
$oSearchFilter = new DBObjectSearch('Organization');
|
||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||
$iCount = $oSet->Count(); // total number of existing Orgs
|
||||
|
||||
// Now get the list of Orgs to be displayed in the menu
|
||||
$oSearchFilter = DBObjectSearch::FromOQL(ApplicationMenu::GetFavoriteSiloQuery());
|
||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||
if (!empty($aFavoriteOrgs))
|
||||
{
|
||||
$oSearchFilter->AddCondition('id', $aFavoriteOrgs, 'IN');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oSearchFilter); // List of favorite orgs
|
||||
}
|
||||
switch ($iCount)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// No such dimension/silo or only one possible choice => nothing to select
|
||||
break;
|
||||
|
||||
default:
|
||||
$oAppContext = new ApplicationContext();
|
||||
$iCurrentOrganization = $oAppContext->GetCurrentValue('org_id');
|
||||
$this->aSiloSelection['html'] = '<form data-role="ibo-navigation-menu--silo-selection--form" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">';
|
||||
|
||||
$oPage = new \CaptureWebPage();
|
||||
|
||||
$oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */);
|
||||
$iMaxComboLength = MetaModel::GetConfig()->Get('max_combo_length');
|
||||
$this->aSiloSelection['html'] .= $oWidget->DisplaySelect($oPage, $iMaxComboLength, false, '', $oSet, $iCurrentOrganization, false, 'c[org_id]', '',
|
||||
array(
|
||||
'iFieldSize' => 20,
|
||||
'iMinChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'),
|
||||
'sDefaultValue' => Dict::S('UI:AllOrganizations'),
|
||||
));
|
||||
$this->aSiloSelection['html'] .= $oPage->GetHtml();
|
||||
// Add other dimensions/context information to this form
|
||||
$oAppContext->Reset('org_id'); // org_id is handled above and we want to be able to change it here !
|
||||
$oAppContext->Reset('menu'); // don't pass the menu, since a menu may expect more parameters
|
||||
$this->aSiloSelection['html'] .= $oAppContext->GetForForm(); // Pass what remains, if anything...
|
||||
$this->aSiloSelection['html'] .= '</form>';
|
||||
|
||||
$sPageJS = $oPage->GetJS();
|
||||
$sPageReadyJS = $oPage->GetReadyJS();
|
||||
$this->aSiloSelection['js'] =
|
||||
<<<JS
|
||||
$sPageJS
|
||||
$sPageReadyJS
|
||||
$('[data-role="ibo-navigation-menu--silo-selection--form"] #org_id').bind('extkeychange', function() { $('[data-role="ibo-navigation-menu--silo-selection--form"]').submit(); } )
|
||||
$('[data-role="ibo-navigation-menu--silo-selection--form"] #label_org_id').click( function() { if ($('[data-role="ibo-navigation-menu--silo-selection--form"] #org_id').val() == '') { $(this).val(''); } } );
|
||||
JS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute if the menu is expanded or collapsed
|
||||
*
|
||||
|
||||
@@ -553,71 +553,7 @@ JS
|
||||
$this->sBreadCrumbEntryUrl = null;
|
||||
$this->sBreadCrumbEntryIcon = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \CoreException
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function GetSiloSelectionForm()
|
||||
{
|
||||
// List of visible Organizations
|
||||
$iCount = 0;
|
||||
$oSet = null;
|
||||
if (MetaModel::IsValidClass('Organization'))
|
||||
{
|
||||
// Display the list of *favorite* organizations... but keeping in mind what is the real number of organizations
|
||||
$aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null);
|
||||
$oSearchFilter = new DBObjectSearch('Organization');
|
||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||
$oSet = new CMDBObjectSet($oSearchFilter);
|
||||
$iCount = $oSet->Count(); // total number of existing Orgs
|
||||
|
||||
// Now get the list of Orgs to be displayed in the menu
|
||||
$oSearchFilter = DBObjectSearch::FromOQL(ApplicationMenu::GetFavoriteSiloQuery());
|
||||
$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
|
||||
if (!empty($aFavoriteOrgs))
|
||||
{
|
||||
$oSearchFilter->AddCondition('id', $aFavoriteOrgs, 'IN');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oSearchFilter); // List of favorite orgs
|
||||
}
|
||||
switch ($iCount)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// No such dimension/silo or only one possible choice => nothing to select
|
||||
$sHtml = '<div id="SiloSelection"><!-- nothing to select --></div>';
|
||||
break;
|
||||
|
||||
default:
|
||||
$oAppContext = new ApplicationContext();
|
||||
$iCurrentOrganization = $oAppContext->GetCurrentValue('org_id');
|
||||
$sHtml = '<div id="SiloSelection">';
|
||||
$sHtml .= '<form style="display:inline" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">';
|
||||
|
||||
$oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */);
|
||||
$sHtml .= $oWidget->DisplaySelect($this, 50, false, '', $oSet, $iCurrentOrganization, false, 'c[org_id]', '',
|
||||
array(
|
||||
'iFieldSize' => 20,
|
||||
'iMinChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'),
|
||||
'sDefaultValue' => Dict::S('UI:AllOrganizations'),
|
||||
));
|
||||
$this->add_ready_script('$("#org_id").bind("extkeychange", function() { $("#SiloSelection form").submit(); } )');
|
||||
$this->add_ready_script("$('#label_org_id').click( function() { if ($('#org_id').val() == '') { $(this).val(''); } } );\n");
|
||||
// Add other dimensions/context information to this form
|
||||
$oAppContext->Reset('org_id'); // org_id is handled above and we want to be able to change it here !
|
||||
$oAppContext->Reset('menu'); // don't pass the menu, since a menu may expect more parameters
|
||||
$sHtml .= $oAppContext->GetForForm(); // Pass what remains, if anything...
|
||||
$sHtml .= '</form>';
|
||||
$sHtml .= '</div>';
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -970,9 +906,7 @@ EOF;
|
||||
/////////////////////////////////////////////////////////
|
||||
////////////////// ☢ DANGER ZONE ☢ /////////////////////
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
$sForm = $this->GetSiloSelectionForm();
|
||||
|
||||
|
||||
// Render the tabs in the page (if any)
|
||||
// $this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content, $this);
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
<span class="ibo-navigation-menu--toggler-bar"></span>
|
||||
</span>
|
||||
</a>
|
||||
<div class="ibo-navigation-menu--silo-selection">
|
||||
{{ oUIBlock.GetSiloSelection().html|raw }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibo-navigation-menu--middle-part">
|
||||
{% for aMenuGroup in oUIBlock.GetMenuGroups() %}
|
||||
|
||||
@@ -2,4 +2,6 @@ $('#{{ oUIBlock.GetId() }}').navigation_menu({
|
||||
display_counts: {% if get_config_parameter('display_menus_count') %} true {% else %} false {% endif %}
|
||||
});
|
||||
|
||||
$('#{{ oUIBlock.GetId() }}').navigation_menu('refreshCounts', null);
|
||||
$('#{{ oUIBlock.GetId() }}').navigation_menu('refreshCounts', null);
|
||||
|
||||
{{ oUIBlock.GetSiloSelection().js|raw }}
|
||||
Reference in New Issue
Block a user