Let the platform do the work

Moving Footer content to Sidebar Nav

Overview

This example explains how to add additional buttons to a new section in the sidebar nav layout. You may have previously customized a button that was added to the footer layout, which can be repurposed here and added to the sidebar-nav layout. We will create a custom view and append the view component to the sidebar-nav layout metadata. The additional button will merely show an alert and a flyout menu with a link to the Accounts module but can be expanded to do much more.

Steps To Complete

This tutorial requires the following steps, which are explained in the sections below:

  1. Extend the language files to include the new labels
  2. Creating the Custom View
  3. Appending the View to Layout Metadata
  4. Adding a Secondary Action

Extending the Language files to Include New Labels

We'll want to add a couple of new labels for our new sidebar-nav-item. To do this, create the following file:

./custom/Extension/application/Ext/Language/en_us.greetingNavItem.php

  <?php

// Create the "Hello" label
$app_strings['LBL_HELLO_C'] = 'Hello!';

Creating the Custom View with a Primary Action

To add a new sidebar-nav-item, you will first need to create the custom view that extends sidebar-nav-item. To create the custom view create a folder in ./custom/clients/base/views with the name of your view, such as ./custom/clients/base/views/greeting-nav-item/. Once your folder is in place, you can create the two primary files that make up your view. By default, we can use the out-of-the-box template for our view.

  1. greeting-nav-item.js - Contains the JavaScript controller logic
  2. greeting-nav-item.php - Contains the metadata your view might use. For this example, we simply use the metadata to define whether the greeting will auto-close or not.

./custom/clients/base/views/greeting-nav-item/greeting-nav-item.js

  ({
    extendsFrom: 'SidebarNavItemView',

    primaryActionOnClick: function() {
        app.alert.show('greeting-alert', {
            level: 'info',
            messages: 'Hello '+ app.user.get('full_name') + '!',
            autoClose: this.meta.autoClose || false
        });
    },
})

./custom/clients/base/views/greeting-nav-item/greeting-nav-item.php:

  <?php

$viewdefs['base']['view']['greeting-nav-item'] = array(
    'autoClose' => true
);

Appending the View to Layout Metadata

Once the view is created, you simply need to add the view to the sidebar-nav Layout metadata. The sidebar-nav Layout is located in ./clients/base/layouts/sidebar-nav/, so appending the view to this layout can be done via the Extension Framework. Create a file  ./custom/Extension/application/Ext/clients/base/layouts/sidebar-nav/ and the Extension Framework will append the metadata to the sidebar-nav Layout.

./custom/Extension/application/Ext/clients/base/layouts/sidebar-nav/greeting-nav-item.php

  <?php 

$viewdefs['base']['layout']['sidebar-nav']['components'][] = [
  'view' => [
      'name' => 'greeting-nav-item',
      'type' => 'greeting-nav-item',
      'icon' => 'sicon-bell-lg',
      'label' => 'LBL_HELLO_C',
      'template' => 'sidebar-nav-item',
   ],
];

Once all the files are in place, you can run a Quick Repair and Rebuild and a new group  sidebar-nav-item at the bottom of the sidebar-nav bar layout.

Group 1 

Note: You may need to refresh the page to see the profile menu items removed.

Adding a Secondary Action

With the introduction of the sidebar-nav-item component, we're now introducing Secondary Actions. These appear by way of a kebab menu when hovering on the sidebar-nav-item container to which they are added. It can be configured similarly to a Primary Action.

In this example, we'll add a secondary action to our greeting-nav-item view. It will trigger a flyout menu that has a link to the Accounts module.

First, let's add a new label to the language file we created earlier for our flyout menu header:

  <?php

// Create the "Greetings" header 
$app_strings['LBL_GREETINGS_C'] = 'Greetings';
 

Next, we can define the components that will be used in the flyout menus via metadata in greeting-nav-item.php. The new metadata looks like this:

./custom/Extension/application/Ext/clients/base/layouts/sidebar-nav/greeting-nav-item.php

<?php

$viewdefs['base']['layout']['sidebar-nav']['components'][] = [
    'view' => [
        'name' => 'greeting-nav-item',
        'type' => 'greeting-nav-item',
        'icon' => 'sicon-bell-lg',
        'label' => 'LBL_HELLO_C',
        'secondary_action' => true,
        'template' => 'sidebar-nav-item',
        'flyoutComponents' => [
            [
                'view' => 'sidebar-nav-flyout-header',
                'title' => 'LBL_GREETINGS_C',
            ],
            [
                'view' => [
                    'type' => 'sidebar-nav-flyout-actions',
                    'actions' => [
                        [
                            'route' => '#Accounts',
                            'label' => 'LBL_ACCOUNTS',
                            'icon' => 'sicon-account-lg',
                        ],
                    ],
                ],
            ],
        ],
    ],
];
 

