[!!!][FEATURE] Allow reloading of backend topbar 83/51183/4
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Sat, 7 Jan 2017 19:14:37 +0000 (20:14 +0100)
committerGeorg Ringer <georg.ringer@gmail.com>
Mon, 9 Jan 2017 18:35:07 +0000 (19:35 +0100)
A new API is introduced that allows to reload the backend’s topbar.
The reload may be triggered via JavaScript and PHP.

As the registered events of the toolbar items within the topbar get lost
after reloading, the event registration for these toolbar items needs
some adoption.

The topbar is now reloaded in case of:
- updating the user's avatar
- after configuring an extension
- opening the EXT:belog module from the System Information menu

Resolves: #79196
Releases: master
Change-Id: Ib6b65d7327c9db2b818ad9ad549cb2f2f00d1595
Reviewed-on: https://review.typo3.org/51183
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
20 files changed:
typo3/sysext/backend/Classes/Controller/BackendController.php
typo3/sysext/backend/Classes/Utility/BackendUtility.php
typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php
typo3/sysext/backend/Resources/Private/Partials/Backend/Topbar.html [new file with mode: 0644]
typo3/sysext/backend/Resources/Private/Templates/Backend/Main.html
typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js
typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ClearCacheMenu.js
typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ShortcutMenu.js
typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/SystemInformationMenu.js
typo3/sysext/backend/Resources/Public/JavaScript/Viewport.js
typo3/sysext/core/Documentation/Changelog/master/Breaking-79196-ToolbarItemEventHandlingChanged.rst [new file with mode: 0644]
typo3/sysext/core/Documentation/Changelog/master/Feature-79196-AllowReloadOfTopbar.rst [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Controller/AbstractController.php
typo3/sysext/extensionmanager/Classes/Controller/ActionController.php
typo3/sysext/extensionmanager/Classes/Controller/ConfigurationController.php
typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php
typo3/sysext/opendocs/Resources/Public/JavaScript/Toolbar/OpendocsMenu.js
typo3/sysext/setup/Classes/Controller/SetupModuleController.php
typo3/sysext/workspaces/Resources/Public/JavaScript/Toolbar/WorkspacesMenu.js

index 5adbfed..fb5c0fc 100644 (file)
@@ -76,6 +76,11 @@ class BackendController
     protected $templatePath = 'EXT:backend/Resources/Private/Templates/';
 
     /**
+     * @var string
+     */
+    protected $partialPath = 'EXT:backend/Resources/Private/Partials/';
+
+    /**
      * @var \TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository
      */
     protected $backendModuleRepository;
@@ -262,40 +267,8 @@ class BackendController
         // Prepare the scaffolding, at this point extension may still add javascript and css
         $view = $this->getFluidTemplateObject($this->templatePath . 'Backend/Main.html');
 
-        // Extension Configuration to find the TYPO3 logo in the left corner
-        $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['backend'], ['allowed_classes' => false]);
-        $logoPath = '';
-        if (!empty($extConf['backendLogo'])) {
-            $customBackendLogo = GeneralUtility::getFileAbsFileName($extConf['backendLogo']);
-            if (!empty($customBackendLogo)) {
-                $logoPath = $customBackendLogo;
-            }
-        }
-        // if no custom logo was set or the path is invalid, use the original one
-        if (empty($logoPath)) {
-            $logoPath = GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Images/typo3_logo_orange.svg');
-            $logoWidth = 22;
-            $logoHeight = 22;
-        } else {
-            // set width/height for custom logo
-            $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $logoPath);
-            $logoWidth = $imageInfo->getWidth() ?? '22';
-            $logoHeight = $imageInfo->getHeight() ?? '22';
-
-            // High-resolution?
-            if (strpos($logoPath, '@2x.') !== false) {
-                $logoWidth /= 2;
-                $logoHeight /= 2;
-            }
-        }
-
-        $view->assign('logoUrl', PathUtility::getAbsoluteWebPath($logoPath));
-        $view->assign('logoWidth', $logoWidth);
-        $view->assign('logoHeight', $logoHeight);
-        $view->assign('applicationVersion', TYPO3_version);
-        $view->assign('siteName', $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']);
         $view->assign('moduleMenu', $this->generateModuleMenu());
-        $view->assign('toolbar', $this->renderToolbar());
+        $view->assign('topbar', $this->renderTopbar());
 
         /******************************************************
          * Now put the complete backend document together
@@ -343,6 +316,52 @@ class BackendController
     }
 
     /**
+     * Renders the topbar, containing the backend logo, sitename etc.
+     *
+     * @return string
+     */
+    protected function renderTopbar()
+    {
+        $view = $this->getFluidTemplateObject($this->partialPath . 'Backend/Topbar.html');
+
+        // Extension Configuration to find the TYPO3 logo in the left corner
+        $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['backend'], ['allowed_classes' => false]);
+        $logoPath = '';
+        if (!empty($extConf['backendLogo'])) {
+            $customBackendLogo = GeneralUtility::getFileAbsFileName($extConf['backendLogo']);
+            if (!empty($customBackendLogo)) {
+                $logoPath = $customBackendLogo;
+            }
+        }
+        // if no custom logo was set or the path is invalid, use the original one
+        if (empty($logoPath)) {
+            $logoPath = GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Images/typo3_logo_orange.svg');
+            $logoWidth = 22;
+            $logoHeight = 22;
+        } else {
+            // set width/height for custom logo
+            $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $logoPath);
+            $logoWidth = $imageInfo->getWidth() ?? '22';
+            $logoHeight = $imageInfo->getHeight() ?? '22';
+
+            // High-resolution?
+            if (strpos($logoPath, '@2x.') !== false) {
+                $logoWidth /= 2;
+                $logoHeight /= 2;
+            }
+        }
+
+        $view->assign('logoUrl', PathUtility::getAbsoluteWebPath($logoPath));
+        $view->assign('logoWidth', $logoWidth);
+        $view->assign('logoHeight', $logoHeight);
+        $view->assign('applicationVersion', TYPO3_version);
+        $view->assign('siteName', $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']);
+        $view->assign('toolbar', $this->renderToolbar());
+
+        return $view->render();
+    }
+
+    /**
      * Loads the css and javascript files of all registered navigation widgets
      *
      * @return void
@@ -837,6 +856,19 @@ class BackendController
     }
 
     /**
+     * Returns the toolbar for the AJAX request
+     *
+     * @param ServerRequestInterface $request
+     * @param ResponseInterface $response
+     * @return ResponseInterface
+     */
+    public function getTopbar(ServerRequestInterface $request, ResponseInterface $response)
+    {
+        $response->getBody()->write(json_encode(['topbar' => $this->renderTopbar()]));
+        return $response;
+    }
+
+    /**
      * returns a new standalone view, shorthand function
      *
      * @param string $templatePathAndFileName optional the path to set the template path and filename
@@ -845,6 +877,7 @@ class BackendController
     protected function getFluidTemplateObject($templatePathAndFileName = null)
     {
         $view = GeneralUtility::makeInstance(StandaloneView::class);
+        $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]);
         if ($templatePathAndFileName) {
             $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFileName));
         }
index f52e8b0..e7b4dc2 100644 (file)
@@ -3533,6 +3533,13 @@ class BackendUtility
                                                                if (top && top.TYPO3.ModuleMenu && top.TYPO3.ModuleMenu.App) {
                                                                        top.TYPO3.ModuleMenu.App.refreshMenu();
                                                                }';
+                        break;
+                    case 'updateTopbar':
+                        $signals[] = '
+                                                               if (top && top.TYPO3.Backend && top.TYPO3.Backend.Topbar) {
+                                                                       top.TYPO3.Backend.Topbar.refresh();
+                                                               }';
+                        break;
                 }
             }
         }
index 2ee8bd2..b8a8747 100644 (file)
@@ -111,6 +111,10 @@ return [
         'path' => '/module-menu',
         'target' => Controller\BackendController::class . '::getModuleMenu'
     ],
+    'topbar' => [
+        'path' => '/topbar',
+        'target' => Controller\BackendController::class . '::getTopbar'
+    ],
 
     // Log in into backend
     'login' => [
diff --git a/typo3/sysext/backend/Resources/Private/Partials/Backend/Topbar.html b/typo3/sysext/backend/Resources/Private/Partials/Backend/Topbar.html
new file mode 100644 (file)
index 0000000..74ccfe2
--- /dev/null
@@ -0,0 +1,37 @@
+{namespace core = TYPO3\CMS\Core\ViewHelpers}
+<div class="scaffold-topbar t3js-scaffold-topbar">
+       <div class="topbar">
+               <div class="topbar-header t3js-topbar-header">
+                       <button class="topbar-button topbar-button-modulemenu t3js-topbar-button-modulemenu">
+                               <core:icon identifier="actions-move-move" alternativeMarkupIdentifier="inline" />
+                       </button>
+                       <button class="topbar-button topbar-button-navigationcomponent t3js-topbar-button-navigationcomponent">
+                               <core:icon identifier="apps-pagetree-category-collapse-all" alternativeMarkupIdentifier="inline" />
+                       </button>
+                       <div class="topbar-header-site">
+                               <a href="./" target="_top" title="{siteName} - {applicationVersion}">
+                                       <span class="topbar-header-site-logo">
+                                               <img src="{logoUrl}" width="{logoWidth}" height="{logoHeight}" title="TYPO3 Content Management System" alt="" />
+                                       </span>
+                                       <span class="topbar-header-site-title">
+                                               <span class="topbar-header-site-name">{siteName}</span>
+                                               <span class="topbar-header-site-version">{applicationVersion}</span>
+                                       </span>
+                               </a>
+                       </div>
+                       <button class="topbar-button topbar-button-toolbar t3js-topbar-button-toolbar">
+                               <core:icon identifier="actions-system-extension-configure" alternativeMarkupIdentifier="inline" />
+                       </button>
+                       <button class="topbar-button topbar-button-search t3js-topbar-button-search">
+                               <core:icon identifier="actions-search" alternativeMarkupIdentifier="inline" />
+                       </button>
+               </div>
+       </div>
+</div>
+<div class="scaffold-toolbar t3js-scaffold-toolbar">
+       <div class="toolbar t3js-topbar-toolbar">
+               <ul class="toolbar-list" data-typo3-role="typo3-module-menu">
+                       <f:format.raw>{toolbar}</f:format.raw>
+               </ul>
+       </div>
+</div>
\ No newline at end of file
index 4e9132b..3f8f8d1 100644 (file)
@@ -1,48 +1,12 @@
-{namespace core = TYPO3\CMS\Core\ViewHelpers}
 <div class="scaffold t3js-scaffold scaffold-modulemenu-expanded">
-       <div class="scaffold-topbar t3js-scaffold-topbar">
-
-               <div class="topbar">
-                       <div class="topbar-header t3js-topbar-header">
-                               <button class="topbar-button topbar-button-modulemenu t3js-topbar-button-modulemenu">
-                                       <core:icon identifier="actions-move-move" alternativeMarkupIdentifier="inline" />
-                               </button>
-                               <button class="topbar-button topbar-button-navigationcomponent t3js-topbar-button-navigationcomponent">
-                                       <core:icon identifier="apps-pagetree-category-collapse-all" alternativeMarkupIdentifier="inline" />
-                               </button>
-                               <div class="topbar-header-site">
-                                       <a href="./" target="_top" title="{siteName} - {applicationVersion}">
-                                               <span class="topbar-header-site-logo">
-                                                       <img src="{logoUrl}" width="{logoWidth}" height="{logoHeight}" title="TYPO3 Content Management System" alt="" />
-                                               </span>
-                                               <span class="topbar-header-site-title">
-                                                       <span class="topbar-header-site-name">{siteName}</span>
-                                                       <span class="topbar-header-site-version">{applicationVersion}</span>
-                                               </span>
-                                       </a>
-                               </div>
-                               <button class="topbar-button topbar-button-toolbar t3js-topbar-button-toolbar">
-                                       <core:icon identifier="actions-system-extension-configure" alternativeMarkupIdentifier="inline" />
-                               </button>
-                               <button class="topbar-button topbar-button-search t3js-topbar-button-search">
-                                       <core:icon identifier="actions-search" alternativeMarkupIdentifier="inline" />
-                               </button>
-                       </div>
-               </div>
-
+       <div class="t3js-scaffold-header">
+               <f:format.raw>{topbar}</f:format.raw>
        </div>
        <div class="scaffold-modulemenu t3js-scaffold-modulemenu">
                <div class="modulemenu t3js-modulemenu">
                        <f:format.raw>{moduleMenu}</f:format.raw>
                </div>
        </div>
-       <div class="scaffold-toolbar t3js-scaffold-toolbar">
-               <div class="toolbar t3js-topbar-toolbar">
-                       <ul class="toolbar-list" data-typo3-role="typo3-module-menu">
-                               <f:format.raw>{toolbar}</f:format.raw>
-                       </ul>
-               </div>
-       </div>
        <div class="scaffold-content t3js-scaffold-content">
                <div class="scaffold-content-navigation t3js-scaffold-content-navigation">
                        <div class="scaffold-content-navigation-component" data-component="typo3-navigationIframe">
index 32d8cee..9ef0d2b 100644 (file)
  * Global search to deal with everything in the backend that is search-related
  * @exports TYPO3/CMS/Backend/LiveSearch
  */
