From b3dcfea8dcfc52f9fd8973102734d87292a59c52 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 23 Jul 2020 17:41:27 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B03207=20-=20Global=20search:=20Introduce?= =?UTF-8?q?=20new=20widget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/itopwebpage.class.inc.php | 20 ++ css/backoffice/components/_all.scss | 1 + css/backoffice/components/_global-search.scss | 200 ++++++++++++++++++ css/backoffice/layout/_top-bar.scss | 8 + .../en.dictionary.itop.global-search.php | 4 + .../undraw-collection/web_search.svg | 1 + js/components/global-search.js | 110 ++++++++++ lib/composer/autoload_classmap.php | 1 + lib/composer/autoload_static.php | 1 + pages/UI.php | 22 +- .../GlobalSearch/GlobalSearchHelper.php | 117 ++++++++++ .../components/global-search/layout.html.twig | 38 ++++ .../layouts/navigation-menu/layout.html.twig | 4 +- .../navigation-menu/menu-node.html.twig | 2 +- .../navigation-menu/menu-nodes.html.twig | 2 +- templates/layouts/top-bar/layout.html.twig | 5 +- templates/pages/backoffice/layout.html.twig | 4 +- 17 files changed, 531 insertions(+), 9 deletions(-) create mode 100644 css/backoffice/components/_global-search.scss create mode 100644 images/illustrations/undraw-collection/web_search.svg create mode 100644 js/components/global-search.js create mode 100644 sources/application/GlobalSearch/GlobalSearchHelper.php create mode 100644 templates/components/global-search/layout.html.twig diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index 05cd9950b..3d952b4be 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -22,6 +22,7 @@ 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\GlobalSearch\GlobalSearchHelper; use Combodo\iTop\Application\TwigBase\Twig\TwigHelper; /** @@ -880,6 +881,7 @@ JS $aData = [ 'sId' => 'ibo-top-bar', 'aComponents' => [ + 'aGlobalSearch' => $this->GetGlobalSearchData(), 'aBreadCrumbs' => $this->GetBreadCrumbsData(), ], ]; @@ -887,6 +889,24 @@ JS return $aData; } + /** + * Return the global search data (last queries) + * + * @return array + * @throws \Exception + * @since 2.8.0 + */ + protected function GetGlobalSearchData() + { + $aData = [ + 'sId' => 'ibo-global-search', + 'sEndpoint' => utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=full_text', + 'aLastQueries' => GlobalSearchHelper::GetLastQueries(), + ]; + + return $aData; + } + /** * Return the breadcrumbs data (iTop instance ID, new entry, ...) * diff --git a/css/backoffice/components/_all.scss b/css/backoffice/components/_all.scss index fa1368eb7..784446164 100644 --- a/css/backoffice/components/_all.scss +++ b/css/backoffice/components/_all.scss @@ -17,3 +17,4 @@ */ @import "breadcrumbs"; +@import "global-search"; diff --git a/css/backoffice/components/_global-search.scss b/css/backoffice/components/_global-search.scss new file mode 100644 index 000000000..bb0665243 --- /dev/null +++ b/css/backoffice/components/_global-search.scss @@ -0,0 +1,200 @@ +/*! + * 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 + */ + +/* SCSS variables */ +$ibo-global-search--head--background-color: $ibo-color-white-100 !default; + +$ibo-global-search--icon-padding-x: 16px !default; +$ibo-global-search--icon-padding-y: 0 !default; + +$ibo-global-search--input--padding: 0 default; +$ibo-global-search--input--padding-x--is-opened: 8px !default; +$ibo-global-search--input--padding-y--is-opened: 8px !default; +$ibo-global-search--input--width: 0 !default; +$ibo-global-search--input--width--is-opened: 245px !default; +$ibo-global-search--input--text-color: $ibo-color-grey-800 !default; +$ibo-global-search--input--placeholder-color: $ibo-color-grey-600 !default; + +$ibo-global-search--drawer--max-height: 200px !default; +$ibo-global-search--drawer--padding-x: $ibo-global-search--icon-padding-x !default; +$ibo-global-search--drawer--padding-y: 16px !default; +$ibo-global-search--drawer--top: -1 * ($ibo-global-search--drawer--max-height) !default; +$ibo-global-search--drawer--top--is-opened: 100% !default; +$ibo-global-search--drawer--background-color: $ibo-color-white-100 !default; + +$ibo-global-search--compartment-title--margin-bottom: 8px !default; +$ibo-global-search--compartment-title--padding-left: 32px !default; +$ibo-global-search--compartment-title--text-color: $ibo-color-grey-600 !default; +$ibo-global-search--compartment-title--line-spacing: 8px !default; + +$ibo-global-search--compartment-content--text-color: $ibo-color-grey-900 !default; + +$ibo-global-search--compartment-element--margin-bottom: 8px !default; + +$ibo-global-search--compartment-element-image--margin-right: 8px !default; +$ibo-global-search--compartment-element-image--width: 20px !default; + +$ibo-global-search--compartment--placeholder-image--margin-top: 24px !default; +$ibo-global-search--compartment--placeholder-image--margin-bottom: 16px !default; +$ibo-global-search--compartment--placeholder-image--width: 66% !default; + +$ibo-global-search--compartment--placeholder-hint--padding-x: 8px !default; +$ibo-global-search--compartment--placeholder-hint--padding-y: 0 !default; +$ibo-global-search--compartment--placeholder-hint--text-color: $ibo-color-grey-700 !default; + +/* Animations*/ +@keyframes ibo-global-search--drawer--opening { + from { + top: $ibo-global-search--drawer--top; + box-shadow: none; + } + to { + top: $ibo-global-search--drawer--top--is-opened; + box-shadow: $ibo-elevation-300; + } +} + +/* SCSS rules */ +.ibo-global-search{ + position: relative; + @extend %ibo-vertically-centered-content; + + &.ibo-global-search--is-opened{ + .ibo-global-search--input{ + padding: $ibo-global-search--input--padding-y--is-opened $ibo-global-search--input--padding-x--is-opened; + width: $ibo-global-search--input--width--is-opened; + } + .ibo-global-search--drawer{ + animation-name: ibo-global-search--drawer--opening; + animation-delay: 0.1s; + animation-duration: 0.2s; + animation-direction: normal; + animation-fill-mode: forwards; + } + } +} +.ibo-global-search--head{ + @extend %ibo-vertically-centered-content; + background-color: $ibo-global-search--head--background-color; +} +.ibo-global-search--icon{ + align-self: center; + padding: $ibo-global-search--icon-padding-y $ibo-global-search--icon-padding-x; + @extend %ibo-font-ral-nor-400; +} +.ibo-global-search--input{ + padding: $ibo-global-search--input--padding; + width: $ibo-global-search--input--width; + color: $ibo-global-search--input--text-color; + @extend %ibo-font-ral-nor-300; + + border: none; + outline: none; + + transition: all 0.2s ease-in-out; + + &::placeholder{ + color: $ibo-global-search--input--placeholder-color; + } + /* This rule is duplicated otherwise Chrome won't be able to parse it. */ + &:-ms-input-placeholder, + &::-ms-input-placeholder{ + color: $ibo-global-search--input--placeholder-color; + } + + &:hover, + &:focus, + &:active{ + @extend .ibo-global-search--input; + } +} +/* TODO: Make drawer appear below the top bar so its shadow is cast on the drawer */ +.ibo-global-search--drawer{ + z-index: -1; + position: absolute; + left: 0; + right: 0; + top: $ibo-global-search--drawer--top; + padding: $ibo-global-search--drawer--padding-y $ibo-global-search--drawer--padding-x; + background-color: $ibo-global-search--drawer--background-color; + box-shadow: none; + @extend %ibo-font-ral-nor-100; +} +.ibo-global-search--compartment-title{ + margin-bottom: $ibo-global-search--compartment-title--margin-bottom; + padding-left: $ibo-global-search--compartment-title--padding-left; + overflow-x: hidden; + color: $ibo-global-search--compartment-title--text-color; + + > span{ + position: relative; + + &::before, + &::after{ + content: ""; + display: inline-block; + position: absolute; + top: 50%; + height: 1px; + width: 600px; + border-top: 1px solid $ibo-global-search--compartment-title--text-color; + } + &::before{ + right: 100%; + margin-right: $ibo-global-search--compartment-title--line-spacing; + } + &::after{ + left: 100%; + margin-left: $ibo-global-search--compartment-title--line-spacing; + } + } +} +.ibo-global-search--compartment-content{ + color: $ibo-global-search--compartment-content--text-color; +} +.ibo-global-search--compartment-element{ + display: flex; + align-items: center; + color: inherit; + + @extend %ibo-text-truncated-with-ellipsis; + + &:not(:last-child){ + margin-bottom: $ibo-global-search--compartment-element--margin-bottom; + } +} +.ibo-global-search--compartment-element-image{ + margin-right: $ibo-global-search--compartment-element-image--margin-right; + width: $ibo-global-search--compartment-element-image--width; +} +.ibo-global-search--compartment--placeholder{ + align-items: center; + display: flex; + flex-direction: column; +} +.ibo-global-search--compartment--placeholder-image{ + width: $ibo-global-search--compartment--placeholder-image--width; + margin-top: $ibo-global-search--compartment--placeholder-image--margin-top; + margin-bottom: $ibo-global-search--compartment--placeholder-image--margin-bottom; +} +.ibo-global-search--compartment--placeholder-hint{ + text-align: justify; + padding: $ibo-global-search--compartment--placeholder-hint--padding-y $ibo-global-search--compartment--placeholder-hint--padding-x; + color: $ibo-global-search--compartment--placeholder-hint--text-color; + @extend %ibo-font-ral-ita-100; +} \ No newline at end of file diff --git a/css/backoffice/layout/_top-bar.scss b/css/backoffice/layout/_top-bar.scss index 6a1b6c6ae..be9a3a457 100644 --- a/css/backoffice/layout/_top-bar.scss +++ b/css/backoffice/layout/_top-bar.scss @@ -48,4 +48,12 @@ $ibo-top-bar--quick-actions--margin-right: $ibo-top-bar--elements-spacing !defau flex-grow: 1; /* Occupy as much width as possible */ overflow-x: hidden; /* Avoid glitches when too many items */ } +} +.ibo-top-bar--quick-actions{ + @extend %ibo-vertically-centered-content; + margin-right: var(--ibo-top-bar--quick-actions--margin-right); + + .ibo-global-search{ + + } } \ No newline at end of file diff --git a/dictionaries/ui/components/en.dictionary.itop.global-search.php b/dictionaries/ui/components/en.dictionary.itop.global-search.php index 2812d393c..37953c28c 100644 --- a/dictionaries/ui/components/en.dictionary.itop.global-search.php +++ b/dictionaries/ui/components/en.dictionary.itop.global-search.php @@ -19,4 +19,8 @@ // Global search Dict::Add('EN US', 'English', 'English', array( + 'UI:Component:GlobalSearch:Tooltip' => 'Search throughout the whole application', + 'UI:Component:GlobalSearch:Input:Placeholder' => 'Search...', + 'UI:Component:GlobalSearch:Recents:Title' => 'Recents', + 'UI:Component:GlobalSearch:LastQueries:NoQuery:Placeholder' => 'You haven\'t run any search yet', )); \ No newline at end of file diff --git a/images/illustrations/undraw-collection/web_search.svg b/images/illustrations/undraw-collection/web_search.svg new file mode 100644 index 000000000..64535e501 --- /dev/null +++ b/images/illustrations/undraw-collection/web_search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/components/global-search.js b/js/components/global-search.js new file mode 100644 index 000000000..7ef2c7618 --- /dev/null +++ b/js/components/global-search.js @@ -0,0 +1,110 @@ +/* + * 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 + */ + +; +$(function() +{ + // the widget definition, where 'itop' is the namespace, + // 'breadcrumbs' the widget name + $.widget( 'itop.global_search', + { + // default options + options: + { + + }, + css_classes: + { + opened: 'ibo-global-search--is-opened', + }, + js_selectors: + { + icon: '[data-role="ibo-global-search--icon"]', + form: '[data-role="ibo-global-search--head"]', + input: '[data-role="ibo-global-search--input"]', + compartment_element: '[data-role="ibo-global-search--compartment-element"]', + }, + + // the constructor + _create: function() + { + this.element.addClass('ibo-global-search'); + this._bindEvents(); + }, + // events bound via _bind are removed automatically + // revert other modifications here + _destroy: function() + { + this.element.removeClass('ibo-global-search'); + }, + _bindEvents: function() + { + const me = this; + + this.element.find(this.js_selectors.icon).on('click', function(oEvent){ + me._onIconClick(oEvent); + }); + this.element.find(this.js_selectors.form).on('submit', function(oEvent){ + me._onFormSubmit(oEvent); + }); + this.element.find(this.js_selectors.compartment_element).on('click', function(oEvent){ + me._onCompartmentElementClick(oEvent, $(this)); + }); + $('body').on('click', function(oEvent){ + me._onBodyClick(oEvent); + }); + }, + _onIconClick: function(oEvent) + { + // Avoid anchor glitch + oEvent.preventDefault(); + + // Open drawer + this.element.toggleClass(this.css_classes.opened); + // Focus in the input for a better UX + this.element.find(this.js_selectors.input).trigger('focus'); + }, + _onFormSubmit: function(oEvent) + { + const sSearchValue = this.element.find(this.js_selectors.input).val(); + + // Submit form only if something in the input + if(sSearchValue === '') + { + oEvent.preventDefault(); + } + }, + _onCompartmentElementClick: function(oEvent, oElementElem) + { + // Avoid anchor glitch + oEvent.preventDefault(); + + const sElementQuery = oElementElem.attr('data-query-raw'); + this.element.find(this.js_selectors.input) + .val(sElementQuery) + .closest(this.js_selectors.form).trigger('submit'); + }, + _onBodyClick: function(oEvent) + { + if($(oEvent.target.closest('.ibo-global-search')).length === 0) + { + this.element.removeClass(this.css_classes.opened); + } + } + }); +}); diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 01433a2f7..b4c456415 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -138,6 +138,7 @@ 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\\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', diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 1d5bd7266..8702ad4f2 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -368,6 +368,7 @@ 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\\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', diff --git a/pages/UI.php b/pages/UI.php index 10bc899da..52ef9c1e1 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -17,6 +17,8 @@ * You should have received a copy of the GNU Affero General Public License */ +use Combodo\iTop\Application\GlobalSearch\GlobalSearchHelper; + /** * Displays a popup welcome message, once per session at maximum * until the user unchecks the "Display welcome at startup" @@ -546,15 +548,16 @@ try case 'full_text': // Global "google-like" search $oP->DisableBreadCrumb(); - $sFullText = trim(utils::ReadParam('text', '', false, 'raw_data')); + $sQuery = trim(utils::ReadPostedParam('query', '', 'raw_data')); $iTune = utils::ReadParam('tune', 0); - if (empty($sFullText)) + if (empty($sQuery)) { $oP->p(Dict::S('UI:Search:NoSearch')); } else { $iErrors = 0; + $sFullText = $sQuery; // Check if a class name/label is supplied to limit the search $sClassName = ''; @@ -581,6 +584,21 @@ try $aFullTextNeedles = explode(' ', $sFullText); } + // Save search to history + // - Prepare icon + $sQueryIconUrl = null; + if(!empty($sClassName)) + { + $sQueryIconUrl = MetaModel::GetClassIcon($sClassName, false); + } + // - Prepare label + $sQueryLabel = null; + if($sQuery !== $sFullText) + { + $sQueryLabel = $sFullText; + } + GlobalSearchHelper::AddQueryToHistory($sQuery, $sQueryIconUrl, $sQueryLabel); + // Check the needle length $iMinLenth = MetaModel::GetConfig()->Get('full_text_needle_min'); foreach ($aFullTextNeedles as $sNeedle) diff --git a/sources/application/GlobalSearch/GlobalSearchHelper.php b/sources/application/GlobalSearch/GlobalSearchHelper.php new file mode 100644 index 000000000..029dfaa5f --- /dev/null +++ b/sources/application/GlobalSearch/GlobalSearchHelper.php @@ -0,0 +1,117 @@ + + * @package Combodo\iTop\Application\GlobalSearch + * @since 2.8.0 + */ +class GlobalSearchHelper +{ + const MAX_HISTORY_SIZE = 10; + const USER_PREF_CODE = 'global_search_history'; + + /** + * Add $sQuery to the history. History is limited to the static::MAX_HISTORY_SIZE last queries. + * + * @param string $sQuery Raw search query + * @param string|null $sIconRelUrl Relative URL of the icon + * @param string|null $sLabelAsHtml Alternate label for the query (eg. more human readable or with highlights), MUST be html entities otherwise there can be XSS flaws + * + * @return void + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException + */ + public static function AddQueryToHistory($sQuery, $sIconRelUrl = null, $sLabelAsHtml = null) + { + $aNewQuery = [ + 'query' => $sQuery, + ]; + + // Set icon only when necessary + if(!empty($sIconRelUrl)) + { + //Ensure URL is relative to limit space in the preferences and avoid broken links in case app_root_url changes + $aNewQuery['icon_url'] = str_replace(utils::GetAbsoluteUrlAppRoot(), '', $sIconRelUrl); + } + + // Set label only when necessary to avoid unnecessary space filling of the preferences in the DB + if(!empty($sLabelAsHtml)) + { + $aNewQuery['label_html'] = $sLabelAsHtml; + } + + /** @var array $aQueriesHistory */ + $aQueriesHistory = appUserPreferences::GetPref(static::USER_PREF_CODE, []); + + // Remove same query from history to avoid duplicates + for($iIdx = 0; $iIdx < count($aQueriesHistory); $iIdx++) + { + if($aQueriesHistory[$iIdx]['query'] === $sQuery) + { + unset($aQueriesHistory[$iIdx]); + } + } + + // Add new query + array_unshift($aQueriesHistory, $aNewQuery); + + // Truncate history + if(count($aQueriesHistory) > static::MAX_HISTORY_SIZE) + { + $aQueriesHistory = array_slice($aQueriesHistory, 0, static::MAX_HISTORY_SIZE); + } + + appUserPreferences::SetPref(static::USER_PREF_CODE, $aQueriesHistory); + } + + /** + * Return an array of pasted queries, including the query itself and its HTML label + * + * @return array + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException + */ + public static function GetLastQueries() + { + /** @var array $aLastQueries */ + $aLastQueries = appUserPreferences::GetPref(static::USER_PREF_CODE, []); + + // Add HTML label if missing + for($iIdx = 0; $iIdx < count($aLastQueries); $iIdx++) + { + if(!isset($aLastQueries[$iIdx]['label_html'])) + { + $aLastQueries[$iIdx]['label_html'] = utils::HtmlEntities($aLastQueries[$iIdx]['query']); + } + } + + return $aLastQueries; + } +} \ No newline at end of file diff --git a/templates/components/global-search/layout.html.twig b/templates/components/global-search/layout.html.twig new file mode 100644 index 000000000..3a10e770c --- /dev/null +++ b/templates/components/global-search/layout.html.twig @@ -0,0 +1,38 @@ + + +{# TODO: Move this to a dedicated script file #} + + \ No newline at end of file diff --git a/templates/layouts/navigation-menu/layout.html.twig b/templates/layouts/navigation-menu/layout.html.twig index 1198e41e7..d199c7b0d 100644 --- a/templates/layouts/navigation-menu/layout.html.twig +++ b/templates/layouts/navigation-menu/layout.html.twig @@ -14,7 +14,7 @@
{% for aMenuGroup in aNavigationMenu.aMenuGroups %} - {{ include('layouts/navigation-menu/menu-group.html.twig', { aMenuGroup: aMenuGroup }, false) }} + {{ include('layouts/navigation-menu/menu-group.html.twig', { aMenuGroup: aMenuGroup }) }} {% endfor %}
@@ -30,7 +30,7 @@
{% for aMenuGroup in aNavigationMenu.aMenuGroups %} - {{ include('layouts/navigation-menu/menu-nodes.html.twig', { aMenuGroup: aMenuGroup }, false) }} + {{ include('layouts/navigation-menu/menu-nodes.html.twig', { aMenuGroup: aMenuGroup }) }} {% endfor %}
diff --git a/templates/layouts/navigation-menu/menu-node.html.twig b/templates/layouts/navigation-menu/menu-node.html.twig index 3069cb0d8..1ce87c59b 100644 --- a/templates/layouts/navigation-menu/menu-node.html.twig +++ b/templates/layouts/navigation-menu/menu-node.html.twig @@ -8,7 +8,7 @@ {% if aMenuNode.aSubMenuNodes is defined and aMenuNode.aSubMenuNodes|length > 0 %} {% endif %} diff --git a/templates/layouts/navigation-menu/menu-nodes.html.twig b/templates/layouts/navigation-menu/menu-nodes.html.twig index 6d0dd4ab7..aee8bab05 100644 --- a/templates/layouts/navigation-menu/menu-nodes.html.twig +++ b/templates/layouts/navigation-menu/menu-nodes.html.twig @@ -2,7 +2,7 @@