Once these changes are added, you can run a Quick Repair and Rebuild and sidebar-nav-item will be updated with a Secondary Action.

Group 2
 

Note: You may need to refresh the page to see the profile menu items removed.

 

Customizing the sidebar-nav-item Template

By default, our new sidebar-nav-item is using the base Handlebars template. If you'd like to customize the template, create the following Handlebar Template file greeting-nav-item.hbs. The following snippet is the template for the base view for reference. 

./custom/clients/base/views/greeting-nav-item/greeting-nav-item.hbs

{{#if appIsSynced}}
    <button class="sidebar-nav-item-btn w-full bg-transparent absolute p-0 text-base text-initial"
       rel="tooltip"
       data-placement="{{tooltipPlacement}}"
       title="{{str label}}"
    >
        <span class="collapsed block ml-0 px-5.5 py-2" rel="tooltip" data-placement="{{tooltipPlacement}}" title="{{str label module}}">
            <i class="{{buildIcon icon}} text-white"></i>
        </span>
        <span class="expanded ellipsis_inline ml-0 px-5.5 py-2 text-white"  rel="tooltip" data-placement="{{tooltipPlacement}}" title="{{str label module}}">
            <i class="{{buildIcon icon}} text-white"></i>
            <span class="text-sm pl-4.5">{{str label}}</span>
        </span>
    </button>
    
    {{#if secondaryAction}}
        <button class="sidebar-nav-item-kebab bg-transparent absolute p-0 h-full">
            <i class="{{buildIcon 'sicon-kebab'}} text-white"></i>
        </button>
    {{/if}}
{{/if}}

Next, in ./custom/Extension/application/Ext/clients/base/layouts/sidebar-nav/greeting-nav-item.php remove the 'template' => 'sidebar-nav-item' metadata entry. 

Note: Sidebar components must be expanded/collapsed state aware now, therefore you must make sure to provide collapsed (simple icon) and expanded (icon + text) class elements in your buttons.

Changing position of sidebar-nav-item

If you need to change the position of the sidebar-nav-item in the sidebar-nav layout, it is recommended that the layout be redefined using custom metadata. For example, if you wanted to move the group we created above, we could define the custom metadata as such:

./custom/clients/base/layouts/sidebar-nav/sidebar-nav.php

<?php

/*
 * Your installation or use of this SugarCRM file is subject to the applicable
 * terms available at
 * http://support.sugarcrm.com/Resources/Master_Subscription_Agreements/.
 * If you do not agree to all of the applicable terms or do not have the
 * authority to bind the entity as an authorized representative, then do not
 * install or use this SugarCRM file.
 *
 * Copyright (C) SugarCRM Inc. All rights reserved.
 */

$viewdefs['base']['layout']['sidebar-nav'] = [
    'components' => [
        [ 
            'layout' => '...',
        ],
        [
            'layout' => [
                'type' => 'sidebar-nav-item-group-modules',
                'css_class' => 'flex-grow flex-shrink',
            ],
        ],
        [
            'layout' => [
                'type' => 'sidebar-nav-item-group',
                'name' => 'sidebar-nav-item-group-bottom',
                'css_class' => 'flex-grow-0 flex-shrink-0',
                'components' => [
                    [
                        'view' => [
                            'name' => 'footer-greet-button',
                            'type' => 'footer-greet-button',
                            'route' => '#Accounts',
                            'icon' => 'sicon-bell-lg',
                            'label' => 'Hello!',
                            'flyoutComponents' => [
                                [
                                    'view' => 'sidebar-nav-flyout-header',
                                    'title' => 'Greetings',
                                ],
                                [
                                    'view' => [
                                        'type' => 'sidebar-nav-flyout-actions',
                                        'actions' => [
                                            [
                                                'route' => '#Accounts',
                                                'label' => 'LBL_ACCOUNTS',
                                                'icon' => 'sicon-account-lg',
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                ],
            ],
        ],
        [
            'layout' => [
                'type' => 'sidebar-nav-item-group',
                'name' => 'sidebar-nav-item-group-bottom',
                'css_class' => 'flex-grow-0 flex-shrink-0',
                'components' => [ ... ],
            ],
        ],
    ],
];

Note: Although this is a best practice for customizing base metadata, these base layouts are subject to change and may be changed in the future. Maintenance of these customizations belongs to the owner of the instance.