From 50bf0c9a27a8ce3c3073881f8f53247ce766a1c0 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Wed, 30 Sep 2020 17:46:11 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B02847=20-=20Rework=20of=20TabContainer=20?= =?UTF-8?q?/=20Tab=20-=20Add=20JS=20widget=20to=20handle=20front-end=20log?= =?UTF-8?q?ic=20and=20for=20better=20encapsulation=20-=20Move=20SCSS=20fil?= =?UTF-8?q?es=20to=20match=20convention=20-=20Update=20SCSS=20files=20-=20?= =?UTF-8?q?Remove=20unused=20SCSS=20file=20-=20Move=20HTML=20templates=20t?= =?UTF-8?q?o=20match=20convention=20-=20Remove=20unused=20HTML=20template?= =?UTF-8?q?=20-=20Renamed=20codes=20and=20folders=20to=20match=20conventio?= =?UTF-8?q?n=20-=20Update=20PHPDoc=20-=20Reformat=20code=20-=20Remove=20us?= =?UTF-8?q?age=20of=20return=20type=20hinting=20when=20using=20"self"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/backoffice/components/_ajaxtab.scss | 4 - css/backoffice/components/_all.scss | 5 +- css/backoffice/components/_tab.scss | 4 - css/backoffice/components/_tabcontainer.scss | 37 ---- .../tab-container/_tab-container.scss | 55 ++++++ .../components/tab-container/_tab.scss | 28 +++ css/ui-lightness/jqueryui.scss | 92 +++++----- js/layouts/tab-container.js | 172 ++++++++++++++---- .../UI/Layout/TabContainer/Tab/AjaxTab.php | 123 +++++++------ .../UI/Layout/TabContainer/Tab/Tab.php | 27 ++- .../UI/Layout/TabContainer/TabContainer.php | 5 +- sources/application/WebPage/TabManager.php | 2 +- sources/application/WebPage/iTopWebPage.php | 51 ------ .../layouts/tab-container/layout.html.twig | 31 ++++ .../layouts/tab-container/layout.js.twig | 1 + .../tab-container/tab/layout.html.twig | 9 + .../layouts/tabcontainer/layout.html.twig | 26 --- .../tabcontainer/tab/ajaxtab.html.twig | 2 - .../layouts/tabcontainer/tab/layout.html.twig | 2 - .../layouts/tabcontainer/tab/tab.html.twig | 9 - 20 files changed, 398 insertions(+), 287 deletions(-) delete mode 100644 css/backoffice/components/_ajaxtab.scss delete mode 100644 css/backoffice/components/_tab.scss delete mode 100644 css/backoffice/components/_tabcontainer.scss create mode 100644 css/backoffice/components/tab-container/_tab-container.scss create mode 100644 css/backoffice/components/tab-container/_tab.scss create mode 100644 templates/layouts/tab-container/layout.html.twig create mode 100644 templates/layouts/tab-container/layout.js.twig create mode 100644 templates/layouts/tab-container/tab/layout.html.twig delete mode 100644 templates/layouts/tabcontainer/layout.html.twig delete mode 100644 templates/layouts/tabcontainer/tab/ajaxtab.html.twig delete mode 100644 templates/layouts/tabcontainer/tab/layout.html.twig delete mode 100644 templates/layouts/tabcontainer/tab/tab.html.twig diff --git a/css/backoffice/components/_ajaxtab.scss b/css/backoffice/components/_ajaxtab.scss deleted file mode 100644 index 2b1c120e8..000000000 --- a/css/backoffice/components/_ajaxtab.scss +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * copyright Copyright (C) 2010-2020 Combodo SARL - * license http://opensource.org/licenses/AGPL-3.0 - */ diff --git a/css/backoffice/components/_all.scss b/css/backoffice/components/_all.scss index 0095e1b31..830fc109b 100644 --- a/css/backoffice/components/_all.scss +++ b/css/backoffice/components/_all.scss @@ -13,9 +13,8 @@ @import "popover-menu/popover-menu-item"; @import "newsroom-menu"; -@import "tabcontainer"; -@import "tab"; -@import "ajaxtab"; +@import "tab-container/tab-container"; +@import "tab-container/tab"; @import "title"; @import "form"; @import "input"; diff --git a/css/backoffice/components/_tab.scss b/css/backoffice/components/_tab.scss deleted file mode 100644 index 2b1c120e8..000000000 --- a/css/backoffice/components/_tab.scss +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * copyright Copyright (C) 2010-2020 Combodo SARL - * license http://opensource.org/licenses/AGPL-3.0 - */ diff --git a/css/backoffice/components/_tabcontainer.scss b/css/backoffice/components/_tabcontainer.scss deleted file mode 100644 index 78392ccaa..000000000 --- a/css/backoffice/components/_tabcontainer.scss +++ /dev/null @@ -1,37 +0,0 @@ -/*! - * copyright Copyright (C) 2010-2020 Combodo SARL - * license http://opensource.org/licenses/AGPL-3.0 - */ - -.ibo-tab-container { - -} - -.ibo-tab-container-header { - background: $ibo-color-grey-100; -} - -.ibo-tab-header { - a { - @extend %ibo-font-ral-med-200; - color: $ibo-color-grey-700; - - :hover { - color: $ibo-color-grey-900; - } - } - - &.ui-state-active a { - color: $ibo-color-blue-800; - @extend %ibo-font-ral-bol-200; - - :hover { - color: $ibo-color-blue-800; - } - } -} - -.ibo-tab-content { - background: $ibo-color-white-100; -} - diff --git a/css/backoffice/components/tab-container/_tab-container.scss b/css/backoffice/components/tab-container/_tab-container.scss new file mode 100644 index 000000000..468b7d7c7 --- /dev/null +++ b/css/backoffice/components/tab-container/_tab-container.scss @@ -0,0 +1,55 @@ +/*! + * @copyright Copyright (C) 2010-2020 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ + +/* SCSS variables */ +$ibo-tab-container--tabs-list--height: 36px !default; +$ibo-tab-container--tabs-list--padding-x: 24px !default; +$ibo-tab-container--tabs-list--background-color: $ibo-color-grey-100 !default; + +$ibo-tab-container--tab-header--max-width: 110px !default; +$ibo-tab-container--tab-header--text-color: $ibo-color-grey-700 !default; +$ibo-tab-container--tab-header--text-color--is-active: $ibo-color-blue-800 !default; +$ibo-tab-container--tab-header--text-color--on-hover: $ibo-color-blue-800 !default; +$ibo-tab-container--tab-header--background-color--on-hover: $ibo-color-grey-200 !default; + +$ibo-tab-container--tab-toggler--padding-x: 24px !default; + +/* Rules */ +.ibo-tab-container--tabs-list { + @extend %ibo-full-height-content; + justify-content: center; + height: $ibo-tab-container--tabs-list--height; + + background-color: $ibo-tab-container--tabs-list--background-color; + @extend %ibo-font-ral-nor-150; +} +.ibo-tab-container--tab-header{ + @extend %ibo-full-height-content; + + color: $ibo-tab-container--tab-header--text-color; + + &:hover{ + color: $ibo-tab-container--tab-header--text-color--on-hover; + background-color: $ibo-tab-container--tab-header--background-color--on-hover; + } + &.ui-tabs-active{ + @extend %ibo-font-ral-bol-150; + color: $ibo-tab-container--tab-header--text-color--is-active; + } +} +.ibo-tab-container--tab-toggler{ + @extend %ibo-fully-centered-content; + padding-left: $ibo-tab-container--tab-toggler--padding-x; + padding-right: $ibo-tab-container--tab-toggler--padding-x; + + @extend %ibo-text-truncated-with-ellipsis; + color: inherit; /* To get color from parent */ + + &:hover, + &:active{ + color: inherit; + } +} + diff --git a/css/backoffice/components/tab-container/_tab.scss b/css/backoffice/components/tab-container/_tab.scss new file mode 100644 index 000000000..7dd76f768 --- /dev/null +++ b/css/backoffice/components/tab-container/_tab.scss @@ -0,0 +1,28 @@ +/*! + * @copyright Copyright (C) 2010-2020 Combodo SARL + * @license http://opensource.org/licenses/AGPL-3.0 + */ + +.ibo-tab--header { + a { + @extend %ibo-font-ral-med-200; + color: $ibo-color-grey-700; + + :hover { + color: $ibo-color-grey-900; + } + } + + &.ui-state-active a { + color: $ibo-color-blue-800; + @extend %ibo-font-ral-bol-200; + + :hover { + color: $ibo-color-blue-800; + } + } +} + +.ibo-tab--content { + background: $ibo-color-white-100; +} \ No newline at end of file diff --git a/css/ui-lightness/jqueryui.scss b/css/ui-lightness/jqueryui.scss index 3ef2593a0..d766ab9fd 100644 --- a/css/ui-lightness/jqueryui.scss +++ b/css/ui-lightness/jqueryui.scss @@ -929,52 +929,52 @@ button.ui-button { .ui-spinner-down { bottom: 0; } -.ui-tabs { - position: relative; - padding: .2em; - .ui-tabs-nav { - margin: 0; - padding: .2em .2em 0; - li { - list-style: none; - float: left; - position: relative; - top: 0; - margin: 1px .2em 0 0; - border-bottom-width: 0; - padding: 0; - white-space: nowrap; - } - .ui-tabs-anchor { - float: left; - padding: .5em 1em; - text-decoration: none; - } - li.ui-tabs-active { - margin-bottom: -1px; - padding-bottom: 1px; - .ui-tabs-anchor { - cursor: text; - } - } - li.ui-state-disabled { - .ui-tabs-anchor { - cursor: text; - } - } - li.ui-tabs-loading { - .ui-tabs-anchor { - cursor: text; - } - } - } - .ui-tabs-panel { - display: block; - border-width: 0; - padding: 1em 1.4em; - // background: none; - } -} +//.ui-tabs { +// position: relative; +// padding: .2em; +// .ui-tabs-nav { +// margin: 0; +// padding: .2em .2em 0; +// li { +// list-style: none; +// float: left; +// position: relative; +// top: 0; +// margin: 1px .2em 0 0; +// border-bottom-width: 0; +// padding: 0; +// white-space: nowrap; +// } +// .ui-tabs-anchor { +// float: left; +// padding: .5em 1em; +// text-decoration: none; +// } +// li.ui-tabs-active { +// margin-bottom: -1px; +// padding-bottom: 1px; +// .ui-tabs-anchor { +// cursor: text; +// } +// } +// li.ui-state-disabled { +// .ui-tabs-anchor { +// cursor: text; +// } +// } +// li.ui-tabs-loading { +// .ui-tabs-anchor { +// cursor: text; +// } +// } +// } +// .ui-tabs-panel { +// display: block; +// border-width: 0; +// padding: 1em 1.4em; +// // background: none; +// } +//} .ui-tabs-collapsible { .ui-tabs-nav { li.ui-tabs-active { diff --git a/js/layouts/tab-container.js b/js/layouts/tab-container.js index 2f62d07e5..26c0a3c2e 100644 --- a/js/layouts/tab-container.js +++ b/js/layouts/tab-container.js @@ -1,44 +1,140 @@ -// The "tab widgets" to handle. -var tabs = $('div[id^=tabbedContent]'); -// Ugly patch for a change in the behavior of jQuery UI: -// Before jQuery UI 1.9, tabs were always considered as "local" (opposed to Ajax) -// when their href was beginning by #. Starting with 1.9, a tag in the page -// is taken into account and causes "local" tabs to be considered as Ajax -// unless their URL is equal to the URL of the page... -if ($('base').length > 0) { - $('div[id^=tabbedContent] > ul > li > a').each(function () { - var sHash = location.hash; - var sCleanLocation = location.href.toString().replace(sHash, '').replace(/#$/, ''); - $(this).attr("href", sCleanLocation + $(this).attr("href")); - }); -} -if ($.bbq) { - // This selector will be reused when selecting actual tab widget A elements. - var tab_a_selector = 'ul.ui-tabs-nav a'; +$(function() +{ + $.widget( 'itop.tab_container', + { + // default options + options: + { + }, + css_classes: + { + }, + js_selectors: + { + tabs_list: '[data-role="ibo-tab-container--tabs-list"]', + tab_header: '[data-role="ibo-tab-container--tab-header"]', + tab_toggler: '[data-role="ibo-tab-container--tab-toggler"]', + }, - // Enable tabs on all tab widgets. The `event` property must be overridden so - // that the tabs aren't changed on click, and any custom event name can be - // specified. Note that if you define a callback for the 'select' event, it - // will be executed for the selected tab whenever the hash changes. - tabs.tabs({event: 'change'}); + // the constructor + _create: function() + { + this.element.addClass('ibo-tab-container'); - // Define our own click handler for the tabs, overriding the default. - tabs.find(tab_a_selector).click(function () { - var state = {}; + // Ugly patch for a change in the behavior of jQuery UI: + // Before jQuery UI 1.9, tabs were always considered as "local" (opposed to Ajax) + // when their href was beginning by #. Starting with 1.9, a tag in the page + // is taken into account and causes "local" tabs to be considered as Ajax + // unless their URL is equal to the URL of the page... + if ($('base').length > 0) { + this.element.find(this.js_selectors.tab_toggler).each(function () { + const sHash = location.hash; + const sCleanLocation = location.href.toString().replace(sHash, '').replace(/#$/, ''); + $(this).attr('href', sCleanLocation + $(this).attr('href')); + }); + } - // Get the id of this tab widget. - var id = $(this).closest('div[id^=tabbedContent]').attr('id'); + if ($.bbq) { + // This selector will be reused when selecting actual tab widget A elements. + const sTabAnchorSelector = 'ul.ui-tabs-nav a'; - // Get the index of this tab. - var idx = $(this).parent().prevAll().length; + // Enable tabs on all tab widgets. The `event` property must be overridden so + // that the tabs aren't changed on click, and any custom event name can be + // specified. Note that if you define a callback for the 'select' event, it + // will be executed for the selected tab whenever the hash changes. + this.element.tabs({event: 'change'}); + } else { + this.element.tabs(); + } - // Set the state! - state[id] = idx; - $.bbq.pushState(state); - }); -} else { - tabs.tabs(); -} -$('.ibo-tab-container-spinner').hide(); -$('.ibo-tab-container').show(); \ No newline at end of file + this._bindEvents(); + }, + // events bound via _bind are removed automatically + // revert other modifications here + _destroy: function() + { + this.element.removeClass('ibo-tab-container'); + }, + _bindEvents: function() + { + const me = this; + + // Bind an event on tab activation + this.element.on('tabsactivate', function(oEvent, oUI){ + me._onTabActivated(oUI); + }); + // Bind an event to window.onhashchange that, when the history state changes, + // iterates over all tab widgets, changing the current tab as necessary. + $(window).on('hashchange', function(){ + me._onHashChange(); + }); + // Define our own click handler for the tabs, overriding the default. + this.element.find(this.js_selectors.tab_toggler).on('click', function(){ + me._onTogglerClick($(this)); + }); + }, + + // Events callbacks + // - Update URL hash when tab is activated + _onTabActivated: function(oUI) + { + let oState = {}; + + // Get the id of this tab widget. + const sId = this.element.attr( 'id' ); + + // Get the index of this tab. + const iIdx = $(oUI.newTab).prevAll().length; + + // Set the state! + oState[ sId ] = iIdx; + $.bbq.pushState( oState ); + }, + // - Change current tab as necessary when URL hash changes + _onHashChange: function() + { + // Get the index for this tab widget from the hash, based on the + // appropriate id property. In jQuery 1.4, you should use e.getState() + // instead of $.bbq.getState(). The second, 'true' argument coerces the + // string value to a number. + const iIdx = $.bbq.getState( this.element.attr('id'), true ) || 0; + + // Select the appropriate tab for this tab widget by triggering the custom + // event specified in the .tabs() init above (you could keep track of what + // tab each widget is on using .data, and only select a tab if it has + // changed). + this.element.find(this.js_selectors.tab_toggler).eq(iIdx).triggerHandler('change'); + + // Iterate over all truncated lists to find whether they are expanded or not + $('a.truncated').each(function() + { + const sState = $.bbq.getState( this.id, true ) || 'close'; + if (sState === 'open') + { + $(this).trigger('open'); + } + else + { + $(this).trigger('close'); + } + }); + }, + _onTogglerClick: function(oTabHeaderElem) + { + if ($.bbq) { + let oState = {}; + + // Get the id of this tab widget. + const sId = this.element.attr('id'); + + // Get the index of this tab. + const iIdx = oTabHeaderElem.parent().prevAll().length; + + // Set the state! + oState[sId] = iIdx; + $.bbq.pushState(oState); + } + } + }); +}); diff --git a/sources/application/UI/Layout/TabContainer/Tab/AjaxTab.php b/sources/application/UI/Layout/TabContainer/Tab/AjaxTab.php index 56dcc7d42..06c3fb4db 100644 --- a/sources/application/UI/Layout/TabContainer/Tab/AjaxTab.php +++ b/sources/application/UI/Layout/TabContainer/Tab/AjaxTab.php @@ -21,7 +21,6 @@ namespace Combodo\iTop\Application\UI\Layout\TabContainer\Tab; use Combodo\iTop\Application\UI\iUIBlock; -use Combodo\iTop\Application\UI\Layout\iUIContentBlock; use Combodo\iTop\Application\UI\UIException; use Dict; use TabManager; @@ -30,95 +29,99 @@ use TabManager; * Class AjaxTab * * @package Combodo\iTop\Application\UI\Layout\TabContainer\Tab + * @internal + * @since 2.8.0 */ -class AjaxTab extends Tab -{ +class AjaxTab extends Tab { // Overloaded constants - public const BLOCK_CODE = 'ibo-ajaxtab'; - public const HTML_TEMPLATE_REL_PATH = 'layouts/tabcontainer/tab/ajaxtab'; + public const BLOCK_CODE = 'ibo-ajax-tab'; + public const TAB_TYPE = TabManager::ENUM_TAB_TYPE_AJAX; - protected const TAB_TYPE = TabManager::ENUM_TAB_TYPE_AJAX; - - /** @var string */ - private $sURL; - /** @var bool */ + /** @var string The target URL to be loaded asynchronously */ + private $sUrl; + /** @var bool Whether the tab should should be cached by the browser or always refreshed */ private $bCache; /** - * @param string $sHtml + * @param string $sUrl * - * @return \Combodo\iTop\Application\UI\iUIBlock - * @throws \Combodo\iTop\Application\UI\UIException + * @return $this */ - public function AddHtml(string $sHtml): iUIBlock - { - throw new UIException($this, Dict::Format('UIBlock:Error:AddBlockForbidden', $this->GetId())); - } + public function SetUrl(string $sUrl) { + $this->sUrl = $sUrl; - /** - * @param \Combodo\iTop\Application\UI\iUIBlock $oSubBlock - * - * @return iUIContentBlock - * @throws \Combodo\iTop\Application\UI\UIException - */ - public function AddSubBlock(iUIBlock $oSubBlock): iUIContentBlock - { - throw new UIException($this, Dict::Format('UIBlock:Error:AddBlockForbidden', $this->GetId())); - } - - /** - * @return array|\Combodo\iTop\Application\UI\iUIBlock[] - */ - public function GetSubBlocks(): array - { - return []; - } - - /** - * @param mixed $sURL - * - * @return AjaxTab - */ - public function SetURL(string $sURL): self - { - $this->sURL = $sURL; return $this; } /** + * @return string + */ + public function GetUrl(): string { + return $this->sUrl; + } + + /** + * Set whether the tab should should be cached by the browser or always refreshed + * * @param bool $bCache * - * @return AjaxTab + * @return $this */ - public function SetCache(bool $bCache): self - { + public function SetCache(bool $bCache) { $this->bCache = $bCache; + return $this; } /** + * Return whether the tab should should be cached by the browser or always refreshed + * * @return string */ - public function GetURL(): string - { - return $this->sURL; - } - - /** - * @return string - */ - public function GetCache(): string - { + public function GetCache(): string { return $this->bCache ? 'true' : 'false'; } - public function GetParameters(): array - { + //------------------------------- + // iUIBlock implementation + //------------------------------- + + /** + * @inheritDoc + */ + public function GetParameters(): array { $aParams = parent::GetParameters(); - $aParams['sURL'] = $this->GetURL(); + $aParams['sURL'] = $this->GetUrl(); $aParams['sCache'] = $this->GetCache() ? 'true' : 'false'; return $aParams; } + + //------------------------------- + // iUIContentBlock implementation + //------------------------------- + + /** + * @inheritDoc + * @throws \Combodo\iTop\Application\UI\UIException + */ + public function AddHtml(string $sHtml) { + throw new UIException($this, Dict::Format('UIBlock:Error:AddBlockForbidden', $this->GetId())); + } + + /** + * @inheritDoc + * @throws \Combodo\iTop\Application\UI\UIException + */ + public function AddSubBlock(iUIBlock $oSubBlock) { + throw new UIException($this, Dict::Format('UIBlock:Error:AddBlockForbidden', $this->GetId())); + } + + /** + * @inheritDoc + */ + public function GetSubBlocks(): array { + return []; + } } diff --git a/sources/application/UI/Layout/TabContainer/Tab/Tab.php b/sources/application/UI/Layout/TabContainer/Tab/Tab.php index 8d440d500..6b32bcbf9 100644 --- a/sources/application/UI/Layout/TabContainer/Tab/Tab.php +++ b/sources/application/UI/Layout/TabContainer/Tab/Tab.php @@ -27,33 +27,56 @@ use TabManager; * Class Tab * * @package Combodo\iTop\Application\UI\Layout\TabContainer\Tab + * @internal + * @since 2.8.0 */ class Tab extends UIContentBlock { // Overloaded constants public const BLOCK_CODE = 'ibo-tab'; - public const HTML_TEMPLATE_REL_PATH = 'layouts/tabcontainer/tab/tab'; + public const HTML_TEMPLATE_REL_PATH = 'layouts/tab-container/tab/layout'; - protected const TAB_TYPE = TabManager::ENUM_TAB_TYPE_HTML; + /** @var string */ + public const TAB_TYPE = TabManager::ENUM_TAB_TYPE_HTML; + /** @var string */ protected $sTitle; + /** + * Tab constructor. + * + * @param string $sTabCode + * @param string $sTitle + */ public function __construct(string $sTabCode, string $sTitle) { parent::__construct($sTabCode); $this->sTitle = $sTitle; } + /** + * @return string + */ public function GetType(): string { return static::TAB_TYPE; } + /** + * @return string + */ public function GetTitle(): string { return $this->sTitle; } + //------------------------------- + // iUIBlock implementation + //------------------------------- + + /** + * @inheritDoc + */ public function GetParameters(): array { return [ diff --git a/sources/application/UI/Layout/TabContainer/TabContainer.php b/sources/application/UI/Layout/TabContainer/TabContainer.php index 813747b55..0343107e5 100644 --- a/sources/application/UI/Layout/TabContainer/TabContainer.php +++ b/sources/application/UI/Layout/TabContainer/TabContainer.php @@ -36,8 +36,9 @@ use Dict; class TabContainer extends UIContentBlock { // Overloaded constants - public const BLOCK_CODE = 'ibo-tabcontainer'; - public const HTML_TEMPLATE_REL_PATH = 'layouts/tabcontainer/layout'; + public const BLOCK_CODE = 'ibo-tab-container'; + public const HTML_TEMPLATE_REL_PATH = 'layouts/tab-container/layout'; + public const JS_TEMPLATE_REL_PATH = 'layouts/tab-container/layout'; public const JS_FILES_REL_PATH = [ 'js/layouts/tab-container.js' ]; diff --git a/sources/application/WebPage/TabManager.php b/sources/application/WebPage/TabManager.php index a66cbe3aa..7db09b8b1 100644 --- a/sources/application/WebPage/TabManager.php +++ b/sources/application/WebPage/TabManager.php @@ -209,7 +209,7 @@ class TabManager // Set the content of the tab /** @var \Combodo\iTop\Application\UI\Layout\TabContainer\Tab\AjaxTab $oTab */ $oTab = $this->InitTab($this->m_sCurrentTabContainer, $sTabCode, static::ENUM_TAB_TYPE_AJAX, $sTabTitle); - $oTab->SetURL($sUrl) + $oTab->SetUrl($sUrl) ->SetCache($bCache); return ''; // Nothing to add to the page for now diff --git a/sources/application/WebPage/iTopWebPage.php b/sources/application/WebPage/iTopWebPage.php index 8b4dbe74d..cb05b265c 100644 --- a/sources/application/WebPage/iTopWebPage.php +++ b/sources/application/WebPage/iTopWebPage.php @@ -366,57 +366,6 @@ JS SetUserPreference(parent_id+'_'+this.id+'_height', $(this).height(), true); // true => persistent } } ); - - - // refresh the hash when the tab is changed (from a JS script) - $('body').on( 'tabsactivate', '.ui-tabs', function(event, ui) { - var state = {}; - - // Get the id of this tab widget. - var id = $(ui.newTab).closest( 'div[id^=tabbedContent]' ).attr( 'id' ); - - // Get the index of this tab. - var idx = $(ui.newTab).prevAll().length; - - // Set the state! - state[ id ] = idx; - $.bbq.pushState( state ); - }); - - // Bind an event to window.onhashchange that, when the history state changes, - // iterates over all tab widgets, changing the current tab as necessary. - $(window).bind( 'hashchange', function(e) - { - // Iterate over all tab widgets. - tabs.each(function() - { - // Get the index for this tab widget from the hash, based on the - // appropriate id property. In jQuery 1.4, you should use e.getState() - // instead of $.bbq.getState(). The second, 'true' argument coerces the - // string value to a number. - var idx = $.bbq.getState( this.id, true ) || 0; - - // Select the appropriate tab for this tab widget by triggering the custom - // event specified in the .tabs() init above (you could keep track of what - // tab each widget is on using .data, and only select a tab if it has - // changed). - $(this).find( tab_a_selector ).eq( idx ).triggerHandler( 'change' ); - }); - - // Iterate over all truncated lists to find whether they are expanded or not - $('a.truncated').each(function() - { - var state = $.bbq.getState( this.id, true ) || 'close'; - if (state == 'open') - { - $(this).trigger('open'); - } - else - { - $(this).trigger('close'); - } - }); - }); // Shortcut menu actions $('.actions_button a').click( function() { diff --git a/templates/layouts/tab-container/layout.html.twig b/templates/layouts/tab-container/layout.html.twig new file mode 100644 index 000000000..6bc633130 --- /dev/null +++ b/templates/layouts/tab-container/layout.html.twig @@ -0,0 +1,31 @@ +{# @copyright Copyright (C) 2010-2020 Combodo SARL #} +{# @license http://opensource.org/licenses/AGPL-3.0 #} +
+ {% block iboTabContainer %} + + {% block iboTabContainerTabsContainers %} + {% for oTab in oUIBlock.GetSubBlocks() %} + {% if oTab.GetType() == 'html' %} +
+ {{ render_block(oTab, {aPage: aPage}) }} +
+ {% endif %} + {% endfor %} + {% endblock %} + {% endblock %} +
+ diff --git a/templates/layouts/tab-container/layout.js.twig b/templates/layouts/tab-container/layout.js.twig new file mode 100644 index 000000000..c8b990ce4 --- /dev/null +++ b/templates/layouts/tab-container/layout.js.twig @@ -0,0 +1 @@ +$('#{{ oUIBlock.GetId() }}').tab_container(); \ No newline at end of file diff --git a/templates/layouts/tab-container/tab/layout.html.twig b/templates/layouts/tab-container/tab/layout.html.twig new file mode 100644 index 000000000..b264adb70 --- /dev/null +++ b/templates/layouts/tab-container/tab/layout.html.twig @@ -0,0 +1,9 @@ +{# @copyright Copyright (C) 2010-2020 Combodo SARL #} +{# @license http://opensource.org/licenses/AGPL-3.0 #} +
+ {% block iboContentBlockContainer %} + {% for oSubBlock in oUIBlock.GetSubBlocks() %} + {{ render_block(oSubBlock, {aPage: aPage}) }} + {% endfor %} + {% endblock %} +
\ No newline at end of file diff --git a/templates/layouts/tabcontainer/layout.html.twig b/templates/layouts/tabcontainer/layout.html.twig deleted file mode 100644 index 0317c16c9..000000000 --- a/templates/layouts/tabcontainer/layout.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{# @copyright Copyright (C) 2010-2020 Combodo SARL #} -{# @license http://opensource.org/licenses/AGPL-3.0 #} -{% block iboTabContainer %} -
- - - -{% endblock %} - diff --git a/templates/layouts/tabcontainer/tab/ajaxtab.html.twig b/templates/layouts/tabcontainer/tab/ajaxtab.html.twig deleted file mode 100644 index f6cb411cf..000000000 --- a/templates/layouts/tabcontainer/tab/ajaxtab.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{# @copyright Copyright (C) 2010-2020 Combodo SARL #} -{# @license http://opensource.org/licenses/AGPL-3.0 #} \ No newline at end of file diff --git a/templates/layouts/tabcontainer/tab/layout.html.twig b/templates/layouts/tabcontainer/tab/layout.html.twig deleted file mode 100644 index f6cb411cf..000000000 --- a/templates/layouts/tabcontainer/tab/layout.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -{# @copyright Copyright (C) 2010-2020 Combodo SARL #} -{# @license http://opensource.org/licenses/AGPL-3.0 #} \ No newline at end of file diff --git a/templates/layouts/tabcontainer/tab/tab.html.twig b/templates/layouts/tabcontainer/tab/tab.html.twig deleted file mode 100644 index dce4bb80d..000000000 --- a/templates/layouts/tabcontainer/tab/tab.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{# @copyright Copyright (C) 2010-2020 Combodo SARL #} -{# @license http://opensource.org/licenses/AGPL-3.0 #} -
- {% block iboContentBlockContainer %} - {% for oSubBlock in oUIBlock.GetSubBlocks() %} - {{ render_block(oSubBlock, {aPage: aPage}) }} - {% endfor %} - {% endblock %} -
\ No newline at end of file