mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°2847 - Rework iTopWebPage layout (WIP Part VI)
- iTopWebPage: Restore "open search" feature - iTopWebPage: Change all resources URL to absolute in order to benefit from the "duplicate removal" benefits - iTopWebPage: Remove obsolete method IsMenuPaneVisible() - Config: Add new parameters quick_create.enabled / global_search.enabled / breadcrumb.enabled - utils: Add new GetAppRevisionNumber() method - Introduce iUIBlock interface for UI layouts, components, ... - Introduce BlockRenderer to properly render blocks - Add "render_block" function to TwigHelper to render blocks directly from TWIG - Refactor layouts and components into proper block classes to fit the new architecture
This commit is contained in:
@@ -21,10 +21,10 @@ require_once(APPROOT."/application/nicewebpage.class.inc.php");
|
||||
require_once(APPROOT."/application/applicationcontext.class.inc.php");
|
||||
require_once(APPROOT."/application/user.preferences.class.inc.php");
|
||||
|
||||
use Combodo\iTop\Application\Branding;
|
||||
use Combodo\iTop\Application\QuickCreate\QuickCreateHelper;
|
||||
use Combodo\iTop\Application\GlobalSearch\GlobalSearchHelper;
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\Layout\NavigationMenu\NavigationMenuFactory;
|
||||
use Combodo\iTop\Application\UI\Layout\TopBar\TopBarFactory;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
@@ -87,47 +87,48 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
// TODO: Should we keep this? Makes no sense
|
||||
//$this->add_header("Cache-control: no-cache");
|
||||
// TODO: Add only what's necessary
|
||||
$this->add_linked_stylesheet("../css/jquery.treeview.css");
|
||||
$this->add_linked_stylesheet("../css/jquery-ui-timepicker-addon.css");
|
||||
$this->add_linked_stylesheet("../css/jquery.multiselect.css");
|
||||
$this->add_linked_stylesheet("../css/magnific-popup.css");
|
||||
$this->add_linked_stylesheet("../css/c3.min.css");
|
||||
$this->add_linked_stylesheet("../node_modules/tippy.js/dist/tippy.css");
|
||||
$this->add_linked_stylesheet("../node_modules/tippy.js/animations/shift-away-subtle.css");
|
||||
$this->add_linked_stylesheet("../css/font-awesome/css/all.min.css");
|
||||
$this->add_linked_stylesheet("../css/font-combodo/font-combodo.css");
|
||||
$this->add_linked_stylesheet("../js/ckeditor/plugins/codesnippet/lib/highlight/styles/obsidian.css");
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/jquery.treeview.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/jquery-ui-timepicker-addon.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/jquery.multiselect.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/magnific-popup.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/c3.min.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/dist/tippy.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/animations/shift-away-subtle.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-combodo/font-combodo.css');
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'js/ckeditor/plugins/codesnippet/lib/highlight/styles/obsidian.css');
|
||||
|
||||
// TODO: Add only what's necessary
|
||||
$this->add_linked_script('../js/jquery.layout.min.js');
|
||||
$this->add_linked_script('../js/jquery.ba-bbq.min.js');
|
||||
$this->add_linked_script("../js/jquery.treeview.js");
|
||||
$this->add_linked_script("../js/date.js");
|
||||
$this->add_linked_script("../js/jquery-ui-timepicker-addon.js");
|
||||
$this->add_linked_script("../js/jquery-ui-timepicker-addon-i18n.min.js");
|
||||
$this->add_linked_script("../js/jquery.blockUI.js");
|
||||
$this->add_linked_script("../js/utils.js");
|
||||
$this->add_linked_script("../js/swfobject.js");
|
||||
$this->add_linked_script("../js/ckeditor/ckeditor.js");
|
||||
$this->add_linked_script("../js/ckeditor/adapters/jquery.js");
|
||||
$this->add_linked_script("../js/ckeditor/plugins/codesnippet/lib/highlight/highlight.pack.js");
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.layout.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.ba-bbq.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.treeview.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/date.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui-timepicker-addon.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui-timepicker-addon-i18n.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.blockUI.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/swfobject.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/ckeditor/ckeditor.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/ckeditor/adapters/jquery.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/ckeditor/plugins/codesnippet/lib/highlight/highlight.pack.js');
|
||||
/* @deprecated qTip will be removed in 2.9.0, use Tippy.js instead */
|
||||
$this->add_linked_script("../js/jquery.qtip-1.0.min.js");
|
||||
$this->add_linked_script("../node_modules/@popperjs/core/dist/umd/popper.js");
|
||||
$this->add_linked_script("../node_modules/tippy.js/dist/tippy-bundle.umd.js");
|
||||
$this->add_linked_script('../js/property_field.js');
|
||||
$this->add_linked_script('../js/icon_select.js');
|
||||
$this->add_linked_script('../js/raphael-min.js');
|
||||
$this->add_linked_script('../js/d3.js');
|
||||
$this->add_linked_script('../js/c3.js');
|
||||
$this->add_linked_script('../js/jquery.multiselect.js');
|
||||
$this->add_linked_script('../js/ajaxfileupload.js');
|
||||
$this->add_linked_script('../js/jquery.mousewheel.js');
|
||||
$this->add_linked_script('../js/jquery.magnific-popup.min.js');
|
||||
$this->add_linked_script('../js/moment-with-locales.min.js');
|
||||
$this->add_linked_script('../js/showdown.min.js');
|
||||
$this->add_linked_script('../js/pages/backoffice.js');
|
||||
$this->add_linked_script('../js/newsroom_menu.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.qtip-1.0.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'node_modules/@popperjs/core/dist/umd/popper.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/dist/tippy-bundle.umd.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/property_field.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/icon_select.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/raphael-min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/d3.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/c3.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.multiselect.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/ajaxfileupload.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.mousewheel.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.magnific-popup.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/moment-with-locales.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/showdown.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/pages/backoffice.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/newsroom_menu.js');
|
||||
|
||||
$this->add_dict_entry('UI:FillAllMandatoryFields');
|
||||
|
||||
@@ -144,33 +145,6 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true is the navigation menu should be expanded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function IsMenuPaneVisible()
|
||||
{
|
||||
$bIsExpanded = false;
|
||||
if (MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
// Leave the menu collapsed
|
||||
}
|
||||
else
|
||||
{
|
||||
if (utils::ReadParam('force_menu_pane', null) === 0)
|
||||
{
|
||||
$bIsExpanded = false;
|
||||
}
|
||||
elseif (appUserPreferences::GetPref('menu_pane', 'closed') === 'opened')
|
||||
{
|
||||
$bIsExpanded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $bIsExpanded;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -675,14 +649,16 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* @see static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE, static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES
|
||||
*
|
||||
* @param string $sId Identifies the item, to search after it in the current breadcrumb
|
||||
* @param string $sLabel Label of the breadcrumb item
|
||||
* @param string $sDescription More information, displayed as a tooltip
|
||||
* @param string $sUrl Specify a URL if the current URL as perceived on the browser side is not relevant
|
||||
* @param string $sIcon Image URL (relative or absolute) or CSS classes (eg. "fas fa-wrench") of the icon that will be displayed next to the label
|
||||
* @param string $sIconType Type of the icon, must be set according to the $sIcon value. See class constants ENUM_BREADCRUMB_ENTRY_ICON_TYPE_XXX
|
||||
*
|
||||
* @see static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_IMAGE, static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES
|
||||
* @param string $sIcon Image URL (relative or absolute) or CSS classes (eg. "fas fa-wrench") of the icon that will be displayed next
|
||||
* to the label
|
||||
* @param string $sIconType Type of the icon, must be set according to the $sIcon value. See class constants
|
||||
* ENUM_BREADCRUMB_ENTRY_ICON_TYPE_XXX
|
||||
*/
|
||||
public function SetBreadCrumbEntry($sId, $sLabel, $sDescription, $sUrl = '', $sIcon = '', $sIconType = self::DEFAULT_BREADCRUMB_ENTRY_ICON_TYPE)
|
||||
{
|
||||
@@ -812,209 +788,70 @@ JS
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the complete revision number of the application
|
||||
* Return the navigation menu layout (id, menu groups, ...)
|
||||
*
|
||||
* @return string
|
||||
* @since 2.8.0
|
||||
*/
|
||||
protected function GetApplicationRevisionNumber()
|
||||
{
|
||||
if (ITOP_REVISION == 'svn')
|
||||
{
|
||||
// This is NOT a version built using the build system, just display the main version
|
||||
$sRevisionNumber = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a build made from SVN, let display the full information
|
||||
$sRevisionNumber = Dict::Format('UI:iTopVersion:Long', ITOP_APPLICATION, ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE);
|
||||
}
|
||||
|
||||
return $sRevisionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the navigation menu data (id, menu groups, ...)
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @internal
|
||||
* @return \Combodo\iTop\Application\UI\Layout\NavigationMenu\NavigationMenu
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
* @since 2.8.0
|
||||
* @internal
|
||||
*/
|
||||
protected function GetNavigationMenuData()
|
||||
protected function GetNavigationMenuLayout()
|
||||
{
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
$aData = [
|
||||
'sId' => 'ibo-navigation-menu',
|
||||
'sAppRevisionNumber' => $this->GetApplicationRevisionNumber(),
|
||||
'sAppSquareIconUrl' => Branding::GetSquareMainLogoAbsoluteUrl(),
|
||||
'sAppFullIconUrl' => Branding::GetFullMainLogoAbsoluteUrl(),
|
||||
'sAppIconLink' => MetaModel::GetConfig()->Get('app_icon_url'),
|
||||
'aMenuGroups' => ApplicationMenu::GetMenuGroups($oAppContext->GetAsHash()),
|
||||
'bIsExpanded' => $this->IsMenuPaneVisible(),
|
||||
];
|
||||
|
||||
// TODO: Move this in the PHP component when designed
|
||||
$this->add_linked_script('../js/layouts/navigation-menu.js');
|
||||
// ... and this in a dedicated JS TWIG
|
||||
$this->add_ready_script(<<<JS
|
||||
$('#{$aData['sId']}').navigation_menu();
|
||||
JS
|
||||
);
|
||||
|
||||
return $aData;
|
||||
return NavigationMenuFactory::MakeStandard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the top bar data (global search, breadcrumbs, ...)
|
||||
* Return the top bar layout (global search, breadcrumbs, ...)
|
||||
*
|
||||
* @return array
|
||||
* @throws \ConfigException
|
||||
* @internal
|
||||
* @return \Combodo\iTop\Application\UI\Layout\TopBar\TopBar
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @since 2.8.0
|
||||
* @internal
|
||||
*/
|
||||
protected function GetTopBarData()
|
||||
protected function GetTopBarLayout()
|
||||
{
|
||||
$aData = [
|
||||
'sId' => 'ibo-top-bar',
|
||||
'aComponents' => [
|
||||
'aQuickCreate' => $this->GetQuickCreateData(),
|
||||
'aGlobalSearch' => $this->GetGlobalSearchData(),
|
||||
'aBreadCrumbs' => $this->GetBreadCrumbsData(),
|
||||
],
|
||||
];
|
||||
|
||||
return $aData;
|
||||
return TopBarFactory::MakeStandard($this->GetBreadCrumbsNewEntry());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the quick create data (last classes)
|
||||
* Return the new breadcrumbs entry or null if we don't create a new entry for the current page
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @since 2.8.0
|
||||
* @internal
|
||||
*/
|
||||
protected function GetQuickCreateData()
|
||||
{
|
||||
$aData = [
|
||||
'sId' => 'ibo-quick-create',
|
||||
'sEndpoint' => utils::GetAbsoluteUrlAppRoot().'pages/UI.php',
|
||||
'aAvailableClasses' => UserRights::GetAllowedClasses(UR_ACTION_CREATE, array('bizmodel'), true),
|
||||
'aLastClasses' => QuickCreateHelper::GetLastClasses(),
|
||||
];
|
||||
|
||||
// TODO: Move this in the PHP component when designed
|
||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/selectize.default.css');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/selectize.min.js');
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/components/quick-create.js');
|
||||
// ... and this in a dedicated JS TWIG
|
||||
$this->add_ready_script(<<<JS
|
||||
$('#{$aData['sId']}').quick_create();
|
||||
JS
|
||||
);
|
||||
|
||||
return $aData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the global search data (last queries)
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @return array|null
|
||||
* @since 2.8.0
|
||||
* @internal
|
||||
*/
|
||||
protected function GetGlobalSearchData()
|
||||
protected function GetBreadCrumbsNewEntry()
|
||||
{
|
||||
$aData = [
|
||||
'sId' => 'ibo-global-search',
|
||||
'sEndpoint' => utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=full_text',
|
||||
'aLastQueries' => GlobalSearchHelper::GetLastQueries(),
|
||||
];
|
||||
$aNewEntry = null;
|
||||
|
||||
// TODO: Move this in the PHP component when designed
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/components/global-search.js');
|
||||
// ... and this in a dedicated JS TWIG
|
||||
$this->add_ready_script(<<<JS
|
||||
$('#{$aData['sId']}').global_search();
|
||||
JS
|
||||
);
|
||||
|
||||
return $aData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the breadcrumbs data (iTop instance ID, new entry, ...)
|
||||
*
|
||||
* @return array
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @since 2.8.0
|
||||
* @internal
|
||||
*/
|
||||
protected function GetBreadCrumbsData()
|
||||
{
|
||||
$aData = [
|
||||
'sId' => 'ibo-breadcrumbs',
|
||||
'aWidgetOptions' => [],
|
||||
];
|
||||
|
||||
$iBreadCrumbMaxCount = utils::GetConfig()->Get('breadcrumb.max_count');
|
||||
if ($iBreadCrumbMaxCount > 1)
|
||||
if ($this->bBreadCrumbEnabled)
|
||||
{
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$siTopInstanceId = $oConfig->GetItopInstanceid();
|
||||
|
||||
if ($this->bBreadCrumbEnabled)
|
||||
// Default entry values
|
||||
if (is_null($this->sBreadCrumbEntryId))
|
||||
{
|
||||
// Default entry values
|
||||
if (is_null($this->sBreadCrumbEntryId))
|
||||
{
|
||||
$this->sBreadCrumbEntryId = $this->s_title;
|
||||
$this->sBreadCrumbEntryLabel = $this->s_title;
|
||||
$this->sBreadCrumbEntryDescription = $this->s_title;
|
||||
$this->sBreadCrumbEntryUrl = '';
|
||||
$this->sBreadCrumbEntryIcon = 'fas fa-wrench';
|
||||
$this->sBreadCrumbEntryIconType = static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES;
|
||||
}
|
||||
|
||||
$aNewEntry = array(
|
||||
'id' => $this->sBreadCrumbEntryId,
|
||||
'url' => $this->sBreadCrumbEntryUrl,
|
||||
'label' => utils::HtmlEntities($this->sBreadCrumbEntryLabel),
|
||||
'description' => utils::HtmlEntities($this->sBreadCrumbEntryDescription),
|
||||
'icon' => $this->sBreadCrumbEntryIcon,
|
||||
'icon_type' => $this->sBreadCrumbEntryIconType,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aNewEntry = null;
|
||||
$this->sBreadCrumbEntryId = $this->s_title;
|
||||
$this->sBreadCrumbEntryLabel = $this->s_title;
|
||||
$this->sBreadCrumbEntryDescription = $this->s_title;
|
||||
$this->sBreadCrumbEntryUrl = '';
|
||||
$this->sBreadCrumbEntryIcon = 'fas fa-wrench';
|
||||
$this->sBreadCrumbEntryIconType = static::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES;
|
||||
}
|
||||
|
||||
$aData['aWidgetOptions'] = [
|
||||
'itop_instance_id' => $siTopInstanceId,
|
||||
'max_count' => $iBreadCrumbMaxCount,
|
||||
'new_entry' => $aNewEntry,
|
||||
$aNewEntry = [
|
||||
'id' => $this->sBreadCrumbEntryId,
|
||||
'url' => $this->sBreadCrumbEntryUrl,
|
||||
'label' => utils::HtmlEntities($this->sBreadCrumbEntryLabel),
|
||||
'description' => utils::HtmlEntities($this->sBreadCrumbEntryDescription),
|
||||
'icon' => $this->sBreadCrumbEntryIcon,
|
||||
'icon_type' => $this->sBreadCrumbEntryIconType,
|
||||
];
|
||||
}
|
||||
|
||||
// TODO: Move this in the PHP component when designed
|
||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/components/breadcrumbs.js');
|
||||
// ... and this in a dedicated JS TWIG
|
||||
$sWidgetOptionsAsJson = json_encode($aData['aWidgetOptions']);
|
||||
$this->add_ready_script(<<<JS
|
||||
// Note: When refactor in the JS TWIG, use {{ aBreadCrumbs.aWidgetOptions|json_encode|raw }}
|
||||
$('#{$aData['sId']}').breadcrumbs($sWidgetOptionsAsJson);
|
||||
JS
|
||||
);
|
||||
|
||||
return $aData;
|
||||
return $aNewEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1194,12 +1031,34 @@ EOF
|
||||
'sHeader' => $this->RenderHeaderHtml(),
|
||||
'sFooter' => $this->RenderFooterHtml(),
|
||||
];
|
||||
// - Prepare navigation menu
|
||||
$aData['aLayouts']['oNavigationMenu'] = $this->GetNavigationMenuLayout();
|
||||
// - Prepare top bar
|
||||
$aData['aLayouts']['oTopBar'] = $this->GetTopBarLayout();
|
||||
// - Retrieve layouts linked files
|
||||
// Note: Adding them now instead of in the template allow us to remove duplicates and lower the browser parsing time
|
||||
/** @var \Combodo\iTop\Application\UI\UIBlock|string $oLayout */
|
||||
foreach ($aData['aLayouts'] as $oLayout)
|
||||
{
|
||||
if (!$oLayout instanceof UIBlock)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// - Navigation menu
|
||||
$aData['aLayouts']['aNavigationMenu'] = $this->GetNavigationMenuData();
|
||||
// CSS files
|
||||
foreach ($oLayout->GetCssFilesUrlRecursively(true) as $sFileAbsUrl)
|
||||
{
|
||||
$this->add_linked_stylesheet($sFileAbsUrl);
|
||||
}
|
||||
// JS files
|
||||
foreach ($oLayout->GetJsFilesUrlRecursively(true) as $sFileAbsUrl)
|
||||
{
|
||||
$this->add_linked_script($sFileAbsUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// - Top bar
|
||||
$aData['aLayouts']['aTopBar'] = $this->GetTopBarData();
|
||||
// Components
|
||||
// Note: For now all components are either included in the layouts above or put in page through the add_ui_block() API, so there is no need to do anything more.
|
||||
|
||||
// Variable content of the page
|
||||
$aData['aPage'] = array_merge(
|
||||
@@ -1292,10 +1151,10 @@ EOF
|
||||
{
|
||||
$sHtml .= $this->output_dict_entries(true); // before any script so that they can benefit from the translations
|
||||
|
||||
if (!$this->IsPrintableVersion())
|
||||
{
|
||||
$this->add_script("var iPaneVisWatchDog = window.setTimeout('FixPaneVis()',5000);");
|
||||
}
|
||||
// if (!$this->IsPrintableVersion())
|
||||
// {
|
||||
// $this->add_script("var iPaneVisWatchDog = window.setTimeout('FixPaneVis()',5000);");
|
||||
// }
|
||||
|
||||
|
||||
// TODO: Should we still do this init vs ready separation?
|
||||
@@ -1333,8 +1192,7 @@ EOF
|
||||
}
|
||||
|
||||
|
||||
// TODO: Does this still work?
|
||||
$sHtml .= "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"".utils::GetAbsoluteUrlAppRoot()."pages/opensearch.xml.php\" />\n";
|
||||
// $sHtml .= "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"".utils::GetAbsoluteUrlAppRoot()."pages/opensearch.xml.php\" />\n";
|
||||
|
||||
|
||||
$sHtml .= "</head>\n";
|
||||
@@ -1379,10 +1237,10 @@ EOF;
|
||||
$sHtml .= "<div class=\"printable-content\" style=\"width: $sDefaultResolution;\">";
|
||||
}
|
||||
|
||||
// Render the text of the global search form
|
||||
$sText = htmlentities(utils::ReadParam('text', '', false, 'raw_data'), ENT_QUOTES, self::PAGES_CHARSET);
|
||||
$sOnClick = " onclick=\"if ($('#global-search-input').val() != '') { $('#global-search form').submit(); } \"";
|
||||
$sDefaultPlaceHolder = Dict::S("UI:YourSearch");
|
||||
// // Render the text of the global search form
|
||||
// $sText = htmlentities(utils::ReadParam('text', '', false, 'raw_data'), ENT_QUOTES, self::PAGES_CHARSET);
|
||||
// $sOnClick = " onclick=\"if ($('#global-search-input').val() != '') { $('#global-search form').submit(); } \"";
|
||||
// $sDefaultPlaceHolder = Dict::S("UI:YourSearch");
|
||||
|
||||
if ($this->IsPrintableVersion())
|
||||
{
|
||||
@@ -1409,57 +1267,57 @@ EOF;
|
||||
$sLogOffMenu .= "<li><span>$sLogonMessage</span></li>\n";
|
||||
$aActions = array();
|
||||
|
||||
$aAllowedPortals = UserRights::GetAllowedPortals();
|
||||
if (count($aAllowedPortals) > 1)
|
||||
{
|
||||
// Adding portals
|
||||
foreach ($aAllowedPortals as $aAllowedPortal)
|
||||
{
|
||||
if ($aAllowedPortal['id'] !== 'backoffice')
|
||||
{
|
||||
$oPortalMenuItem = new URLPopupMenuItem('portal:'.$aAllowedPortal['id'], Dict::S($aAllowedPortal['label']),
|
||||
$aAllowedPortal['url'], '_blank');
|
||||
$aActions[$oPortalMenuItem->GetUID()] = $oPortalMenuItem->GetMenuItem();
|
||||
}
|
||||
}
|
||||
// Adding a separator
|
||||
$oPortalSeparatorMenuItem = new SeparatorPopupMenuItem();
|
||||
$aActions[$oPortalSeparatorMenuItem->GetUID()] = $oPortalSeparatorMenuItem->GetMenuItem();
|
||||
}
|
||||
// $aAllowedPortals = UserRights::GetAllowedPortals();
|
||||
// if (count($aAllowedPortals) > 1)
|
||||
// {
|
||||
// // Adding portals
|
||||
// foreach ($aAllowedPortals as $aAllowedPortal)
|
||||
// {
|
||||
// if ($aAllowedPortal['id'] !== 'backoffice')
|
||||
// {
|
||||
// $oPortalMenuItem = new URLPopupMenuItem('portal:'.$aAllowedPortal['id'], Dict::S($aAllowedPortal['label']),
|
||||
// $aAllowedPortal['url'], '_blank');
|
||||
// $aActions[$oPortalMenuItem->GetUID()] = $oPortalMenuItem->GetMenuItem();
|
||||
// }
|
||||
// }
|
||||
// // Adding a separator
|
||||
// $oPortalSeparatorMenuItem = new SeparatorPopupMenuItem();
|
||||
// $aActions[$oPortalSeparatorMenuItem->GetUID()] = $oPortalSeparatorMenuItem->GetMenuItem();
|
||||
// }
|
||||
|
||||
$oPrefs = new URLPopupMenuItem('UI:Preferences', Dict::S('UI:Preferences'),
|
||||
utils::GetAbsoluteUrlAppRoot()."pages/preferences.php?".$oAppContext->GetForLink());
|
||||
$aActions[$oPrefs->GetUID()] = $oPrefs->GetMenuItem();
|
||||
// $oPrefs = new URLPopupMenuItem('UI:Preferences', Dict::S('UI:Preferences'),
|
||||
// utils::GetAbsoluteUrlAppRoot()."pages/preferences.php?".$oAppContext->GetForLink());
|
||||
// $aActions[$oPrefs->GetUID()] = $oPrefs->GetMenuItem();
|
||||
|
||||
if (utils::IsArchiveMode())
|
||||
{
|
||||
$oExitArchive = new JSPopupMenuItem('UI:ArchiveModeOff', Dict::S('UI:ArchiveModeOff'), 'return ArchiveMode(false);');
|
||||
$aActions[$oExitArchive->GetUID()] = $oExitArchive->GetMenuItem();
|
||||
// $oExitArchive = new JSPopupMenuItem('UI:ArchiveModeOff', Dict::S('UI:ArchiveModeOff'), 'return ArchiveMode(false);');
|
||||
// $aActions[$oExitArchive->GetUID()] = $oExitArchive->GetMenuItem();
|
||||
|
||||
$sIcon = '<span class="fas fa-lock fa-1x"></span>';
|
||||
$this->AddApplicationMessage(Dict::S('UI:ArchiveMode:Banner'), $sIcon, Dict::S('UI:ArchiveMode:Banner+'));
|
||||
}
|
||||
elseif (UserRights::CanBrowseArchive())
|
||||
{
|
||||
$oBrowseArchive = new JSPopupMenuItem('UI:ArchiveModeOn', Dict::S('UI:ArchiveModeOn'), 'return ArchiveMode(true);');
|
||||
$aActions[$oBrowseArchive->GetUID()] = $oBrowseArchive->GetMenuItem();
|
||||
}
|
||||
if (utils::CanLogOff())
|
||||
{
|
||||
$oLogOff = new URLPopupMenuItem('UI:LogOffMenu', Dict::S('UI:LogOffMenu'),
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/logoff.php?operation=do_logoff');
|
||||
$aActions[$oLogOff->GetUID()] = $oLogOff->GetMenuItem();
|
||||
}
|
||||
if (UserRights::CanChangePassword())
|
||||
{
|
||||
$oChangePwd = new URLPopupMenuItem('UI:ChangePwdMenu', Dict::S('UI:ChangePwdMenu'),
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=change_pwd');
|
||||
$aActions[$oChangePwd->GetUID()] = $oChangePwd->GetMenuItem();
|
||||
}
|
||||
// elseif (UserRights::CanBrowseArchive())
|
||||
// {
|
||||
// $oBrowseArchive = new JSPopupMenuItem('UI:ArchiveModeOn', Dict::S('UI:ArchiveModeOn'), 'return ArchiveMode(true);');
|
||||
// $aActions[$oBrowseArchive->GetUID()] = $oBrowseArchive->GetMenuItem();
|
||||
// }
|
||||
// if (utils::CanLogOff())
|
||||
// {
|
||||
// $oLogOff = new URLPopupMenuItem('UI:LogOffMenu', Dict::S('UI:LogOffMenu'),
|
||||
// utils::GetAbsoluteUrlAppRoot().'pages/logoff.php?operation=do_logoff');
|
||||
// $aActions[$oLogOff->GetUID()] = $oLogOff->GetMenuItem();
|
||||
// }
|
||||
// if (UserRights::CanChangePassword())
|
||||
// {
|
||||
// $oChangePwd = new URLPopupMenuItem('UI:ChangePwdMenu', Dict::S('UI:ChangePwdMenu'),
|
||||
// utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=change_pwd');
|
||||
// $aActions[$oChangePwd->GetUID()] = $oChangePwd->GetMenuItem();
|
||||
// }
|
||||
utils::GetPopupMenuItems($this, iPopupMenuExtension::MENU_USER_ACTIONS, null, $aActions);
|
||||
|
||||
$oAbout = new JSPopupMenuItem('UI:AboutBox', Dict::S('UI:AboutBox'), 'return ShowAboutBox();');
|
||||
$aActions[$oAbout->GetUID()] = $oAbout->GetMenuItem();
|
||||
// $oAbout = new JSPopupMenuItem('UI:AboutBox', Dict::S('UI:AboutBox'), 'return ShowAboutBox();');
|
||||
// $aActions[$oAbout->GetUID()] = $oAbout->GetMenuItem();
|
||||
|
||||
$sLogOffMenu .= $this->RenderPopupMenuItems($aActions);
|
||||
// TODO: END USER MENU
|
||||
@@ -1519,7 +1377,7 @@ EOF;
|
||||
}
|
||||
|
||||
// TODO: What do we do with this?
|
||||
$sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help');
|
||||
// $sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help');
|
||||
//$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>";
|
||||
|
||||
// $sDisplayIcon = utils::GetAbsoluteUrlAppRoot().'images/itop-logo.png?t='.utils::GetCacheBusterTimestamp();
|
||||
@@ -1583,7 +1441,7 @@ EOF;
|
||||
$sHtml .= ' <div id="global-search"><form action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">';
|
||||
$sHtml .= ' <table id="top-left-buttons-area"><tr>';
|
||||
$sHtml .= ' <td id="top-left-global-search-cell"><div id="global-search-area"><input id="global-search-input" type="text" name="text" placeholder="'.$sDefaultPlaceHolder.'" value="'.$sText.'"></input><div '.$sOnClick.' id="global-search-image"><i class="top-right-icon fa-flip-horizontal fas fa-search"></i><input type="hidden" name="operation" value="full_text"/></div></div></td>';
|
||||
$sHtml .= ' <td id="top-left-help-cell"><a id="help-link" href="'.$sOnlineHelpUrl.'" target="_blank" title="'.Dict::S('UI:Help').'"><i class="top-right-icon fas fa-question-circle"></i></a></td>';
|
||||
// $sHtml .= ' <td id="top-left-help-cell"><a id="help-link" href="'.$sOnlineHelpUrl.'" target="_blank" title="'.Dict::S('UI:Help').'"><i class="top-right-icon fas fa-question-circle"></i></a></td>';
|
||||
$sHtml .= ' <td id="top-left-newsroom-cell">'.$sNewsRoomInitialImage.'</td>';
|
||||
$sHtml .= ' <td id="top-left-logoff-cell">'.self::FilterXSS($sLogOffMenu).'</td>';
|
||||
$sHtml .= ' </tr></table></form></div>';
|
||||
|
||||
@@ -909,6 +909,28 @@ class utils
|
||||
return $sAppRootUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the complete revision number of the application
|
||||
*
|
||||
* @return string
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public static function GetAppRevisionNumber()
|
||||
{
|
||||
if (ITOP_REVISION == 'svn')
|
||||
{
|
||||
// This is NOT a version built using the build system, just display the main version
|
||||
$sRevisionNumber = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a build made from SVN, let display the full information
|
||||
$sRevisionNumber = Dict::Format('UI:iTopVersion:Long', ITOP_APPLICATION, ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE);
|
||||
}
|
||||
|
||||
return $sRevisionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle the variety of HTTP servers
|
||||
* See N°286 (fixed in [896]), and N°634 (this fix)
|
||||
|
||||
@@ -1137,6 +1137,30 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => true,
|
||||
),
|
||||
'quick_create.enabled' => array(
|
||||
'type' => 'bool',
|
||||
'description' => 'Whether or not the global search is enabled',
|
||||
'default' => true,
|
||||
'value' => true,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'global_search.enabled' => array(
|
||||
'type' => 'bool',
|
||||
'description' => 'Whether or not the global search is enabled',
|
||||
'default' => true,
|
||||
'value' => true,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'breadcrumb.enabled' => array(
|
||||
'type' => 'bool',
|
||||
'description' => 'Whether or not the breadcrumbs is enabled',
|
||||
'default' => true,
|
||||
'value' => true,
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'breadcrumb.max_count' => array(
|
||||
'type' => 'integer',
|
||||
'description' => 'Maximum number of items kept in the history breadcrumb. Set it to 0 to entirely disable the breadcrumb.',
|
||||
|
||||
@@ -102,6 +102,7 @@ $ibo-quick-create--compartment--placeholder-hint--text-color: $ibo-color-grey-70
|
||||
}
|
||||
.ibo-quick-create--input{
|
||||
width: $ibo-quick-create--input--width;
|
||||
border: none;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
/* Remove selectize.js theme and apply our own */
|
||||
|
||||
@@ -138,8 +138,6 @@ return array(
|
||||
'CheckStopWatchThresholds' => $baseDir . '/core/ormstopwatch.class.inc.php',
|
||||
'CheckableExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Branding' => $baseDir . '/sources/application/Branding.php',
|
||||
'Combodo\\iTop\\Application\\GlobalSearch\\GlobalSearchHelper' => $baseDir . '/sources/application/GlobalSearch/GlobalSearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\QuickCreate\\QuickCreateHelper' => $baseDir . '/sources/application/QuickCreate/QuickCreateHelper.php',
|
||||
'Combodo\\iTop\\Application\\Search\\AjaxSearchException' => $baseDir . '/sources/application/search/ajaxsearchexception.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Search\\CriterionConversionAbstract' => $baseDir . '/sources/application/search/criterionconversionabstract.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Search\\CriterionConversion\\CriterionToOQL' => $baseDir . '/sources/application/search/criterionconversion/criteriontooql.class.inc.php',
|
||||
@@ -150,6 +148,25 @@ return array(
|
||||
'Combodo\\iTop\\Application\\TwigBase\\Controller\\PageNotFoundException' => $baseDir . '/sources/application/TwigBase/Controller/Controller.php',
|
||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => $baseDir . '/sources/application/TwigBase/Twig/Extension.php',
|
||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => $baseDir . '/sources/application/TwigBase/Twig/TwigHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Breadcrumbs\\Breadcrumbs' => $baseDir . '/sources/application/UI/Component/Breadcrumbs/Breadcrumbs.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\GlobalSearch\\GlobalSearch' => $baseDir . '/sources/application/UI/Component/GlobalSearch/GlobalSearch.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\GlobalSearch\\GlobalSearchFactory' => $baseDir . '/sources/application/UI/Component/GlobalSearch/GlobalSearchFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\GlobalSearch\\GlobalSearchHelper' => $baseDir . '/sources/application/UI/Component/GlobalSearch/GlobalSearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenu' => $baseDir . '/sources/application/UI/Component/PopoverMenu/PopoverMenu.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuFactory' => $baseDir . '/sources/application/UI/Component/PopoverMenu/PopoverMenuFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\JsPopoverMenuItem' => $baseDir . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/JsPopoverMenuItem.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\PopoverMenuItem' => $baseDir . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/PopoverMenuItem.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\PopupMenuItemFactory' => $baseDir . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/PopupMenuItemFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\UrlPopoverMenuItem' => $baseDir . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/UrlPopoverMenuItem.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\QuickCreate\\QuickCreate' => $baseDir . '/sources/application/UI/Component/QuickCreate/QuickCreate.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\QuickCreate\\QuickCreateFactory' => $baseDir . '/sources/application/UI/Component/QuickCreate/QuickCreateFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\QuickCreate\\QuickCreateHelper' => $baseDir . '/sources/application/UI/Component/QuickCreate/QuickCreateHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\NavigationMenu\\NavigationMenu' => $baseDir . '/sources/application/UI/Layout/NavigationMenu/NavigationMenu.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\NavigationMenu\\NavigationMenuFactory' => $baseDir . '/sources/application/UI/Layout/NavigationMenu/NavigationMenuFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\TopBar\\TopBar' => $baseDir . '/sources/application/UI/Layout/TopBar/TopBar.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\TopBar\\TopBarFactory' => $baseDir . '/sources/application/UI/Layout/TopBar/TopBarFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\UIBlock' => $baseDir . '/sources/application/UI/UIBlock.php',
|
||||
'Combodo\\iTop\\Application\\UI\\iUIBlock' => $baseDir . '/sources/application/UI/iUIBlock.php',
|
||||
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
||||
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
@@ -186,6 +203,7 @@ return array(
|
||||
'Combodo\\iTop\\Form\\Validator\\MandatoryValidator' => $baseDir . '/sources/Form/Validator/MandatoryValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => $baseDir . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\Validator' => $baseDir . '/sources/Form/Validator/Validator.php',
|
||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => $baseDir . '/sources/Renderer/BlockRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => $baseDir . '/sources/Renderer/Bootstrap/BsFormRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\FieldRenderer\\BsFieldRenderer' => $baseDir . '/sources/Renderer/Bootstrap/FieldRenderer/BsFieldRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\FieldRenderer\\BsFileUploadFieldRenderer' => $baseDir . '/sources/Renderer/Bootstrap/FieldRenderer/BsFileUploadFieldRenderer.php',
|
||||
|
||||
@@ -368,8 +368,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'CheckStopWatchThresholds' => __DIR__ . '/../..' . '/core/ormstopwatch.class.inc.php',
|
||||
'CheckableExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Branding' => __DIR__ . '/../..' . '/sources/application/Branding.php',
|
||||
'Combodo\\iTop\\Application\\GlobalSearch\\GlobalSearchHelper' => __DIR__ . '/../..' . '/sources/application/GlobalSearch/GlobalSearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\QuickCreate\\QuickCreateHelper' => __DIR__ . '/../..' . '/sources/application/QuickCreate/QuickCreateHelper.php',
|
||||
'Combodo\\iTop\\Application\\Search\\AjaxSearchException' => __DIR__ . '/../..' . '/sources/application/search/ajaxsearchexception.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Search\\CriterionConversionAbstract' => __DIR__ . '/../..' . '/sources/application/search/criterionconversionabstract.class.inc.php',
|
||||
'Combodo\\iTop\\Application\\Search\\CriterionConversion\\CriterionToOQL' => __DIR__ . '/../..' . '/sources/application/search/criterionconversion/criteriontooql.class.inc.php',
|
||||
@@ -380,6 +378,25 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'Combodo\\iTop\\Application\\TwigBase\\Controller\\PageNotFoundException' => __DIR__ . '/../..' . '/sources/application/TwigBase/Controller/Controller.php',
|
||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\Extension' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/Extension.php',
|
||||
'Combodo\\iTop\\Application\\TwigBase\\Twig\\TwigHelper' => __DIR__ . '/../..' . '/sources/application/TwigBase/Twig/TwigHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\Breadcrumbs\\Breadcrumbs' => __DIR__ . '/../..' . '/sources/application/UI/Component/Breadcrumbs/Breadcrumbs.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\GlobalSearch\\GlobalSearch' => __DIR__ . '/../..' . '/sources/application/UI/Component/GlobalSearch/GlobalSearch.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\GlobalSearch\\GlobalSearchFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/GlobalSearch/GlobalSearchFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\GlobalSearch\\GlobalSearchHelper' => __DIR__ . '/../..' . '/sources/application/UI/Component/GlobalSearch/GlobalSearchHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenu' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/PopoverMenu.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/PopoverMenuFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\JsPopoverMenuItem' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/JsPopoverMenuItem.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\PopoverMenuItem' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/PopoverMenuItem.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\PopupMenuItemFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/PopupMenuItemFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\UrlPopoverMenuItem' => __DIR__ . '/../..' . '/sources/application/UI/Component/PopoverMenu/PopoverMenuItem/UrlPopoverMenuItem.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\QuickCreate\\QuickCreate' => __DIR__ . '/../..' . '/sources/application/UI/Component/QuickCreate/QuickCreate.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\QuickCreate\\QuickCreateFactory' => __DIR__ . '/../..' . '/sources/application/UI/Component/QuickCreate/QuickCreateFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Component\\QuickCreate\\QuickCreateHelper' => __DIR__ . '/../..' . '/sources/application/UI/Component/QuickCreate/QuickCreateHelper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\NavigationMenu\\NavigationMenu' => __DIR__ . '/../..' . '/sources/application/UI/Layout/NavigationMenu/NavigationMenu.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\NavigationMenu\\NavigationMenuFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/NavigationMenu/NavigationMenuFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\TopBar\\TopBar' => __DIR__ . '/../..' . '/sources/application/UI/Layout/TopBar/TopBar.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Layout\\TopBar\\TopBarFactory' => __DIR__ . '/../..' . '/sources/application/UI/Layout/TopBar/TopBarFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\UIBlock' => __DIR__ . '/../..' . '/sources/application/UI/UIBlock.php',
|
||||
'Combodo\\iTop\\Application\\UI\\iUIBlock' => __DIR__ . '/../..' . '/sources/application/UI/iUIBlock.php',
|
||||
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
||||
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
@@ -416,6 +433,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'Combodo\\iTop\\Form\\Validator\\MandatoryValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/MandatoryValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\NotEmptyExtKeyValidator' => __DIR__ . '/../..' . '/sources/Form/Validator/NotEmptyExtKeyValidator.php',
|
||||
'Combodo\\iTop\\Form\\Validator\\Validator' => __DIR__ . '/../..' . '/sources/Form/Validator/Validator.php',
|
||||
'Combodo\\iTop\\Renderer\\BlockRenderer' => __DIR__ . '/../..' . '/sources/Renderer/BlockRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\BsFormRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/BsFormRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\FieldRenderer\\BsFieldRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/FieldRenderer/BsFieldRenderer.php',
|
||||
'Combodo\\iTop\\Renderer\\Bootstrap\\FieldRenderer\\BsFileUploadFieldRenderer' => __DIR__ . '/../..' . '/sources/Renderer/Bootstrap/FieldRenderer/BsFileUploadFieldRenderer.php',
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\GlobalSearch\GlobalSearchHelper;
|
||||
use Combodo\iTop\Application\QuickCreate\QuickCreateHelper;
|
||||
use Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearchHelper;
|
||||
use Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreateHelper;
|
||||
|
||||
/**
|
||||
* Displays a popup welcome message, once per session at maximum
|
||||
|
||||
259
sources/Renderer/BlockRenderer.php
Normal file
259
sources/Renderer/BlockRenderer.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Renderer;
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Application\UI\iUIBlock;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Class BlockRenderer
|
||||
*
|
||||
* Used to render any block of the UI (layouts, components)
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Renderer\Component
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class BlockRenderer
|
||||
{
|
||||
/** @var \Twig_Environment $oTwigEnv Singleton used during rendering */
|
||||
protected static $oTwigEnv;
|
||||
|
||||
/**
|
||||
* Helper to use directly in TWIG to render a block and its sub blocks
|
||||
*
|
||||
* @param \Combodo\iTop\Application\UI\iUIBlock $oBlock
|
||||
*
|
||||
* @return string
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public static function RenderBlockTemplates(iUIBlock $oBlock)
|
||||
{
|
||||
$oSelf = new static($oBlock);
|
||||
return $oSelf->RenderTemplates();
|
||||
}
|
||||
|
||||
/** @var \Combodo\iTop\Application\UI\iUIBlock $oBlock */
|
||||
protected $oBlock;
|
||||
/** @var \Combodo\iTop\Renderer\RenderingOutput $oRenderingOutput */
|
||||
protected $oRenderingOutput;
|
||||
|
||||
/**
|
||||
* BlockRenderer constructor.
|
||||
*
|
||||
* @param \Combodo\iTop\Application\UI\iUIBlock $oBlock
|
||||
*/
|
||||
public function __construct(iUIBlock $oBlock)
|
||||
{
|
||||
if(null === static::$oTwigEnv)
|
||||
{
|
||||
static::$oTwigEnv = TwigHelper::GetTwigEnvironment(APPROOT.'templates/');
|
||||
}
|
||||
|
||||
$this->oBlock = $oBlock;
|
||||
$this->ResetRenderingOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the rendering output so it can be computed again
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function ResetRenderingOutput()
|
||||
{
|
||||
$this->oRenderingOutput = new RenderingOutput();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the processed rendering output.
|
||||
*
|
||||
* @return \Combodo\iTop\Renderer\RenderingOutput
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetRenderingOutput()
|
||||
{
|
||||
$this->ResetRenderingOutput();
|
||||
|
||||
$this->oRenderingOutput->AddHtml($this->RenderHtml())
|
||||
->AddCss($this->RenderCssInline())
|
||||
->AddJs($this->RenderJsInline())
|
||||
->SetCssFiles($this->GetCssFiles())
|
||||
->SetJsFiles($this->GetJsFiles());
|
||||
|
||||
return $this->oRenderingOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw output of the HTML template
|
||||
*
|
||||
* @return string
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function RenderHtml()
|
||||
{
|
||||
$sOutput = '';
|
||||
if(!empty($this->oBlock::GetHtmlTemplateRelPath()))
|
||||
{
|
||||
$sOutput = TwigHelper::RenderTemplate(
|
||||
static::$oTwigEnv,
|
||||
[$this->GetBlockParameterNameForTemplate() => $this->oBlock],
|
||||
$this->oBlock::GetHtmlTemplateRelPath(),
|
||||
TwigHelper::ENUM_FILE_TYPE_HTML
|
||||
);
|
||||
}
|
||||
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw output of the JS template
|
||||
*
|
||||
* @return string
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function RenderJsInline()
|
||||
{
|
||||
$sOutput = '';
|
||||
if(!empty($this->oBlock::GetJsTemplateRelPath()))
|
||||
{
|
||||
$sOutput = TwigHelper::RenderTemplate(
|
||||
static::$oTwigEnv,
|
||||
[$this->GetBlockParameterNameForTemplate() => $this->oBlock],
|
||||
$this->oBlock::GetJsTemplateRelPath(),
|
||||
TwigHelper::ENUM_FILE_TYPE_JS
|
||||
);
|
||||
}
|
||||
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw output of the CSS template
|
||||
*
|
||||
* @return string
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function RenderCssInline()
|
||||
{
|
||||
$sOutput = '';
|
||||
if(!empty($this->oBlock::GetCssTemplateRelPath()))
|
||||
{
|
||||
$sOutput = TwigHelper::RenderTemplate(
|
||||
static::$oTwigEnv,
|
||||
[$this->GetBlockParameterNameForTemplate() => $this->oBlock],
|
||||
$this->oBlock::GetCssTemplateRelPath(),
|
||||
TwigHelper::ENUM_FILE_TYPE_CSS
|
||||
);
|
||||
}
|
||||
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the cumulated HTML output of the CSS, HTML and JS templates
|
||||
*
|
||||
* @return string
|
||||
* @throws \ReflectionException
|
||||
* @throws \Twig\Error\LoaderError
|
||||
* @throws \Twig\Error\RuntimeError
|
||||
* @throws \Twig\Error\SyntaxError
|
||||
*/
|
||||
public function RenderTemplates()
|
||||
{
|
||||
$sOutput = '';
|
||||
|
||||
// CSS first to avoid visual glitches
|
||||
$sCssOutput = $this->RenderCssInline();
|
||||
if(!empty($sCssOutput))
|
||||
{
|
||||
$sOutput .= <<<HTML
|
||||
<style>
|
||||
{$sCssOutput}
|
||||
</style>
|
||||
HTML;
|
||||
}
|
||||
|
||||
$sOutput .= $this->RenderHtml();
|
||||
|
||||
// JS last so all markup is build and ready
|
||||
$sJsOutput = $this->RenderJsInline();
|
||||
if(!empty($sJsOutput))
|
||||
{
|
||||
$sOutput .= <<<HTML
|
||||
<script type="text/javascript">
|
||||
{$sJsOutput}
|
||||
</script>
|
||||
HTML;
|
||||
}
|
||||
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the absolute URL of the block JS files
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetJsFiles()
|
||||
{
|
||||
return $this->oBlock->GetJsFilesUrlRecursively(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the absolute URL of the block CSS files
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetCssFiles()
|
||||
{
|
||||
return $this->oBlock->GetCssFilesUrlRecursively(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the parameter used in the template to access the block object (class short name = without namespace)
|
||||
*
|
||||
* @return string
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function GetBlockParameterNameForTemplate()
|
||||
{
|
||||
return 'o'.(new ReflectionClass($this->oBlock))->getShortName();
|
||||
}
|
||||
}
|
||||
@@ -165,6 +165,20 @@ class RenderingOutput
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JS files (absolute URLs) and replace any existing ones.
|
||||
*
|
||||
* @param array $aFiles Array of absolute URLs
|
||||
*
|
||||
* @return $this
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function SetJsFiles($aFiles)
|
||||
{
|
||||
$this->aJsFiles = $aFiles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
@@ -204,6 +218,20 @@ class RenderingOutput
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CSS files (absolute URLs) and replace any existing ones.
|
||||
*
|
||||
* @param array $aFiles Array of absolute URLs
|
||||
*
|
||||
* @return $this
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function SetCssFiles($aFiles)
|
||||
{
|
||||
$this->aCssFiles = $aFiles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $sFile
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace Combodo\iTop\Application\TwigBase\Twig;
|
||||
|
||||
|
||||
use AttributeDateTime;
|
||||
use Combodo\iTop\Application\UI\iUIBlock;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Dict;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
@@ -144,6 +146,13 @@ class Extension
|
||||
$oTwigEnv->addFunction(new Twig_SimpleFunction('get_absolute_url_modules_root', function () {
|
||||
return utils::GetAbsoluteUrlModulesRoot();
|
||||
}));
|
||||
|
||||
// Function to render a UI block (HTML, inline CSS, inline JS) and its sub blocks directly in the TWIG
|
||||
// Usage in twig: {{ render_block(oBlock) }}
|
||||
/** @since 2.8.0 */
|
||||
$oTwigEnv->addFunction(new Twig_SimpleFunction('render_block', function(iUIBlock $oBlock){
|
||||
return BlockRenderer::RenderBlockTemplates($oBlock);
|
||||
}, ['is_safe' => ['html']]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
106
sources/application/UI/Component/Breadcrumbs/Breadcrumbs.php
Normal file
106
sources/application/UI/Component/Breadcrumbs/Breadcrumbs.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\Breadcrumbs;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class Breadcrumbs
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\Breadcrumbs
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class Breadcrumbs extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-breadcrumbs';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/breadcrumbs/layout';
|
||||
const JS_TEMPLATE_REL_PATH = 'components/breadcrumbs/layout';
|
||||
const JS_FILES_REL_PATH = [
|
||||
'js/components/breadcrumbs.js',
|
||||
];
|
||||
|
||||
/** @var array|null $aNewEntry */
|
||||
protected $aNewEntry;
|
||||
|
||||
/**
|
||||
* QuickCreate constructor.
|
||||
*
|
||||
* @param string $sId
|
||||
* @param array|null $aNewEntry
|
||||
*/
|
||||
public function __construct($sId = null, $aNewEntry = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->SetNewEntry($aNewEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* The new breadcrumbs entry
|
||||
*
|
||||
* @param array|null $aNewEntry
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetNewEntry($aNewEntry)
|
||||
{
|
||||
$this->aNewEntry = $aNewEntry;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetNewEntry()
|
||||
{
|
||||
return $this->aNewEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetJsWidgetOptions()
|
||||
{
|
||||
$aJsWidgetOptions = [];
|
||||
|
||||
$iBreadCrumbMaxCount = utils::GetConfig()->Get('breadcrumb.max_count');
|
||||
if ($iBreadCrumbMaxCount > 1)
|
||||
{
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$siTopInstanceId = $oConfig->GetItopInstanceid();
|
||||
|
||||
$aJsWidgetOptions = [
|
||||
'itop_instance_id' => $siTopInstanceId,
|
||||
'max_count' => $iBreadCrumbMaxCount,
|
||||
'new_entry' => $this->GetNewEntry(),
|
||||
];
|
||||
}
|
||||
|
||||
return $aJsWidgetOptions;
|
||||
}
|
||||
}
|
||||
115
sources/application/UI/Component/GlobalSearch/GlobalSearch.php
Normal file
115
sources/application/UI/Component/GlobalSearch/GlobalSearch.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\GlobalSearch;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class GlobalSearch
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\GlobalSearch
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class GlobalSearch extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-global-search';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/global-search/layout';
|
||||
const JS_TEMPLATE_REL_PATH = 'components/global-search/layout';
|
||||
const JS_FILES_REL_PATH = [
|
||||
'js/components/global-search.js',
|
||||
];
|
||||
|
||||
const DEFAULT_ENDPOINT_REL_URL = 'pages/UI.php?operation=full_text';
|
||||
|
||||
/** @var string $sEndpoint Absolute endpoint URL of the search form */
|
||||
protected $sEndpoint;
|
||||
/** @var array $aLastQueries */
|
||||
protected $aLastQueries;
|
||||
|
||||
/**
|
||||
* GlobalSearch constructor.
|
||||
*
|
||||
* @param string $sId
|
||||
* @param array $aLastClasses
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($sId = null, $aLastClasses = [])
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->SetEndpoint(static::DEFAULT_ENDPOINT_REL_URL);
|
||||
$this->SetLastQueries($aLastClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the search form endpoint URL.
|
||||
* If $bRelativeUrl is true, then $sEndpoint will be complete with the app_root_url
|
||||
*
|
||||
* @param string $sEndpoint URL to the endpoint
|
||||
* @param bool $bRelativeUrl Whether or not the $sEndpoint parameter is a relative URL
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function SetEndpoint($sEndpoint, $bRelativeUrl = true)
|
||||
{
|
||||
$this->sEndpoint = (($bRelativeUrl) ? utils::GetAbsoluteUrlAppRoot() : '') . $sEndpoint;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the absolute URL of the search form
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetEndpoint()
|
||||
{
|
||||
return $this->sEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the last queries at once
|
||||
*
|
||||
* @param array $aLastQueries
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetLastQueries($aLastQueries)
|
||||
{
|
||||
$this->aLastQueries = $aLastQueries;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last queries (query itself, label as HTML)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetLastQueries()
|
||||
{
|
||||
return $this->aLastQueries;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\GlobalSearch;
|
||||
|
||||
|
||||
/**
|
||||
* Class GlobalSearchFactory
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\GlobalSearch
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class GlobalSearchFactory
|
||||
{
|
||||
/**
|
||||
* Make a GlobalSearch component with the history entries from the current user
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearch
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function MakeFromUserHistory()
|
||||
{
|
||||
$aLastClasses = GlobalSearchHelper::GetLastQueries();
|
||||
|
||||
return new GlobalSearch(GlobalSearch::BLOCK_CODE, $aLastClasses);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\GlobalSearch;
|
||||
namespace Combodo\iTop\Application\UI\Component\GlobalSearch;
|
||||
|
||||
|
||||
use appUserPreferences;
|
||||
@@ -27,7 +27,8 @@ use utils;
|
||||
* Class GlobalSearchHelper
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\GlobalSearch
|
||||
* @package Combodo\iTop\Application\UI\Component\GlobalSearch
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class GlobalSearchHelper
|
||||
224
sources/application/UI/Component/PopoverMenu/PopoverMenu.php
Normal file
224
sources/application/UI/Component/PopoverMenu/PopoverMenu.php
Normal file
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\PopoverMenu;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class PopoverMenu
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\PopoverMenu
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class PopoverMenu extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-popover-menu';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/popover-menu/layout';
|
||||
//const JS_TEMPLATE_REl_PATH = 'components/popover-menu/layout';
|
||||
const JS_FILES_REL_PATH = [
|
||||
'js/components/popover-menu.js',
|
||||
];
|
||||
|
||||
/** @var array $aSections */
|
||||
protected $aSections;
|
||||
|
||||
/**
|
||||
* PopoverMenu constructor.
|
||||
*
|
||||
* @param string|null $sId
|
||||
*/
|
||||
public function __construct($sId = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->aSections = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a section $sId if not already existing.
|
||||
* Important: It does not reset the section.
|
||||
*
|
||||
* @param string $sId
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddSection($sId)
|
||||
{
|
||||
if (false === $this->HasSection($sId))
|
||||
{
|
||||
$this->aSections[$sId] = [
|
||||
'aItems' => [],
|
||||
];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the $sId section.
|
||||
* Note: If the section does not exist, we silently proceed anyway.
|
||||
*
|
||||
* @param string $sId
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function RemoveSection($sId)
|
||||
{
|
||||
if (true === $this->HasSection($sId))
|
||||
{
|
||||
unset($this->aSections[$sId]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the $sId section exists
|
||||
*
|
||||
* @param string $sId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasSection($sId)
|
||||
{
|
||||
return array_key_exists($sId, $this->aSections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the $sId section from all its items.
|
||||
*
|
||||
* @param string $sId
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function ClearSection($sId)
|
||||
{
|
||||
if (false === $this->HasSection($sId))
|
||||
{
|
||||
throw new Exception('Could not clear section "'.$sId.'" as it does not exist in the "'.$this->GetId().'" menu');
|
||||
}
|
||||
|
||||
$this->aSections[$sId]['aItems'] = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sections
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetSections()
|
||||
{
|
||||
return $this->aSections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the $oItem in the $sSectionId. If an item with the same ID already exists it will be overwritten.
|
||||
*
|
||||
* @param string $sSectionId
|
||||
* @param \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem $oItem
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function AddItem($sSectionId, PopoverMenuItem $oItem)
|
||||
{
|
||||
if(false === $this->HasSection($sSectionId))
|
||||
{
|
||||
throw new Exception('Could not add an item to the "'.$sSectionId.'" section has it does not seem to exist in the "'.$this->GetId().'" menu.');
|
||||
}
|
||||
|
||||
$this->aSections[$sSectionId]['aItems'][$oItem->GetId()] = $oItem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the $sItemId from the $sSectionId.
|
||||
* Note: If the item is not in the section, we proceed silently.
|
||||
*
|
||||
* @param string $sSectionId
|
||||
* @param string $sItemId
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function RemoveItem($sSectionId, $sItemId)
|
||||
{
|
||||
if(false === $this->HasSection($sSectionId))
|
||||
{
|
||||
throw new Exception('Could not remove en item from the "'.$sSectionId.'" as it does not seem to exist in the "'.$this->GetId().'" menu.');
|
||||
}
|
||||
|
||||
if(array_key_exists($sItemId, $this->aSections[$sSectionId]['aItems']))
|
||||
{
|
||||
unset($this->aSections[$sSectionId]['aItems'][$sItemId]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all $aItems at once in the $sSectionId, overwriting all existing.
|
||||
*
|
||||
* @param string $sSectionId
|
||||
* @param PopoverMenuItem[] $aItems
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function SetItems($sSectionId, $aItems)
|
||||
{
|
||||
if(false === $this->HasSection($sSectionId))
|
||||
{
|
||||
throw new Exception('Could not set items to the "'.$sSectionId.'" section has it does not seem to exist in the "'.$this->GetId().'" menu.');
|
||||
}
|
||||
|
||||
$this->aSections[$sSectionId]['aItems'] = $aItems;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetSubBlocks()
|
||||
{
|
||||
$aSubBlocks = [];
|
||||
|
||||
foreach($this->aSections as $sSectionId => $aSectionData)
|
||||
{
|
||||
foreach($aSectionData['aItems'] as $sItemId => $oItem)
|
||||
{
|
||||
$aSubBlocks[$sItemId] = $oItem;
|
||||
}
|
||||
}
|
||||
|
||||
return $aSubBlocks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\PopoverMenu;
|
||||
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopupMenuItemFactory;
|
||||
use Dict;
|
||||
use JSPopupMenuItem;
|
||||
use MetaModel;
|
||||
use URLPopupMenuItem;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class PopoverMenuFactory
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\PopoverMenu
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class PopoverMenuFactory
|
||||
{
|
||||
/**
|
||||
* Make a standard NavigationMenu layout for backoffice pages
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu
|
||||
* @throws \CoreException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function MakeUserMenuForNavigationMenu()
|
||||
{
|
||||
$oMenu = new PopoverMenu('ibo-navigation-menu--user-menu');
|
||||
|
||||
// Allowed portals
|
||||
$aAllowedPortalsItems = static::PrepareAllowedPortalsItemsForUserMenu();
|
||||
if(!empty($aAllowedPortalsItems))
|
||||
{
|
||||
$oMenu->AddSection('allowed_portals')
|
||||
->SetItems('allowed_portals', $aAllowedPortalsItems);
|
||||
}
|
||||
|
||||
// User related pages
|
||||
$oMenu->AddSection('user_related')
|
||||
->SetItems('user_related', static::PrepareUserRelatedItemsForUserMenu());
|
||||
|
||||
// Misc links
|
||||
$oMenu->AddSection('misc')
|
||||
->SetItems('misc', static::PrepareMiscItemsForUserMenu());
|
||||
|
||||
return $oMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the allowed portals items for the current user
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem[]
|
||||
*/
|
||||
protected static function PrepareAllowedPortalsItemsForUserMenu()
|
||||
{
|
||||
$aItems = [];
|
||||
foreach (UserRights::GetAllowedPortals() as $aAllowedPortal)
|
||||
{
|
||||
if ($aAllowedPortal['id'] !== 'backoffice')
|
||||
{
|
||||
$oPopupMenuItem = new URLPopupMenuItem(
|
||||
'portal:'.$aAllowedPortal['id'],
|
||||
Dict::S($aAllowedPortal['label']),
|
||||
$aAllowedPortal['url'],
|
||||
'_blank'
|
||||
);
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem($oPopupMenuItem);
|
||||
}
|
||||
}
|
||||
|
||||
return $aItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user related items (preferences, change password, log off, ...)
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem[]
|
||||
* @throws \CoreException
|
||||
*/
|
||||
protected static function PrepareUserRelatedItemsForUserMenu()
|
||||
{
|
||||
$aItems = [];
|
||||
|
||||
// Preferences
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new URLPopupMenuItem(
|
||||
'UI:Preferences',
|
||||
Dict::S('UI:Preferences'),
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/preferences.php'
|
||||
)
|
||||
);
|
||||
|
||||
// Archive mode
|
||||
if(true === utils::IsArchiveMode())
|
||||
{
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new JSPopupMenuItem(
|
||||
'UI:ArchiveModeOff',
|
||||
Dict::S('UI:ArchiveModeOff'),
|
||||
'return ArchiveMode(false);'
|
||||
)
|
||||
);
|
||||
}
|
||||
elseif(UserRights::CanBrowseArchive())
|
||||
{
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new JSPopupMenuItem(
|
||||
'UI:ArchiveModeOn',
|
||||
Dict::S('UI:ArchiveModeOn'),
|
||||
'return ArchiveMode(true);'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Logoff
|
||||
if(utils::CanLogOff())
|
||||
{
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new URLPopupMenuItem(
|
||||
'UI:LogOffMenu',
|
||||
Dict::S('UI:LogOffMenu'),
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/logoff.php?operation=do_logoff'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Change password
|
||||
if (UserRights::CanChangePassword())
|
||||
{
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new URLPopupMenuItem(
|
||||
'UI:ChangePwdMenu',
|
||||
Dict::S('UI:ChangePwdMenu'),
|
||||
utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=change_pwd'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: iPopupMenuExtension::MENU_USER_ACTIONS
|
||||
|
||||
return $aItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the misc. items for the user menu (online doc., about box)
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem[]
|
||||
*/
|
||||
protected static function PrepareMiscItemsForUserMenu()
|
||||
{
|
||||
$aItems = [];
|
||||
|
||||
// Online documentation
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new URLPopupMenuItem(
|
||||
'UI:Help',
|
||||
Dict::S('UI:Help'),
|
||||
MetaModel::GetConfig()->Get('online_help'),
|
||||
'_blank'
|
||||
)
|
||||
);
|
||||
|
||||
// About box
|
||||
$aItems[] = PopupMenuItemFactory::MakeFromApplicationPopupMenuItem(
|
||||
new JSPopupMenuItem(
|
||||
'UI:AboutBox',
|
||||
Dict::S('UI:AboutBox'),
|
||||
'return ShowAboutBox();'
|
||||
)
|
||||
);
|
||||
|
||||
return $aItems;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem;
|
||||
|
||||
|
||||
/**
|
||||
* Class JsPopoverMenuItem
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class JsPopoverMenuItem extends PopoverMenuItem
|
||||
{
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/popover-menu/item/mode_js';
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem;
|
||||
|
||||
|
||||
use ApplicationPopupMenuItem;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
|
||||
/**
|
||||
* Class PopoverMenuItem
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class PopoverMenuItem extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-popover-menu--item';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/popover-menu/item/layout';
|
||||
|
||||
/** @var \ApplicationPopupMenuItem $oPopupMenuItem We decorate the class with the original \ApplicationPopupMenuItem as it is used among the application (backoffice, portal, extensions) and cannot be refactored without BC breaks */
|
||||
protected $oPopupMenuItem;
|
||||
|
||||
/**
|
||||
* PopoverMenuItem constructor.
|
||||
*
|
||||
* @param \ApplicationPopupMenuItem $oPopupMenuItem
|
||||
*/
|
||||
public function __construct(ApplicationPopupMenuItem $oPopupMenuItem)
|
||||
{
|
||||
$this->oPopupMenuItem = $oPopupMenuItem;
|
||||
parent::__construct(/* ID will be generated from $oPopupMenuItem */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function GenerateId()
|
||||
{
|
||||
return static::BLOCK_CODE.'-'.$this->oPopupMenuItem->GetUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ApplicationPopupMenuItem::GetLabel()
|
||||
* @return string
|
||||
*/
|
||||
public function GetLabel()
|
||||
{
|
||||
return $this->oPopupMenuItem->GetLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ApplicationPopupMenuItem::SetCssClasses()
|
||||
* @param array $aCssClasses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetCssClasses($aCssClasses)
|
||||
{
|
||||
$this->oPopupMenuItem->SetCssClasses($aCssClasses);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ApplicationPopupMenuItem::AddCssClass()
|
||||
* @param string $sCssClass
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddCssClass($sCssClass)
|
||||
{
|
||||
$this->oPopupMenuItem->AddCssClass($sCssClass);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \ApplicationPopupMenuItem::GetCssClasses()
|
||||
* @return array
|
||||
*/
|
||||
public function GetCssClasses()
|
||||
{
|
||||
return $this->oPopupMenuItem->GetCssClasses();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem;
|
||||
|
||||
|
||||
|
||||
use ApplicationPopupMenuItem;
|
||||
use JSPopupMenuItem;
|
||||
use URLPopupMenuItem;
|
||||
|
||||
/**
|
||||
* Class PopupMenuItemFactory
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class PopupMenuItemFactory
|
||||
{
|
||||
/**
|
||||
* Make a standard NavigationMenu layout for backoffice pages
|
||||
*
|
||||
* @param \ApplicationPopupMenuItem $oItem
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItem
|
||||
*/
|
||||
public static function MakeFromApplicationPopupMenuItem(ApplicationPopupMenuItem $oItem)
|
||||
{
|
||||
$sNamespace = 'Combodo\\iTop\\Application\\UI\\Component\\PopoverMenu\\PopoverMenuItem\\';
|
||||
switch(true)
|
||||
{
|
||||
case $oItem instanceof URLPopupMenuItem:
|
||||
$sTargetClass = 'UrlPopoverMenuItem';
|
||||
break;
|
||||
case $oItem instanceof JSPopupMenuItem:
|
||||
$sTargetClass = 'JsPopoverMenuItem';
|
||||
break;
|
||||
default:
|
||||
$sTargetClass = 'PopoverMenuItem';
|
||||
break;
|
||||
}
|
||||
$sTargetClass = $sNamespace.$sTargetClass;
|
||||
|
||||
return new $sTargetClass($oItem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem;
|
||||
|
||||
|
||||
/**
|
||||
* Class UrlPopoverMenuItem
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuItem
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class UrlPopoverMenuItem extends PopoverMenuItem
|
||||
{
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/popover-menu/item/mode_url';
|
||||
}
|
||||
103
sources/application/UI/Component/QuickCreate/QuickCreate.php
Normal file
103
sources/application/UI/Component/QuickCreate/QuickCreate.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\QuickCreate;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use UserRights;
|
||||
|
||||
/**
|
||||
* Class QuickCreate
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\QuickCreate
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class QuickCreate extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-quick-create';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'components/quick-create/layout';
|
||||
const JS_TEMPLATE_REL_PATH = 'components/quick-create/layout';
|
||||
const JS_FILES_REL_PATH = [
|
||||
'js/selectize.min.js',
|
||||
'js/components/quick-create.js',
|
||||
];
|
||||
const CSS_FILES_REL_PATH = [
|
||||
'css/selectize.default.css',
|
||||
];
|
||||
|
||||
const DEFAULT_ENDPOINT_REL_URL = 'pages/UI.php';
|
||||
|
||||
/** @var array $aAvailableClasses */
|
||||
protected $aAvailableClasses;
|
||||
/** @var array $aLastClasses */
|
||||
protected $aLastClasses;
|
||||
|
||||
/**
|
||||
* QuickCreate constructor.
|
||||
*
|
||||
* @param string $sId
|
||||
* @param array $aLastClasses
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \DictExceptionMissingString
|
||||
*/
|
||||
public function __construct($sId = null, $aLastClasses = [])
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->aAvailableClasses = UserRights::GetAllowedClasses(UR_ACTION_CREATE, array('bizmodel'), true);
|
||||
$this->aLastClasses = $aLastClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the available classes (to create) for the current user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetAvailableClasses()
|
||||
{
|
||||
return $this->aAvailableClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the last classes at once
|
||||
*
|
||||
* @param array $aLastClasses
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetLastClasses($aLastClasses)
|
||||
{
|
||||
$this->aLastClasses = $aLastClasses;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last classes (class name, label as HTML, icon URL, ...)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetLastClasses()
|
||||
{
|
||||
return $this->aLastClasses;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Component\QuickCreate;
|
||||
|
||||
|
||||
/**
|
||||
* Class QuickCreateFactory
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Component\QuickCreate
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class QuickCreateFactory
|
||||
{
|
||||
/**
|
||||
* Make a QuickCreate component with the last classes from the current user
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreate
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public static function MakeFromUserHistory()
|
||||
{
|
||||
$aLastClasses = QuickCreateHelper::GetLastClasses();
|
||||
|
||||
return new QuickCreate(QuickCreate::BLOCK_CODE,$aLastClasses);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\QuickCreate;
|
||||
namespace Combodo\iTop\Application\UI\Component\QuickCreate;
|
||||
|
||||
|
||||
use appUserPreferences;
|
||||
@@ -29,7 +29,8 @@ use utils;
|
||||
* Class QuickCreateHelper
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\QuickCreate
|
||||
* @package Combodo\iTop\Application\UI\Component\QuickCreate
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class QuickCreateHelper
|
||||
222
sources/application/UI/Layout/NavigationMenu/NavigationMenu.php
Normal file
222
sources/application/UI/Layout/NavigationMenu/NavigationMenu.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Layout\NavigationMenu;
|
||||
|
||||
|
||||
use ApplicationContext;
|
||||
use ApplicationMenu;
|
||||
use appUserPreferences;
|
||||
use Combodo\iTop\Application\Branding;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
use Dict;
|
||||
use MetaModel;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class NavigationMenu
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Layout\NavigationMenu
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class NavigationMenu extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-navigation-menu';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'layouts/navigation-menu/layout';
|
||||
const JS_TEMPLATE_REL_PATH = 'layouts/navigation-menu/layout';
|
||||
const JS_FILES_REL_PATH = [
|
||||
'js/layouts/navigation-menu.js',
|
||||
];
|
||||
|
||||
/** @var string $sAppRevisionNumber */
|
||||
protected $sAppRevisionNumber;
|
||||
/** @var string $sAppSquareIconUrl */
|
||||
protected $sAppSquareIconUrl;
|
||||
/** @var string $sAppFullIconUrl */
|
||||
protected $sAppFullIconUrl;
|
||||
/** @var string $sAppIconLink */
|
||||
protected $sAppIconLink;
|
||||
/** @var array $aMenuGroups */
|
||||
protected $aMenuGroups;
|
||||
/** @var array $aUserData */
|
||||
protected $aUserData;
|
||||
/** @var \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu $oUserMenu */
|
||||
private $oUserMenu;
|
||||
/** @var bool $bIsExpanded */
|
||||
protected $bIsExpanded;
|
||||
|
||||
/**
|
||||
* NavigationMenu constructor.
|
||||
*
|
||||
* @param string|null $sId
|
||||
* @param \ApplicationContext $oAppContext
|
||||
* @param \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu $oUserMenu
|
||||
*
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($sId, ApplicationContext $oAppContext, PopoverMenu $oUserMenu)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
|
||||
$this->sAppRevisionNumber = utils::GetAppRevisionNumber();
|
||||
$this->sAppSquareIconUrl = Branding::GetSquareMainLogoAbsoluteUrl();
|
||||
$this->sAppFullIconUrl = Branding::GetFullMainLogoAbsoluteUrl();
|
||||
$this->sAppIconLink = MetaModel::GetConfig()->Get('app_icon_url');
|
||||
$this->aMenuGroups = ApplicationMenu::GetMenuGroups($oAppContext->GetAsHash());
|
||||
$this->oUserMenu = $oUserMenu;
|
||||
|
||||
$this->ComputeExpandedState();
|
||||
$this->ComputeUserData();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetAppRevisionNumber()
|
||||
{
|
||||
return $this->sAppRevisionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetAppSquareIconUrl()
|
||||
{
|
||||
return $this->sAppSquareIconUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetAppFullIconUrl()
|
||||
{
|
||||
return $this->sAppFullIconUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetAppIconLink()
|
||||
{
|
||||
return $this->sAppIconLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetMenuGroups()
|
||||
{
|
||||
return $this->aMenuGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetUserData()
|
||||
{
|
||||
return $this->aUserData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenu
|
||||
*/
|
||||
public function GetUserMenu()
|
||||
{
|
||||
return $this->oUserMenu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the menu is expanded
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function IsExpanded()
|
||||
{
|
||||
return $this->bIsExpanded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetSubBlocks()
|
||||
{
|
||||
return [$this->oUserMenu->GetId() => $this->oUserMenu];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute if the menu is expanded or collapsed
|
||||
*
|
||||
* @return $this
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
protected function ComputeExpandedState()
|
||||
{
|
||||
$bIsExpanded = false;
|
||||
// Check if menu should be opened only if we re not in demo mode
|
||||
if (false === MetaModel::GetConfig()->Get('demo_mode'))
|
||||
{
|
||||
if (utils::ReadParam('force_menu_pane', null) === 0)
|
||||
{
|
||||
$bIsExpanded = false;
|
||||
}
|
||||
elseif (appUserPreferences::GetPref('menu_pane', 'closed') === 'opened')
|
||||
{
|
||||
$bIsExpanded = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->bIsExpanded = $bIsExpanded;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the user data displayed in the menu (organization, name, picture, ...)
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function ComputeUserData()
|
||||
{
|
||||
$aData = [
|
||||
'sOrganization' => UserRights::GetContactOrganizationFriendlyname(),
|
||||
'sFirstname' => UserRights::GetContactFirstname(),
|
||||
'sPictureUrl' => UserRights::GetContactPicture(),
|
||||
];
|
||||
|
||||
// Logon message
|
||||
$sLogonMessageDictCode = (UserRights::IsAdministrator()) ? 'UI:LoggedAsMessage+Admin' : 'UI:LoggedAsMessage';
|
||||
$aData['sLogonMessage'] = Dict::Format($sLogonMessageDictCode, UserRights::GetUser());
|
||||
|
||||
$this->aUserData = $aData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Layout\NavigationMenu;
|
||||
|
||||
|
||||
use ApplicationContext;
|
||||
use Combodo\iTop\Application\UI\Component\PopoverMenu\PopoverMenuFactory;
|
||||
|
||||
/**
|
||||
* Class NavigationMenuFactory
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Layout\NavigationMenu
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class NavigationMenuFactory
|
||||
{
|
||||
/**
|
||||
* Make a standard NavigationMenu layout for backoffice pages
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Layout\NavigationMenu\NavigationMenu
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public static function MakeStandard()
|
||||
{
|
||||
return new NavigationMenu(
|
||||
NavigationMenu::BLOCK_CODE,
|
||||
new ApplicationContext(),
|
||||
PopoverMenuFactory::MakeUserMenuForNavigationMenu()
|
||||
);
|
||||
}
|
||||
}
|
||||
185
sources/application/UI/Layout/TopBar/TopBar.php
Normal file
185
sources/application/UI/Layout/TopBar/TopBar.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Layout\TopBar;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\Breadcrumbs\Breadcrumbs;
|
||||
use Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearch;
|
||||
use Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreate;
|
||||
use Combodo\iTop\Application\UI\UIBlock;
|
||||
|
||||
/**
|
||||
* Class TopBar
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Layout\TopBar
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class TopBar extends UIBlock
|
||||
{
|
||||
const BLOCK_CODE = 'ibo-top-bar';
|
||||
|
||||
const HTML_TEMPLATE_REL_PATH = 'layouts/top-bar/layout';
|
||||
|
||||
/** @var QuickCreate|null $oQuickCreate */
|
||||
protected $oQuickCreate;
|
||||
/** @var GlobalSearch|null $oGlobalSearch */
|
||||
protected $oGlobalSearch;
|
||||
/** @var Breadcrumbs|null $oBreadcrumbs */
|
||||
protected $oBreadcrumbs;
|
||||
|
||||
/**
|
||||
* TopBar constructor.
|
||||
*
|
||||
* @param string $sId
|
||||
* @param \Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreate $oQuickCreate
|
||||
* @param \Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearch $oGlobalSearch
|
||||
* @param \Combodo\iTop\Application\UI\Component\Breadcrumbs\Breadcrumbs $oBreadcrumbs
|
||||
*/
|
||||
public function __construct($sId = null, QuickCreate $oQuickCreate = null, GlobalSearch $oGlobalSearch = null, Breadcrumbs $oBreadcrumbs = null)
|
||||
{
|
||||
parent::__construct($sId);
|
||||
|
||||
$this->oQuickCreate = $oQuickCreate;
|
||||
$this->oGlobalSearch = $oGlobalSearch;
|
||||
$this->oBreadcrumbs = $oBreadcrumbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the quick create component
|
||||
*
|
||||
* @param \Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreate $oQuickCreate
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetQuickCreate(QuickCreate $oQuickCreate)
|
||||
{
|
||||
$this->oQuickCreate = $oQuickCreate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the global search component
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreate|null
|
||||
*/
|
||||
public function GetQuickCreate()
|
||||
{
|
||||
return $this->oQuickCreate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the quick create has been set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasQuickCreate()
|
||||
{
|
||||
return ($this->oQuickCreate !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the global search component
|
||||
*
|
||||
* @param \Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearch $oGlobalSearch
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetGlobalSearch(GlobalSearch $oGlobalSearch)
|
||||
{
|
||||
$this->oGlobalSearch = $oGlobalSearch;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the global search component
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearch|null
|
||||
*/
|
||||
public function GetGlobalSearch()
|
||||
{
|
||||
return $this->oGlobalSearch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the global search has been set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasGlobalSearch()
|
||||
{
|
||||
return ($this->oGlobalSearch !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the breadcrumbs component
|
||||
*
|
||||
* @param \Combodo\iTop\Application\UI\Component\Breadcrumbs\Breadcrumbs $oBreadcrumbs
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetBreadcrumbs(Breadcrumbs $oBreadcrumbs)
|
||||
{
|
||||
$this->oBreadcrumbs = $oBreadcrumbs;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the breadcrumbs component
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Component\Breadcrumbs\Breadcrumbs|null
|
||||
*/
|
||||
public function GetBreadcrumbs()
|
||||
{
|
||||
return $this->oBreadcrumbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the breadcrumb has been set
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function HasBreadcrumbs()
|
||||
{
|
||||
return ($this->oBreadcrumbs !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetSubBlocks()
|
||||
{
|
||||
$aSubBlocks = [];
|
||||
|
||||
$aSubBlocksNames = ['QuickCreate', 'GlobalSearch', 'Breadcrumbs'];
|
||||
foreach($aSubBlocksNames as $sSubBlockName)
|
||||
{
|
||||
$sHasMethodName = 'Has'.$sSubBlockName;
|
||||
if(true === call_user_func_array([$this, $sHasMethodName], []))
|
||||
{
|
||||
$sPropertyName = 'o'.$sSubBlockName;
|
||||
$aSubBlocks[$this->$sPropertyName->GetId()] = $this->$sPropertyName;
|
||||
}
|
||||
}
|
||||
|
||||
return $aSubBlocks;
|
||||
}
|
||||
}
|
||||
71
sources/application/UI/Layout/TopBar/TopBarFactory.php
Normal file
71
sources/application/UI/Layout/TopBar/TopBarFactory.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI\Layout\TopBar;
|
||||
|
||||
|
||||
use Combodo\iTop\Application\UI\Component\Breadcrumbs\Breadcrumbs;
|
||||
use Combodo\iTop\Application\UI\Component\GlobalSearch\GlobalSearchFactory;
|
||||
use Combodo\iTop\Application\UI\Component\QuickCreate\QuickCreateFactory;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class TopBarFactory
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @package Combodo\iTop\Application\UI\Layout\TopBar
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class TopBarFactory
|
||||
{
|
||||
/**
|
||||
* Make a standard TopBar layout for backoffice pages
|
||||
*
|
||||
* @param array|null $aBreadcrumbsEntry Current breadcrumbs entry to add
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\Layout\TopBar\TopBar
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public static function MakeStandard($aBreadcrumbsEntry = null)
|
||||
{
|
||||
$oTopBar = new TopBar();
|
||||
|
||||
if(utils::GetConfig()->Get('quick_create.enabled') === true)
|
||||
{
|
||||
$oTopBar->SetQuickCreate(QuickCreateFactory::MakeFromUserHistory());
|
||||
}
|
||||
|
||||
if(utils::GetConfig()->Get('global_search.enabled') === true)
|
||||
{
|
||||
$oTopBar->SetGlobalSearch(GlobalSearchFactory::MakeFromUserHistory());
|
||||
}
|
||||
|
||||
if(utils::GetConfig()->Get('breadcrumb.enabled') === true)
|
||||
{
|
||||
$oBreadcrumbs = new Breadcrumbs(Breadcrumbs::BLOCK_CODE, $aBreadcrumbsEntry);
|
||||
|
||||
$oTopBar->SetBreadcrumbs($oBreadcrumbs);
|
||||
}
|
||||
|
||||
return $oTopBar;
|
||||
}
|
||||
}
|
||||
196
sources/application/UI/UIBlock.php
Normal file
196
sources/application/UI/UIBlock.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI;
|
||||
|
||||
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class UIBlock
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
abstract class UIBlock implements iUIBlock
|
||||
{
|
||||
/** @var string BLOCK_CODE The block code to use to generate the identifier, the CSS/JS prefixes, ... */
|
||||
const BLOCK_CODE = 'ibo-block';
|
||||
|
||||
/** @var string|null GLOBAL_TEMPLATE_REL_PATH Relative path (from <ITOP>/templates/) to the "global" TWIG template which contains HTML, JS inline, JS files, CSS inline, CSS files. Should not be used to often as JS/CSS files would be duplicated making browser parsing time way longer. */
|
||||
const GLOBAL_TEMPLATE_REL_PATH = null;
|
||||
/** @var string|null HTML_TEMPLATE_REL_PATH Relative path (from <ITOP>/templates/) to the HTML template */
|
||||
const HTML_TEMPLATE_REL_PATH = null;
|
||||
/** @var array JS_FILES_REL_PATH Relative paths (from <ITOP>/) to the JS files */
|
||||
const JS_FILES_REL_PATH = [];
|
||||
/** @var string|null JS_TEMPLATE_REL_PATH Relative path (from <ITOP>/templates/) to the JS template */
|
||||
const JS_TEMPLATE_REL_PATH = null;
|
||||
/** @var array CSS_FILES_REL_PATH Relative paths (from <ITOP>/) to the CSS files */
|
||||
const CSS_FILES_REL_PATH = [];
|
||||
/** @var string|null CSS_TEMPLATE_REL_PATH Relative path (from <ITOP>/templates/) to the CSS template */
|
||||
const CSS_TEMPLATE_REL_PATH = null;
|
||||
|
||||
/** @var string ENUM_BLOCK_FILES_TYPE_JS */
|
||||
const ENUM_BLOCK_FILES_TYPE_JS = 'js';
|
||||
/** @var string ENUM_BLOCK_FILES_TYPE_CSS */
|
||||
const ENUM_BLOCK_FILES_TYPE_CSS = 'css';
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function GetGlobalTemplateRelPath()
|
||||
{
|
||||
return static::GLOBAL_TEMPLATE_REL_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function GetHtmlTemplateRelPath()
|
||||
{
|
||||
return static::HTML_TEMPLATE_REL_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function GetJsTemplateRelPath()
|
||||
{
|
||||
return static::JS_TEMPLATE_REL_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function GetJsFilesRelPaths()
|
||||
{
|
||||
return static::JS_FILES_REL_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function GetCssTemplateRelPath()
|
||||
{
|
||||
return static::CSS_TEMPLATE_REL_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function GetCssFilesRelPaths()
|
||||
{
|
||||
return static::CSS_FILES_REL_PATH;
|
||||
}
|
||||
|
||||
|
||||
/** @var string $sId */
|
||||
protected $sId;
|
||||
|
||||
/**
|
||||
* UIBlock constructor.
|
||||
*
|
||||
* @param string|null $sId
|
||||
*/
|
||||
public function __construct($sId = null)
|
||||
{
|
||||
$this->sId = ($sId !== null) ? $sId : $this->GenerateId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a unique ID for the block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function GenerateId()
|
||||
{
|
||||
return uniqid(static::BLOCK_CODE.'-');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function GetId()
|
||||
{
|
||||
return $this->sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return \Combodo\iTop\Application\UI\UIBlock[]
|
||||
*/
|
||||
public function GetSubBlocks()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetJsFilesUrlRecursively($bAbsoluteUrl = false)
|
||||
{
|
||||
return $this->GetFilesUrlRecursively(static::ENUM_BLOCK_FILES_TYPE_JS, $bAbsoluteUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetCssFilesUrlRecursively($bAbsoluteUrl = false)
|
||||
{
|
||||
return $this->GetFilesUrlRecursively(static::ENUM_BLOCK_FILES_TYPE_CSS, $bAbsoluteUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the URL of the block $sFilesType and its sub blocks.
|
||||
* URL is relative unless the $bAbsoluteUrl is set to true.
|
||||
*
|
||||
* @param string $sFilesType (see static::ENUM_BLOCK_FILES_TYPE_JS, static::ENUM_BLOCK_FILES_TYPE_CSS)
|
||||
* @param bool $bAbsoluteUrl
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function GetFilesUrlRecursively($sFilesType, $bAbsoluteUrl = false)
|
||||
{
|
||||
$aFiles = [];
|
||||
$sFilesRelPathMethodName = 'Get'.ucfirst($sFilesType).'FilesRelPaths';
|
||||
$sFilesAbsUrlMethodName = 'Get'.ucfirst($sFilesType).'FilesUrlRecursively';
|
||||
|
||||
// Files from the block itself
|
||||
foreach($this::$sFilesRelPathMethodName() as $sFilePath)
|
||||
{
|
||||
$aFiles[] = (($bAbsoluteUrl === true) ? utils::GetAbsoluteUrlAppRoot() : '').$sFilePath;
|
||||
}
|
||||
|
||||
// Files from its sub blocks
|
||||
foreach($this->GetSubBlocks() as $sSubBlockName => $oSubBlock)
|
||||
{
|
||||
$aFiles = array_merge(
|
||||
$aFiles,
|
||||
call_user_func_array([$oSubBlock, $sFilesAbsUrlMethodName], [$bAbsoluteUrl])
|
||||
);
|
||||
}
|
||||
|
||||
return $aFiles;
|
||||
}
|
||||
}
|
||||
108
sources/application/UI/iUIBlock.php
Normal file
108
sources/application/UI/iUIBlock.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Application\UI;
|
||||
|
||||
|
||||
/**
|
||||
* Interface iUIBlock
|
||||
*
|
||||
* @package Combodo\iTop\Application\UI
|
||||
* @internal
|
||||
* @since 2.8.0
|
||||
*/
|
||||
interface iUIBlock
|
||||
{
|
||||
/**
|
||||
* Return the relative path (from <ITOP>/templates/) of the global template (HTML, JS, CSS) to use or null if it's not provided. Should not be used to often as JS/CSS files would be duplicated making the browser parsing time way longer.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function GetGlobalTemplateRelPath();
|
||||
|
||||
/**
|
||||
* Return the relative path (from <ITOP>/templates/) of the HTML template to use or null if no HTML to render
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function GetHtmlTemplateRelPath();
|
||||
|
||||
/**
|
||||
* Return the relative path (from <ITOP>/templates/) of the JS template to use or null if there is no inline JS to render
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function GetJsTemplateRelPath();
|
||||
|
||||
/**
|
||||
* Return an array of the relative paths (from <ITOP>/) of the JS files to use
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetJsFilesRelPaths();
|
||||
|
||||
/**
|
||||
* Return the relative path (from <ITOP>/templates/) of the CSS template to use or null if there is no inline CSS to render
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function GetCssTemplateRelPath();
|
||||
|
||||
/**
|
||||
* Return an array of the relative paths (from <ITOP>/) of the CSS files to use
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetCssFilesRelPaths();
|
||||
|
||||
/**
|
||||
* Return the ID of the block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetId();
|
||||
|
||||
/**
|
||||
* Return an array iUIBlock embedded in this iUIBlock
|
||||
*
|
||||
* @return \Combodo\iTop\Application\UI\iUIBlock[]
|
||||
*/
|
||||
public function GetSubBlocks();
|
||||
|
||||
/**
|
||||
* Return an array of the JS files URL of the block and its sub blocks.
|
||||
* URL is relative unless the $bAbsolutePath is set to true.
|
||||
*
|
||||
* @param bool $bAbsoluteUrl
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetJsFilesUrlRecursively($bAbsoluteUrl = false);
|
||||
|
||||
/**
|
||||
* Return an array of the CSS files URL of the block and its sub blocks.
|
||||
* URL is relative unless the $bAbsolutePath is set to true.
|
||||
*
|
||||
* @param bool $bAbsoluteUrl
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetCssFilesUrlRecursively($bAbsoluteUrl = false);
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<div id="{{ aBreadCrumbs.sId }}" class="ibo-breadcrumbs"></div>
|
||||
<div id="{{ oBreadcrumbs.Id }}" class="ibo-breadcrumbs"></div>
|
||||
6
templates/components/breadcrumbs/layout.js.twig
Normal file
6
templates/components/breadcrumbs/layout.js.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
// TODO: We need to find a clean way to launch this script only once the JS scripts are loaded
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
setTimeout(function(){
|
||||
$('#{{ oBreadcrumbs.Id }}').breadcrumbs({{ oBreadcrumbs.JsWidgetOptions|json_encode|raw }});
|
||||
}, 500);
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
<div id="{{ aGlobalSearch.sId }}" class="ibo-global-search" data-role="ibo-global-search">
|
||||
<form action="{{ aGlobalSearch.sEndpoint }}" method="post" class="ibo-global-search--head" data-role="ibo-global-search--head">
|
||||
<div id="{{ oGlobalSearch.Id }}" class="ibo-global-search" data-role="ibo-global-search">
|
||||
<form action="{{ oGlobalSearch.Endpoint }}" method="post" class="ibo-global-search--head" data-role="ibo-global-search--head">
|
||||
<a href="#" class="ibo-global-search--icon fas fa-search" data-role="ibo-global-search--icon" data-tooltip-content="{{ 'UI:Component:GlobalSearch:Tooltip'|dict_s }}" data-tooltip-placement="bottom-start" data-tooltip-distance-offset="25"></a>
|
||||
<input type="text" name="query" class="ibo-global-search--input" data-role="ibo-global-search--input" placeholder="{{ 'UI:Component:GlobalSearch:Input:Placeholder'|dict_s }}" />
|
||||
</form>
|
||||
@@ -9,8 +9,8 @@
|
||||
<span>{{ 'UI:Component:GlobalSearch:Recents:Title'|dict_s }}</span>
|
||||
</div>
|
||||
<div class="ibo-global-search--compartment-content" data-role="ibo-global-search--compartment-content">
|
||||
{% if aGlobalSearch.aLastQueries|length > 0 %}
|
||||
{% for aQuery in aGlobalSearch.aLastQueries %}
|
||||
{% if oGlobalSearch.LastQueries|length > 0 %}
|
||||
{% for aQuery in oGlobalSearch.LastQueries %}
|
||||
<a href="#" class="ibo-global-search--compartment-element" data-role="ibo-global-search--compartment-element" data-query-raw="{{ aQuery.query }}" title="{{ aQuery.query }}">
|
||||
{% if aQuery.icon_url is defined %}
|
||||
<img src="{{ aPage.sAbsoluteUrlAppRoot ~ aQuery.icon_url}}" class="ibo-global-search--compartment-element-image" />
|
||||
|
||||
6
templates/components/global-search/layout.js.twig
Normal file
6
templates/components/global-search/layout.js.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
// TODO: We need to find a clean way to launch this script only once the JS scripts are loaded
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
setTimeout(function(){
|
||||
$('#{{ oGlobalSearch.Id }}').global_search();
|
||||
}, 500);
|
||||
});
|
||||
1
templates/components/popover-menu/item/layout.html.twig
Normal file
1
templates/components/popover-menu/item/layout.html.twig
Normal file
@@ -0,0 +1 @@
|
||||
<div>Item: {{ oPopoverMenuItem.Id }}</div>
|
||||
13
templates/components/popover-menu/layout.html.twig
Normal file
13
templates/components/popover-menu/layout.html.twig
Normal file
@@ -0,0 +1,13 @@
|
||||
<div {% if oPopoverMenu.Id is defined %}id="{{ oPopoverMenu.Id }}"{% endif %} class="ibo-popover-menu" data-role="ibo-popover-menu">
|
||||
<div class="ibo-popover-menu--menu">
|
||||
{% for aSection in oPopoverMenu.Sections %}
|
||||
{% if aSection.aItems|length > 0 %}
|
||||
<div class="ibo-popover-menu--section">
|
||||
{% for oPopoverMenuItem in aSection.aItems %}
|
||||
{{ render_block(oPopoverMenuItem) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +1,10 @@
|
||||
<div id="{{ aQuickCreate.sId }}" class="ibo-quick-create" data-role="ibo-quick-create">
|
||||
<form action="{{ aQuickCreate.sEndpoint }}" method="get" class="ibo-quick-create--head" data-role="ibo-quick-create--head">
|
||||
<div id="{{ oQuickCreate.Id }}" class="ibo-quick-create" data-role="ibo-quick-create">
|
||||
<form action="{{ oQuickCreate.Endpoint }}" method="get" class="ibo-quick-create--head" data-role="ibo-quick-create--head">
|
||||
<input type="hidden" name="operation" value="new" />
|
||||
<a href="#" class="ibo-quick-create--icon fas fa-plus" data-role="ibo-quick-create--icon" data-tooltip-content="{{ 'UI:Component:QuickCreate:Tooltip'|dict_s }}" data-tooltip-placement="bottom-start" data-tooltip-distance-offset="25"></a>
|
||||
<select name="class" class="ibo-quick-create--input" data-role="ibo-quick-create--input" placeholder="{{ 'UI:Component:QuickCreate:Input:Placeholder'|dict_s }}">
|
||||
<option value="">{{ 'UI:Component:QuickCreate:Input:Placeholder'|dict_s }}</option>
|
||||
{% for sClassCode, sClassLabel in aQuickCreate.aAvailableClasses %}
|
||||
{% for sClassCode, sClassLabel in oQuickCreate.AvailableClasses %}
|
||||
<option value="{{ sClassCode }}">{{ sClassLabel }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
@@ -15,8 +15,8 @@
|
||||
<span>{{ 'UI:Component:QuickCreate:Recents:Title'|dict_s }}</span>
|
||||
</div>
|
||||
<div class="ibo-quick-create--compartment-content" data-role="ibo-quick-create--compartment-content">
|
||||
{% if aQuickCreate.aLastClasses|length > 0 %}
|
||||
{% for aClass in aQuickCreate.aLastClasses %}
|
||||
{% if oQuickCreate.LastClasses|length > 0 %}
|
||||
{% for aClass in oQuickCreate.LastClasses %}
|
||||
<a href="{{ aClass.target_url }}" class="ibo-quick-create--compartment-element" data-role="ibo-quick-create--compartment-element" data-class-code="{{ aQuery.class }}">
|
||||
{% if aClass.icon_url is defined %}
|
||||
<img src="{{ aClass.icon_url}}" class="ibo-quick-create--compartment-element-image" />
|
||||
|
||||
6
templates/components/quick-create/layout.js.twig
Normal file
6
templates/components/quick-create/layout.js.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
// TODO: We need to find a clean way to launch this script only once the JS scripts are loaded
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
setTimeout(function(){
|
||||
$('#{{ oQuickCreate.Id }}').quick_create();
|
||||
}, 500);
|
||||
});
|
||||
@@ -1,8 +1,8 @@
|
||||
<nav id="{{ aNavigationMenu.sId }}" class="ibo-navigation-menu {% if aNavigationMenu.bIsExpanded == true %}ibo-navigation-menu--is-expanded{% endif %}">
|
||||
<nav id="{{ oNavigationMenu.Id }}" class="ibo-navigation-menu {% if NavigationMenu.IsExpanded == true %}ibo-navigation-menu--is-expanded{% endif %}">
|
||||
<div class="ibo-navigation-menu--body">
|
||||
<div class="ibo-navigation-menu--top-part">
|
||||
<a class="ibo-navigation-menu--square-company-logo" title="{{ aNavigationMenu.sAppRevisionNumber }}" href="{{ aNavigationMenu.sAppIconLink }}">
|
||||
<img src="{{ aNavigationMenu.sAppSquareIconUrl }}" alt="{{ 'UI:Layout:NavigationMenu:CompanyLogo:AltText'|dict_s }}" />
|
||||
<a class="ibo-navigation-menu--square-company-logo" title="{{ oNavigationMenu.AppRevisionNumber }}" href="{{ oNavigationMenu.AppIconLink }}">
|
||||
<img src="{{ oNavigationMenu.AppSquareIconUrl }}" alt="{{ 'UI:Layout:NavigationMenu:CompanyLogo:AltText'|dict_s }}" />
|
||||
</a>
|
||||
<a class="ibo-navigation-menu--toggler" data-role="ibo-navigation-menu--toggler" data-tooltip-content="{{ 'UI:Layout:NavigationMenu:Toggler:Tooltip'|dict_s }}" data-tooltip-placement="right" data-tooltip-distance-offset="20" href="#">
|
||||
<span class="ibo-navigation-menu--toggler-icon">
|
||||
@@ -13,12 +13,23 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="ibo-navigation-menu--middle-part">
|
||||
{% for aMenuGroup in aNavigationMenu.aMenuGroups %}
|
||||
{% for aMenuGroup in oNavigationMenu.MenuGroups %}
|
||||
{{ include('layouts/navigation-menu/menu-group.html.twig', { aMenuGroup: aMenuGroup }) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="ibo-navigation-menu--bottom-part">
|
||||
|
||||
<div class="ibo-navigation-menu--notifications">
|
||||
<div class="ibo-navigation-menu--notifications-toggler"></div>
|
||||
<div class="ibo-navigation-menu--notifications-menu"></div>
|
||||
</div>
|
||||
<div class="ibo-navigation-menu--user-info">
|
||||
<div class="ibo-navigation-menu--user-picture"></div>
|
||||
<div class="ibo-navigation-menu--user-welcome-message"></div>
|
||||
<div class="ibo-navigation-menu--user-organization"></div>
|
||||
<div class="ibo-navigation-menu--user-menu">
|
||||
{{ render_block(oNavigationMenu.UserMenu) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibo-navigation-menu--drawer" data-role="ibo-navigation-menu--drawer">
|
||||
@@ -29,7 +40,7 @@
|
||||
<span class="ibo-navigation-menu--menu-filter-hotkey">{{ 'UI:Layout:NavigationMenu:MenuFilter:Input:Hotkey'|dict_s }}</span>
|
||||
</div>
|
||||
<div class="ibo-navigation-menu--menu-groups">
|
||||
{% for aMenuGroup in aNavigationMenu.aMenuGroups %}
|
||||
{% for aMenuGroup in oNavigationMenu.MenuGroups %}
|
||||
{{ include('layouts/navigation-menu/menu-nodes.html.twig', { aMenuGroup: aMenuGroup }) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
6
templates/layouts/navigation-menu/layout.js.twig
Normal file
6
templates/layouts/navigation-menu/layout.js.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
// TODO: We need to find a clean way to launch this script only once the JS scripts are loaded
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
setTimeout(function(){
|
||||
$('#{{ oNavigationMenu.Id }}').navigation_menu();
|
||||
}, 500);
|
||||
});
|
||||
@@ -1,7 +1,13 @@
|
||||
<nav id="{{ aTopBar.sId }}" class="ibo-top-bar">
|
||||
<nav id="{{ oTopBar.Id }}" class="ibo-top-bar">
|
||||
<div class="ibo-top-bar--quick-actions">
|
||||
{{ include('components/quick-create/layout.html.twig', { aQuickCreate: aTopBar.aComponents.aQuickCreate }) }}
|
||||
{{ include('components/global-search/layout.html.twig', { aGlobalSearch: aTopBar.aComponents.aGlobalSearch }) }}
|
||||
{% if oTopBar.HasQuickCreate %}
|
||||
{{ render_block(oTopBar.QuickCreate) }}
|
||||
{% endif %}
|
||||
{% if oTopBar.HasGlobalSearch %}
|
||||
{{ render_block(oTopBar.GlobalSearch) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{{ include('components/breadcrumbs/layout.html.twig', { aBreadCrumbs: aTopBar.aComponents.aBreadCrumbs }) }}
|
||||
{% if oTopBar.HasBreadcrumbs %}
|
||||
{{ render_block(oTopBar.Breadcrumbs) }}
|
||||
{% endif %}
|
||||
</nav>
|
||||
@@ -33,9 +33,9 @@
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body data-gui-type="backoffice">
|
||||
{{ include('layouts/navigation-menu/layout.html.twig', { aNavigationMenu: aLayouts.aNavigationMenu }) }}
|
||||
{{ render_block(aLayouts.oNavigationMenu) }}
|
||||
<div id="ibo-page-container">
|
||||
{{ include('layouts/top-bar/layout.html.twig', { aTopBar: aLayouts.aTopBar }) }}
|
||||
{{ render_block(aLayouts.oTopBar) }}
|
||||
<main id="ibo-page-content">
|
||||
{{ aPage.aSanitizedContent|raw }}
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user