{{ aMenuGroup.sTitle }}

\ No newline at end of file diff --git a/templates/layouts/top-bar/layout.html.twig b/templates/layouts/top-bar/layout.html.twig index daee443b8..105e30c39 100644 --- a/templates/layouts/top-bar/layout.html.twig +++ b/templates/layouts/top-bar/layout.html.twig @@ -1,3 +1,6 @@ \ No newline at end of file diff --git a/templates/pages/backoffice/layout.html.twig b/templates/pages/backoffice/layout.html.twig index 7e517cd47..f31a4bc20 100644 --- a/templates/pages/backoffice/layout.html.twig +++ b/templates/pages/backoffice/layout.html.twig @@ -38,9 +38,9 @@ {% endblock %} - {{ include('layouts/navigation-menu/layout.html.twig', { aNavigationMenu: aLayouts.aNavigationMenu }, false) }} + {{ include('layouts/navigation-menu/layout.html.twig', { aNavigationMenu: aLayouts.aNavigationMenu }) }}
- {{ include('layouts/top-bar/layout.html.twig', { aTopBar: aLayouts.aTopBar }, false) }} + {{ include('layouts/top-bar/layout.html.twig', { aTopBar: aLayouts.aTopBar }) }}
{{ aPage.aSanitizedContent|raw }}