Enterprise Navigation Component (v3.0.16)

Change log

  • Fix width and height values for SVG inline.
  • Remove enteprise-nav-info component (help icon) from header (feature reported on FSPE-6078).

Introduction

Enterprise navigation component is formed by two components: enterprise-nav-header and enterprise-nav-menu.

Enterprise navigation header (enterprise-nav-header) component is the top component that shows items as logo, switcher, notifications, help, user and enterprises list. Enterprise navigation menu (enterprise-nav-menu) component is a vertical left menu that shows all the options available on the portal selected in the switcher component.

Those components works together. When the user selects an option in the switcher componenet, the options into the menu component will be change.

The labels for using them are:

<enterprise-nav-header></enterprise-nav-header>
<enterprise-nav-menu></enterprise-nav-menu>

Using the component

From Vanilla JS, just add those script in your index.html header:

<script type="module"
        src="https://assets.ctl.io/EnterpriseNav/{version}/dist/po-enterprise-nav/po-enterprise-nav.esm.js"></script>
<script nomodule
        src="https://assets.ctl.io/EnterpriseNav/{version}/dist/po-enterprise-nav/po-enterprise-nav.js"></script>

From other frameworks: we strongly recommend to visit https://stenciljs.com/docs/overview.

For every version, there is NPM package is available in the url: https://assets.ctl.io/EnterpriseNav/{version}/po-enterprise-nav.tgz.

Chi in Enterprise Navigation Component

Chi is needed in the application that is using the Enterprise Navigation Component. Scripts needed are:

<script src="https://assets.ctl.io/chi/3.1.0/js/chi.js"></script>
<script src="https://assets.ctl.io/chi/3.1.0/chi-icons.js"></script>
<link rel="stylesheet" href="https://assets.ctl.io/chi/3.1.0/chi.css">

For more information related to Chi, please visit: https://assets.ctl.io/chi/3.1.0/getting-started/.

Events To Configure & Manage

Component loaded

  • Listen to know when <enterprise-nav-header> component is loaded: enterpriseNavHeaderLoaded.

  • Listen to kwno when <enterprise-nav-menu> component is loaded: enterpriseNavMenuLoaded.

Once that both components are loaded, initialization function could be called on <enterprise-nav-header> component.

Initializating

  • A public method is available on <enterprise-nav-header> to initialize Enterprise Navigation Component.
// uri:         Domain where we are working on.
//              Mandatory.
//              ie:
//                `https://admin-controlcenter-itv1.centurylink.com`, `https://controlcenter-itv1.centurylink.com`, etc...
//
// menuConf:    Configuration object for menu.
//              Mandatory.
//              Property objects:
//              ** site     => Site name (from your data file) that it will be selected in the switcher.
//                             ie. 'Control Center', 'UCommand'...
//                             Mandatory.
//              ** origin   => Origin key in origin objec for your site (ex. CC, ML3).
//                             Mandatory.
//              ** option   => Menu option id selected on the initialization.
//                             This id could be find into entitledMenus endpoint.
//                             By default, the selection will be done looking for local-href value into the location.href.
//                             Not mandatory.
//              ** url      => URL or path where your data file is located.
//                             By default `/rudra/navigation/entitledMenus` value will be used.
//                             Not mandatory.
//              ** ccmenu   => Menu content gotten from Control Center endpoint or Rudra cache.
//                             If this value is added, `url` value will be ignored for getting the menu content.
//                             Not mandatory.
//              ** menu     => Menu options that you need to add dynamically to the menu component.
//                             Not mandatory.
//
// eventsConf:  Configuration object for events behaviour. Format { `<<event>>`: `<<configuration-behaviour>>` }.
//              Mandatory.
//              ** Values for `<<event>>`:
//               - "logo"                   => "same-tab" by default. This event will not work for Partner users.
//               - "notification"           => "new-tab" by default.
//               - "info"                   => "new-tab" by default.
//               - "impersonation-logout"   => "same-tab" by default.
//               - "my-profile"             => "new-tab" by default.
//               - "logout"                 => "same-tab" by default.
//               - "manage-my-enterprises"  => "new-tab" by default.
//              ** Values for `<<configuration-behaviour>>`:
//               - "emit-event": An event will be fired in order to be manage by the parent.
//               - "same-tab": A page will be open in the same tab.
//               - "new-tab": A page will be open in a new tab.
//
// { env }:     { env: environment }. Where environment can be 'local', 'stage', 'prod'. 'prod' is default value.
//              Not mandatory.
//              ** Menu behaviour:
//               - 'prod': menuConf.menu property content will maintain the sidenav styles.
//               - 'local' or 'stage': menuConf.menu property content will be shown in red color.
//              ** Logout behaviour:
//               - 'prod' value => 'https://business-signin.centurylink.com' will be used.
//               - 'stage' or 'local' values => 'https://business-auth-test.centurylink.com'.