-define(['jquery', 'jquery/autocomplete', 'TYPO3/CMS/Backend/jquery.clearable'], function ($) {
+define([
+       'jquery',
+       'TYPO3/CMS/Backend/Viewport',
+       'jquery/autocomplete',
+       'TYPO3/CMS/Backend/jquery.clearable'
+], function ($, Viewport) {
        'use strict';
 
        var containerSelector = '#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem';
@@ -28,7 +33,7 @@ define(['jquery', 'jquery/autocomplete', 'TYPO3/CMS/Backend/jquery.clearable'],
        var url = TYPO3.settings.ajaxUrls['livesearch'];
        var category = '';
 
-       $(function() {
+       Viewport.Topbar.Toolbar.registerEvent(function() {
                $(searchFieldSelector).autocomplete({
                        // ajax options
                        serviceUrl: url,
index 22558fa..6604155 100644 (file)
  * main functionality for clearing caches via the top bar
  * reloading the clear cache icon
  */
-define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Notification'], function($, Icons, Notification) {
+define([
+       'jquery',
+       'TYPO3/CMS/Backend/Icons',
+       'TYPO3/CMS/Backend/Notification',
+       'TYPO3/CMS/Backend/Viewport'
+], function($, Icons, Notification, Viewport) {
        'use strict';
 
        /**
@@ -76,7 +81,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Notification'],
                });
        };
 
-       $(ClearCacheMenu.initializeEvents);
+       Viewport.Topbar.Toolbar.registerEvent(ClearCacheMenu.initializeEvents);
 
        return ClearCacheMenu;
 });
index 91145a9..a9da605 100644 (file)
@@ -19,8 +19,9 @@
 define(['jquery',
                'TYPO3/CMS/Backend/Modal',
                'TYPO3/CMS/Backend/Icons',
-               'TYPO3/CMS/Backend/Notification'
-       ], function($, Modal, Icons, Notification) {
+               'TYPO3/CMS/Backend/Notification',
+               'TYPO3/CMS/Backend/Viewport'
+       ], function($, Modal, Icons, Notification, Viewport) {
        'use strict';
 
        /**
@@ -210,7 +211,7 @@ define(['jquery',
                });
        };
 
-       $(ShortcutMenu.initializeEvents);
+       Viewport.Topbar.Toolbar.registerEvent(ShortcutMenu.initializeEvents);
 
        // expose as global object
        TYPO3.ShortcutMenu = ShortcutMenu;
index bf03794..b3bb52e 100644 (file)
  * Module: TYPO3/CMS/Backend/Toolbar/SystemInformationMenu
  * System information menu handler
  */
-define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], function($, Icons, Storage) {
+define([
+       'jquery',
+       'TYPO3/CMS/Backend/Icons',
+       'TYPO3/CMS/Backend/Storage',
+       'TYPO3/CMS/Backend/Viewport'
+], function($, Icons, Storage, Viewport) {
        'use strict';
 
        /**
@@ -28,10 +33,8 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], funct
                        containerSelector: '#typo3-cms-backend-backend-toolbaritems-systeminformationtoolbaritem',
                        toolbarIconSelector: '.toolbar-item-icon .t3js-icon',
                        menuContainerSelector: '.dropdown-menu',
-                       moduleLinks: '.t3js-systeminformation-module'
-               },
-               elements: {
-                       $counter: $('.t3js-systeminformation-counter')
+                       moduleLinks: '.t3js-systeminformation-module',
+                       counter: '.t3js-systeminformation-counter'
                }
        };
 
@@ -78,14 +81,15 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], funct
         */
        SystemInformationMenu.updateCounter = function() {
                var $container = $(SystemInformationMenu.identifier.containerSelector).find(SystemInformationMenu.identifier.menuContainerSelector).find('.t3js-systeminformation-container'),
+                       $counter = $(SystemInformationMenu.identifier.counter),
                        count = $container.data('count'),
                        badgeClass = $container.data('severityclass');
 
-               SystemInformationMenu.elements.$counter.text(count).toggle(parseInt(count) > 0);
-               SystemInformationMenu.elements.$counter.removeClass();
+               $counter.text(count).toggle(parseInt(count) > 0);
+               $counter.removeClass();
 
                if (badgeClass !== '') {
-                       SystemInformationMenu.elements.$counter.addClass('toolbar-item-badge badge ' + badgeClass);
+                       $counter.addClass('toolbar-item-badge badge ' + badgeClass);
                }
        };
 
@@ -113,11 +117,11 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], funct
                $ajax.done(function() {
                        // finally, open the module now
                        TYPO3.ModuleMenu.App.showModule(requestedModule);
-                       SystemInformationMenu.updateMenu();
+                       Viewport.Topbar.refresh();
                });
        };
 
-       $(SystemInformationMenu.updateMenu);
+       Viewport.Topbar.Toolbar.registerEvent(SystemInformationMenu.updateMenu);
 
        return SystemInformationMenu;
 });
index 797f465..75382df 100644 (file)
@@ -142,6 +142,21 @@ define(
                                                return 0;
                                        }
                                }
+                       },
+                       Topbar: {
+                               topbarSelector: '.t3js-scaffold-header',
+                               refresh: function() {
+                                       $.ajax(TYPO3.settings.ajaxUrls['topbar']).done(function(data) {
+                                               $(TYPO3.Backend.Topbar.topbarSelector).html(data.topbar);
+                                               $(TYPO3.Backend.Topbar.topbarSelector).trigger('t3-topbar-update');
+                                       });
+                               },
+                               Toolbar: {
+                                       registerEvent: function (callback) {
+                                               $(callback);
+                                               $(TYPO3.Backend.Topbar.topbarSelector).on('t3-topbar-update', callback);
+                                       }
+                               }
                        }
                };
 
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-79196-ToolbarItemEventHandlingChanged.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-79196-ToolbarItemEventHandlingChanged.rst
new file mode 100644 (file)
index 0000000..9621560
--- /dev/null
@@ -0,0 +1,45 @@
+.. include:: ../../Includes.txt
+
+======================================================
+Breaking: #79196 - Toolbar item event handling changed
+======================================================
+
+See :issue:`79196`
+
+Description
+===========
+
+With the introduction of the topbar reloading mechanism, the event handling of toolbar items has changed. Reason is
+that the event information gets lost, as the whole topbar is rendered from scratch after a reload.
+
+
+Impact
+======
+
+After reloading the topbar, not migrated events will not get triggered anymore.
+
+
+Affected Installations
+======================
+
+All installations with old-fashioned toolbar item registrations are affected.
+
+
+Migration
+=========
+
+In most cases it's sufficient to replace the register function with `Viewport.Topbar.Toolbar.registerEvent()`.
+
+Example:
+
+.. code-block:: javascript
+
+       define(['jquery', 'TYPO3/CMS/Backend/Viewport'], function($, Viewport) {
+               // old registration
+               $(MyAwesomeItem.doStuff)
+
+               // new registration
+               Viewport.Topbar.Toolbar.registerEvent(MyAwesomeItem.doStuff);
+       });
+
+.. index:: Backend, JavaScript
\ No newline at end of file
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-79196-AllowReloadOfTopbar.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-79196-AllowReloadOfTopbar.rst
new file mode 100644 (file)
index 0000000..dc8f5e7
--- /dev/null
@@ -0,0 +1,51 @@
+.. include:: ../../Includes.txt
+
+========================================
+Feature: #79196 - Allow reload of topbar
+========================================
+
+See :issue:`79196`
+
+Description
+===========
+
+A new JavaScript API to reload the backend's topbar has been introduced to the TYPO3 Core.
+
+
+Impact
+======
+
+The toolbar reloading may be triggered on JavaScript and PHP code level. To enforce the reloading on PHP side,
+call :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::setUpdateSignal('updateTopbar')`.
+
+Reloading the topbar via JavaScript requires the following code:
+
+.. code-block:: javascript
+
+       // Either: RequireJS style
+       define(['TYPO3/CMS/Backend/Viewport'], function(Viewport) {
+               Viewport.Topbar.refresh();
+       });
+
+       // Or: old-fashioned JavaScript
+       if (top && top.TYPO3.Backend && top.TYPO3.Backend.Topbar) {
+               top.TYPO3.Backend.Topbar.refresh();
+       }';
+
+
+In case a toolbar item registers to the `load` event of the page, the registration must be changed. Reason is that the
+event information gets lost, as the whole toolbar is rendered from scratch after a reload.
+
+Example:
+
+.. code-block:: javascript
+
+       define(['jquery', 'TYPO3/CMS/Backend/Viewport'], function($, Viewport) {
+               // old registration
+               $(MyAwesomeItem.doStuff)
+
+               // new registration
+               Viewport.Topbar.Toolbar.registerEvent(MyAwesomeItem.doStuff);
+       });
+
+.. index:: Backend, JavaScript, PHP-API
\ No newline at end of file
index 2ff223e..017ac8d 100644 (file)
@@ -21,11 +21,14 @@ class AbstractController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl
 {
     const TRIGGER_RefreshModuleMenu = 'refreshModuleMenu';
 
+    const TRIGGER_RefreshTopbar = 'refreshTopbar';
+
     /**
      * @var array
      */
     protected $triggerArguments = [
         self::TRIGGER_RefreshModuleMenu,
+        self::TRIGGER_RefreshTopbar
     ];
 
     /**
index 9709562..fa16187 100644 (file)
@@ -98,7 +98,10 @@ class ActionController extends AbstractController
         } catch (\TYPO3\CMS\Core\Package\Exception\PackageStatesFileNotWritableException $e) {
             $this->addFlashMessage($e->getMessage(), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
         }
-        $this->redirect('index', 'List', null, [self::TRIGGER_RefreshModuleMenu => true]);
+        $this->redirect('index', 'List', null, [
+            self::TRIGGER_RefreshModuleMenu => true,
+            self::TRIGGER_RefreshTopbar => true
+        ]);
     }
 
     /**
index cb511ea..9e63948 100644 (file)
@@ -81,6 +81,8 @@ class ConfigurationController extends AbstractModuleController
         if (!isset($extension['key'])) {
             throw new ExtensionManagerException('Extension key not found.', 1359206803);
         }
+        $this->handleTriggerArguments();
+
         $extKey = $extension['key'];
         $configuration = $this->configurationItemRepository->findByExtensionKey($extKey);
         if ($configuration) {
@@ -117,7 +119,12 @@ class ConfigurationController extends AbstractModuleController
         ) {
             $this->redirect('welcome', 'Distribution', null, ['extension' => $extension->getUid()]);
         } else {
-            $this->redirect('showConfigurationForm', null, null, ['extension' => ['key' => $extensionKey]]);
+            $this->redirect('showConfigurationForm', null, null, [
+                'extension' => [
+                    'key' => $extensionKey
+                ],
+                self::TRIGGER_RefreshTopbar => true
+            ]);
         }
     }
 
@@ -131,7 +138,9 @@ class ConfigurationController extends AbstractModuleController
     public function saveAndCloseAction(array $config, $extensionKey)
     {
         $this->saveConfiguration($config, $extensionKey);
-        $this->redirect('index', 'List');
+        $this->redirect('index', 'List', null, [
+            self::TRIGGER_RefreshTopbar => true
+        ]);
     }
 
     /**
index 64fabba..cb53d8f 100644 (file)
@@ -179,7 +179,10 @@ class UploadExtensionFileController extends AbstractController
             $this->removeExtensionAndRestoreFromBackup($fileName);
             $this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR);
         }
-        $this->redirect('index', 'List', null, [self::TRIGGER_RefreshModuleMenu => true]);
+        $this->redirect('index', 'List', null, [
+            self::TRIGGER_RefreshModuleMenu => true,
+            self::TRIGGER_RefreshTopbar => true
+        ]);
     }
 
     /**
index e09512b..11a2af7 100644 (file)
@@ -60,6 +60,13 @@ class TriggerViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendV
                 'if (top && top.TYPO3.ModuleMenu.App) { top.TYPO3.ModuleMenu.App.refreshMenu(); }'
             );
         }
+
+        if (!empty($this->arguments['triggers'][AbstractController::TRIGGER_RefreshTopbar])) {
+            $pageRenderer->addJsInlineCode(
+                AbstractController::TRIGGER_RefreshTopbar,
+                'if (top && top.TYPO3.Backend && top.TYPO3.Backend.Topbar) { top.TYPO3.Backend.Topbar.refresh(); }'
+            );
+        }
         return '';
     }
 }
index da228a7..a690a23 100644 (file)
  *  - navigating to the documents
  *  - updating the menu
  */
-define(['jquery', 'TYPO3/CMS/Backend/Icons'], function($, Icons) {
+define([
+       'jquery',
+       'TYPO3/CMS/Backend/Icons',
+       'TYPO3/CMS/Backend/Viewport'
+], function($, Icons, Viewport) {
        'use strict';
 
        /**
@@ -113,7 +117,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons'], function($, Icons) {
                $(OpendocsMenu.options.containerSelector).toggleClass('open');
        };
 
-       $(function() {
+       Viewport.Topbar.Toolbar.registerEvent(function() {
                OpendocsMenu.initializeEvents();
                OpendocsMenu.updateMenu();
        });
index 71d4d6c..fbf0d7c 100644 (file)
@@ -299,6 +299,8 @@ class SetupModuleController extends AbstractModule
                 }
                 // Restore admin status after processing
                 $beUser->user['admin'] = $isAdmin;
+
+                BackendUtility::setUpdateSignal('updateTopbar');
             }
         }
     }
index 2a57f0d..c73d780 100644 (file)
@@ -16,7 +16,7 @@
  * toolbar menu for the workspaces functionality to switch between the workspaces
  * and jump to the workspaces module
  */
-define(['jquery'], function($) {
+define(['jquery', 'TYPO3/CMS/Backend/Viewport'], function($, Viewport) {
        'use strict';
 
        /**
@@ -160,7 +160,7 @@ define(['jquery'], function($) {
                }
        };
 
-       $(function() {
+       Viewport.Topbar.Toolbar.registerEvent(function() {
                WorkspacesMenu.initializeEvents();
                WorkspacesMenu.updateBackendContext();
        });