enterpriseNavHeader.initialize(uri, eventsConf, eventsConf, { env });

Use example:

let enterpriseNavMenuLoaded = false;
let enterpriseNavHeaderLoaded = false;

function enterpriseNavMenuLoadedEvent() {
    enterpriseNavMenuLoaded = true;
    enterpriseInitialize(true);
};

function enterpriseNavHeaderLoadedEvent() {
    enterpriseNavHeaderLoaded = true;
    enterpriseInitialize(true);
};

function enterpriseInitialize(addListener) {
  let uri = 'https://controlcenter-itv1.centurylink.com';
  let menuConf = {
    site: 'Control Center',
    origin: 'CC',
  };
  let eventsConf = {
    'notification': 'same-tab',
            'info': 'same-tab',
  };
  let environment = 'stage';

  const enterpriseNavMenu = document.querySelector('enterprise-nav-menu');
  const enterpriseNavHeader = document.querySelector('enterprise-nav-header');

  if (
    enterpriseNavMenu && enterpriseNavHeader &&
    enterpriseNavMenuLoaded && enterpriseNavHeaderLoaded
  ) {
    enterpriseNavMenu.addEventListener('enterpriseNavMenuSelected', function menuSelected(event) {
      // actions when an option in the left menu is selected
      // refer Listening section to `enterpriseNavMenuSelected` event
    });
    enterpriseNavHeader.addEventListener('enterpriseNavHeaderSelected', function headerSelected(event) {
      // actions when an option in the header is selected
      // refer Listening section to `enterpriseNavHeaderSelected` event
    });
    enterpriseNavMenu.addEventListener('enterpriseNavMenuHighlighted', function updateMenuOption(event) {
      // actions depending on the menu option selected
    });

    enterpriseNavHeader.initialize(uri, menuConf, eventsConf, { env: environment });
  }
};

document.addEventListener('enterpriseNavMenuLoaded', enterpriseNavMenuLoadedEvent);
document.addEventListener('enterpriseNavHeaderLoaded', enterpriseNavHeaderLoadedEvent);

Framework notes:

In order to configure properly eventsConf object, EventConfiguration type should imported from po-enterprise-nav library.

import { EventConfiguration } from 'po-enterprise-nav';

let eventsConf: Record<string, EventConfiguration> = {
  'notification': EventConfiguration.SAME_TAB,
  'info': EventConfiguration.NEW_TAB,
  'imperonation-logout': EventConfiguration.EMIT,
};

On the other hand, adding listener should be done in the constructor methos or in 'create' or 'init' lifecycle events. Please, remember to remove these listeners in 'destroy' event in order to avoid memory leaks on the browser.

Listening

  • Listener name to link <enterprise-nav-menu> component with the management function: enterpriseNavMenuSelected.
const enterpriseNavMenu = document.querySelector('enterprise-nav-menu');
enterpriseNavMenu.addEventListener('enterpriseNavMenuGoLink', function goLink(event) {

  // Event will be fired always an user had clicked a menu option in the same domain.
  // `event` is a CustomEvent type with the format:
  //   {
  //      detail: "local-href" property from menu option name entry in JSON file
  //   }

});
  • Listener name to link <enterprise-nav-menu> component with the management funcion: enterpriseNavMenuHighlighted.
const enterpriseNavMenu = document.querySelector('enterprise-nav-menu');
enterpriseNavMenu.addEventListener('enterpriseNavMenuHighlighted', function checkUpdateMenuOption(event) {

  // Event will be fired after calling initialize or update methods for `<enterprise-nav-menu>` component.
  // `event` is a CustomEvent type with the format:
  //   {
  //      detail: {
  //        "isSelected": `<<true when an option is selected, otherwise false>>`,
  //        "localHref": `<<local-href value selected from entitledMenus>>`,
  //        "id": `<<id value selected from entitledMenus>>`,
  //      }
  //   }

});
  • Listener name to link <enterprise-nav-header> component with the management function: enterpriseNavHeaderSelected.
const enterpriseNavHeader = document.querySelector('enterprise-nav-header');
enterpriseNavHeader.addEventListener('enterpriseNavHeaderSelected', function headerSelected(event) {

  // Event will be fired in two situations:
  // 1. User has selected an enterprise in the enterprises list. Backend is already updated with the new enterprise.
  //    `event` is a CustomEvent type with the format:
  //      {
  //        detail: {
  //          "type": "enterprise",
  //          "value": `<<enterprise object selected>>`,
  //        }
  //      }
  // 2. An event was configured as `emit-event` in the eventsConf object.
  //    `event` is a CustomEvent type with the format:
  //      {
  //        detail: {
  //          "type": "link",
  //          "value": `<<event>>`,
  //          "path": `<<selected option relative path>>`,
  //          "uri": `<<uri set in the initialization object or logout uri depens on env value>>`,
  //        }
  //      }

});

Updating

A public method is available on <enterprise-nav-header> to update Enterprise Navigation Component.

  • With IHeader parameter. The Enterprise Navigation Component will not make any API call, and just update the information available into the parameter.
// iheader:   property object available to update manually.
//            IHeader type:
//            {
//              alertsUnread: `<<new alert unread number to set>>`
//              menuOption: `<<new id menu option to set>>`. `enterpriseNavMenuHighlighted` event will be emit after update the menu option
//            }

enterpriseNavHeader.update(iheader);

Use example with parameter:

const enterpriseNavHeader = document.querySelector('enterprise-nav-header');

let iheader: IHeader = {
  alertsUnread: 6
}
enterpriseNavHeader.update(iheader);

let iheader: IHeader = {
  menuOption: "users"
}
enterpriseNavHeader.update(iheader);

In addition to the public method, Enterprise Navigation Component has the ability of update the menu option always that the URL has changed. In these cases, the component will emit the enterpriseNavMenuHighlighted event in order to inform that the value has changed.

The options that menu component is shown are located into

  • menus-2.1.3.json file located in https://assets.ctl.io/menu/menus-2.1.3.json.
  • Control Center endpoint (/rudra/navigation/entitledMenus).

menus-2.1.3.json file has the above structure:

[
  { "value: portal name.": {
      "description": "value: portal description.",

      "origin": [
        // first item will be the option by default
        { "value: origin key.": "value: origin or domain." },

        ...
      ],

      "menu": [
        // internal menu option (WITHOUT second level)
        { "value: menu option name.": {
            "icon": "value: chi icon. Not required.",
            "site": "OriginKey. Not required.",
            "local-href: "value: relative path. Required.",
            "href": "value: complete url. If site exists, required.",
            "id": "value: identifier for the menu option."
          }
        },

        // external menu option (WITHOUT second level)
        { "value: menu option name.": {
            "icon": "value: chi icon. Not required",
            "ext": "value: true. Required",
            "window": "value: window name. Not required.",
            "href: "value: complete url. Required"
          }
        },

        // menu option WITH second level
        { "value: menu option name.": {
            "icon": "value: chi icon. Not required.",
            "menu": [

              // internal menu option (WITHOUT third level)
              { "value: menu option name.": {
                  "site": "OriginKey. Not required.",
                  "local-href: "value: relative path. Required.",
                  "href": "value: complete url. If site exists, required.",
                  "id": "value: identifier for the menu option."
                }
              },

              // external menu option (WITHOUT third level)
              { "value: menu option name.": {
                  "ext": "value: true. Required.",
                  "window": "value: window name. Not required.",
                  "href: "value: complete url. Required."
                }
              },

              // menu option WITH third level
              { "value: menu option name.": {
                  "menu": [

                    // internal menu option
                    { "value: menu option name.": {
                        "site": "OriginKey. Not required.",
                        "local-href: "value: relative path. Required.",
                        "href": "value: complete url. If site exists, required.",
                        "id": "value: identifier for the menu option."
                      }
                    },

                    // external menu option
                    { "value: menu option name.": {
                        "ext": "value: true. Required.",
                        "window": "value: window name. Not required.",
                        "href: "value: complete url. Required."
                      }
                    },

                    ...
                  ]
                }
              },

              ...
            ]
          }
        },

        ...
      ]
    }
  },

  ...
]

Cypress end-2-end and accessibility tests

  • In tests/ you'll find the Cypress end-to-end (e2e) and accessibility (a11y) tests.
  • Tests are separate to local and prod ENVs where each loads different menu.
  • When running tests, the menus are loaded from fixtures located in /tests/fixtures/.
  • For each ENV we test 2 different components:
    • enterprise-nav-menu (side-menu).
    • enterprise-nav-switcher (top, "Enterprise Menu" dropdown).
  • When tests are run, they always test e2e test; running a11y tests is optional (More on that below).
  • Errors from accessibility tests are fixed.
  • Tests can be run in terminal or with GUI.

Running tests:

  • run e2e tests with GUI for each ENV

    • npm run cy:e2e:local:gui
    • npm run cy:e2e:prod:gui
  • run e2e and a11y tests with GUI for each ENV

    • npm run cy:e2e:a11y:local:gui
    • npm run cy:e2e:a11y:prod:gui
  • run e2e tests in terminal for each ENV

    • npm run cy:e2e:local:cmd
    • npm run cy:e2e:prod:cmd
  • run e2e and a11y tests in terminal for each ENV

    • npm run cy:e2e:a11y:local:cmd
    • npm run cy:e2e:a11y:prod:cmd
    • npm run cy:e2e:a11y:local:cmd:firefox
    • npm run cy:e2e:a11y:prod:cmd:firefox

CI/CD

More details on the Enterprise Nav CI/CD pipeline can be found here.

Change log (previous versions)

v3.0.15

  • Change stage red menu to default color.

v3.0.14

  • Chi update to 3.0.0 version.
  • Remove extra margin on enterprise-nav-info component.
  • Adding ccmenu option to menuConf to let full component initialization (Feature reported on FSPE-5831).
  • Adding lumen styles.

v3.0.13

  • Fixing a race condition updating the menu option value in the initalization process.

v3.0.12

  • Hightlight menu option on initialize or update methods (Feature reported on FSPP-21679).
  • Remove, using id property, the dynamic options existed in menus.json (FSPE-5719).

v3.0.11

  • Use hover Chi sidenav.

v3.0.10

  • Chi update to 2.4.1 version.

v3.0.9

  • Fixing logout url for mylevel3 domain.

v3.0.8

  • Adding dynamic menu options for production mode.

v3.0.7

  • Adding update method to enterprise-nav-header component to let refresh it without a full reload (Feature reported on FSPE-5415).

v3.0.6

  • Update highlight menu option when URL changes (Bug reported on FSPP-21647).
  • Remove My Profile when there isn't enterprises selected (Feature reported on FSPP-21716).
  • Add notification number on notification icon (Feature reported on FSPE-5390).

v3.0.5

  • { "Content-Type": "application/json" } header removed on API calls. CORS issue caused.

v3.0.4

  • Remove async/await for fetch calls.
  • Remove cache: no-store option from fetch calls.
  • Remove notification component when loginAsEnterprise (Feature reported on FSPP-21572).
  • Set EnterpriseID on enterprises switcher for loginAsEnterprise when enterprises list doesn't come from Rudra (Bug reported on FSPP-21289).

v3.0.3

  • CC Partner should have logout and Centurylink logo URL to home (Bug reported on FSPP-20726).
  • Remove enterprise switcher dropdown for SMB when enterprises list length === 1 (Bug reported on FSPP-20991).
  • Remove enterprise switcher dropdown for login as an enterprise (Feature reported on FSPP-21289).

v3.0.2

  • Logo event fixed for API initialization.
  • Move assets folder to Dimension.
  • Avoid use browser cache on fetch calls (Bug reported on CSPL-7914).

v3.0.1

  • Added trademark label (™) support to left menu. (Feature reported on FSPE-5257).
  • Remove enterprises and user tooltips (Change reported on FSPE-5285).
  • Chi update to 2.2.0 version.
  • Update documentation with recommendations for using the library in frameworks.
  • Remove event for Partners in logo component. (Bug reported on FSPE-5286).
  • Change Help URL depending on customer type. (Bug reported on FSPE-5287).

v3.0.0

  • Created header component enterprise-nav-header for unifying all headers components (Feature reported on FSPE-5136).
  • Remove logout option when customerType is Partner (Feature reported on FSPE-5155).
  • Show logo depending customerType value (Feature reported on FSPE-5045).
  • Fix MyProfile and Impersonation logout URLS (Bug reported on FSPP-20416, FSPP-20469 and FSPP-20577).

v2.1.4

  • Updated URL logout with the latest CC URL logout. For that propused enterprise-nav-profile and enterprise-nav-user were changed. A new paramerer was added to them called env. Values accepted by env: local, stage and prod. Please review Initializating section. (Reported by Siddharth)
  • Fixed z-index issue with tooltips and CC layout. (Bug reported on CSPA-16516 comment)
  • Removed switcher when user has only one item on it. (Bug reported on CSPA-16594)
  • Fixed pointer cursor on second level menu. (Bug reported on CSPA-16593 and CSPA-16795)

v2.1.3

  • Added tooltip on enterprise-nav-notification, enterprise-nav-info, enterprise-nav-user and enterprise-nav-enterprises components. (Bug reported on CSPA-16516)
  • Updated enterprise-nav-user component in order to show the login-id instead of the first-name and last-name concatenation. (Bug reported on CSPA-16516)
  • Updated enterprise-nav-enterprises component size when there are a few enterprises in the list. (Bug reported on CSPA-16516)