1.4.0 • Published 11 months ago

@turbonomic/turbo-ui-manager v1.4.0

Weekly downloads
4
License
Apache-2.0
Repository
-
Last release
11 months ago

A lightweight frontend library with simple API to integrate and embed the © Turbonomic, Inc UI within a parent application UI.


Features

  • Promise-based API.
  • Bi-directional communication between parent and Turbonomic child application.
  • Subscribe for notification about certain events.

Changes/History

Installing

turbo-ui-manager can be installed with npm or yarn.

Yarn

$ yarn add @turbonomic/turbo-ui-manager # Install via Yarn

NPM

$ npm i @turbonomic/turbo-ui-manager --save # Install via NPM

Import

The library is built to UMD format with library namespace TurboUIManager;

ES6 Imports

import {TurboUI} from '@turbonomic/turbo-ui-manager';

HTML script include

<script src="./dist/turbo-ui-manager.js"></script>
...
<script>
  // self executing function here
  window.onload = function() {
    TurboUIManager.TurboUI.createUIComponent(...);
  };
</script>

require

const TurboUIManager = require('turbo-ui-manager');
...
TurboUIManager.TurboUI.createUIComponent(...);

Usage Overview

  1. The Parent Application requests the turbo-ui-manager to create a new instance of the Turbonomic UI at a given URL attached to a given DOM node and returns an object with interface methods and properties.

  2. The turbo-ui-manaager asynchronously establishes a handshake with the Turbonomic UI and notifies the Parent Application when this has completed or fails for any reason.

  3. The Parent Application can subscribe for notification about certain events such as navigation view changes from within the Turbonomic UI instance, Errors, etc.

  4. The Parent Application can command the Turbonomic UI to navigate to internal views using exposed methods on the interface.

  5. The Parent Application can call the exposed destroy method to cleanup and remove the instance if/when it is no longer needed.


Example

Parent

.append-turbonomic-container {
   height: 900px;
   width: 100%;
 }
import { TurboUI } from '@turbonomic/turbo-ui-manager';

const opts: TurboUI.ITurboUIManagerSettings = {
    url: 'http://example.com/turbonomic/app',
    handshakeTimeout: 1000 * 60,
};
const turboUIManager = TurboUI.createUIComponent(document.getElementById('append-turbonomic-container') as HTMLElement, opts);
// suggest to show some loading animation while waiting for onReady or onSessionStart
turboUIManager.on(TurboUIEvent.LOGIN_READY, onReady);
turboUIManager.on(TurboUIEvent.SESSION_START, onSessionStart);
turboUIManager.on(TurboUIEvent.ERROR, onError);

// immediate call to navigate to plans will be queued and processed after handshake establishes connection
turboUIManager.navigateToPlans();

// navigate to a supported view by view-name
turboUIManager.navigateToViewByName(TurboUI.TurboUIManagerView.SEARCH);

API

Methods

TurboUI.createUIComponent

const turboUIManager: TurboUI.ITurboUIManager = TurboUI.createUIComponent(domElement, options);

This is the exposed function to initialize everything and return a reference with the public interface. It returns synchronously while the internal initialization happens asynchronously. It is possible to invoke calls with the returned interface before initialization has completed - such as subscribing for notification of events like the APP_READY event - these will simply be queued and handled afterwards.

NameTypeDescriptionRequiredDefault
domElementHTMLElementPassed in HTML element where the Turbonomic UI instance will be appended to in the DOMtrue
optionsITurboUIManagerSettingsOptions object with some config details for the connection to the Turbonomic UItrue

ITurboUIManager.navigateTo___()

There are a number of ways to command navigation of the UI:

  • Navigate using exposed hooks for specific views

    Command the Turbonomic UI to transition to the given top-level view. Each of these corresponds to a TurboUIManagerView
turboUIManager.navigateToHome();
turboUIManager.navigateToSearch();
turboUIManager.navigateToPlans();
turboUIManager.navigateToReports();
turboUIManager.navigateToPlacement();
turboUIManager.navigateToDashboards();
turboUIManager.navigateToSettings();
  • Navigate to view by view-name argument: ITurboUIManager.navigateToViewByName(viewName: TurboUIManagerView)

    Command the Turbonomic UI to transition to the given top-level view by supplying an enumerated view-name argument
turboUIManager.navigateToViewByName(TurboUIManagerView.PLANS);
turboUIManager.navigateToViewByName(TurboUIManagerView.DASHBOARDS);
  • Navigate to view by url-encoded viewKey: ITurboUIManager.navigateToViewByKey(viewKey: base64-string)

    Command the Turbonomic UI to transition to a hashed-view "viewKey" which is a base64 url encoded view path. Ordinarily the intent is to instantiate the UI during create with a viewKey populated from the url query params in order to handle stateful page refreshes or url sharing/bookmarking.
turboUIManager.navigateToViewByKey(new URLSearchParams(window.location.search).get('viewKey'));
  • Navigate to view by scopeID: ITurboUIManager.navigateToScopeByID(scopeID: uuid-string)

    Command the Turbonomic UI to show scoped dashboard overview for a specific entity identified by its UUID (received from API)
turboUIManager.navigateToScopeByID('1839473243894');
  • Navigate to view by view-options: ITurboUIManager.navigateToViewByOptions(viewOptions: TurboUI.ITurboUIManagerViewSettings)

    Encompasses a combination of all of the above options but follows a hard-coded priority order using the options as follows:
  1. scopeID is checked and followed if it exists
  2. viewKey is checked and followed if it exists
  3. view enumerated view-name is checked and followed if it exists
  4. default fallback is to navigate to the home view if no other condition is met.
turboUIManager.navigateToViewByOptions({
  scopeID: '01234567891011',
  viewKey: 'Iy92aWV3L21haW4vaG9tZS9NYXJrZXQvaHlicmlk',
  view: TurboUIManagerView.HOME,
});

ITurboUIManager.viewNotifications()

turboUIManager.viewNotifications();

Open the notifications slideout.


ITurboUIManager.on()

turboUIManager.on(eventName, callbackFunction);

register a subscriber function for a given TurboUIEvent. It returns a handle function that can be invoked to remove the specific subscriber. Multiple subscribers can be bound to a given event name topic. To remove all subscribers for an event use off

NameTypeDescriptionRequiredDefault
eventNameTurboUIEventOne-of TurboUIEvent values from exported enumtrue
callbackFunctionTurboEventListenera callback function accepting 0-N number of argumentstrue

ITurboUIManager.off()

turboUIManager.off(eventName);

Deregister and removes all subscriber functions associated with specific TurboUIEvent

NameTypeDescriptionRequiredDefault
eventNameTurboUIEventOne-of TurboUIEvent values from exported enum to unsubscribe fromtrue

ITurboUIManager.clearAllSubscribers()

turboUIManager.clearAllSubscribers();

Deregister and removes all subscriber functions for all events. Use this is dismounting/hiding the TurboUI element with the anticipation that you may resume showing it again as this will prevent potential detatched event listeners representing a memory-leak. You will need to re-register the subscribers for handling events upon resuming/showing the TurboUI once again.


ITurboUIManager.hide()

turboUIManager.hide(element);

Hides/minimizes the turbo-ui instance attached to the provided element. Is Promise-based: Tries to Query-select the turbo-ui from the provided element and sets height to '0px' explicitly. IFF the query-selection cannot locate the underlying Turbo-UI, the promise will be rejected. This is useful because it provides a way to be aware that a new call to create and instantiate the UI may be required (or indicates the root DOM element provided no longer contains the Turbo-UI as a child node).

NameTypeDescriptionRequiredDefault
elementHTMLElement_The root HTML DOM element provided to create and mount the turboUI instance initially

ITurboUIManager.show()

turboUIManager.show(element);

Show/maximizes the turbo-ui instance attached to the provided element. Is Promise-based: Tries to Query-select the turbo-ui from the provided element and sets height to 'inherit' explicitly. IFF the query-selection cannot locate the underlying Turbo-UI, the promise will be rejected. This is useful because it indicates either something went wrong with the root DOM node provided not being correct and/or that a new call to initialize/create the Turbo-UI instance is required.

NameTypeDescriptionRequiredDefault
elementHTMLElement_The root HTML DOM element provided to create and mount the turboUI instance initially

ITurboUIManager.getEnabledViews()

const enabledViews: TurboUI.TurboUIManagerView[] = turboUIManager.getEnabledViews();

A method returning the list of enabled TurboUI.TurboUIManagerView items.

Note: this is also notified as an argument to subscribers of the event TurboUIManagerEvent.SESSION_START.

ITurboUIManager.getCurrentView()

const currentView: TurboUI.TurboUIManagerView = turboUIManager.getCurrentView();

Call method returning the currentView property of the underlying Turbonomic UI.

ITurboUIManager.getCurrentViewState()

const currentView: TurboUI.TurboUIManagerView = turboUIManager.getCurrentViewState();

Call method returning an IViewTransition interface object describing the current state of the underlying Turbonomic UI. The object can contain the following properties: viewName, viewUrl and viewKey Note: it is also possible (and probably better) to subscribe for TurboUIManagerEvent.VIEW_CHANGE events with a callback function that will receive this every time the value changes.


ITurboUIManager.isSessionStarted()

const isSessionStarted: boolean = turboUIManager.isSessionStarted();

Check whether an authenticated session has been started within the TurboUI. Note: Typically you will subscribe for TurboUIManagerEvent.SESSION_START event to receive a callback when the session starts. However, if you are re-connecting to an existing TurboUI container, the session may already (still) be active so this enables to check the truthiness of that state.


ITurboUIManager.getUrlFromViewKey(viewKey: base64-encoded-string)

const urlPath: string = turboUIManager.getUrlFromViewKey('Iy92aWV3L21haW4vaG9tZS9NYXJrZXQvaHlicmlk');
console.log(urlPath); // ----> '#/view/main/home/Market/hybrid'

Returns the decoded url-path of the view from the supplied view-key. The viewKey is a url-safe base64 encoded string. This is useful for logging or debugging purposes but is not necessary for navigation purposes normally. This path is also provided along with the top-level TurboUIManagerView name and the encoded viewKey to the TurboUIManagerEvent.VIEW_CHANGE subscribers


Interfaces & Enums

TurboUI.ITurboUIManagerSettings

const options: TurboUI.ITurboUIManagerConnectionSettings = {
  url: 'https://example.com/turbonomic/app',
  handshakeTimeout: 5000,
  scopeID?: string|null,
  viewKey?: string|null,
  view?: TurboUIManagerView,
}

This is the configuration object for connecting with the underlying Turbonomic UI instance. It is required to provide a fully-qualified URL to the instance.

Note the URL for the Turbonomic UI must be on the same domain as the parent application, else the handshake will fail.

NameTypeDescriptionRequiredDefault
urlstringFully Qualified URL pointing to the root of the Turbonomic instance to be embeddedtrue
handshakeTimeoutnumberMaximum time in milliseconds to wait for the handshake to be established with child Turbonomic UI instancefalse10000
scopeIDstring (uuid)(priority 1) Initialize the Turbo-UI connection to display the scoped dashboard overview for a specific entity identify by its uuid (as scopeID)falseHOME
viewKeystring (base64)(priority 2) Initialize the Turbo-UI connection to display the specified view identified by the base-64 url encoded hashfalseHOME
viewTurboUIManagerView(priority 3) A specific Top-Level TurboUI View to display upon initializing the connectionfalseHOME

TurboUI.TurboUIManagerView

Enum of top-level views within the Turbonomic UI. These ordinarily would exist in the Left-hand Navbar. Any number of these can be restricted for various reasons.

Values
HOME ,SEARCH ,PLANS ,PLACEMENT ,DASHBOARDS, REPORTS ,SETTINGS ,NOTIFICATIONS

TurboUI.TurboUIManagerEvent

turboUIManager.on(TurboUIEvent.ERROR, onError);
turboUIManager.on(TurboUIEvent.LOGIN_READY, onReady);
turboUIManager.on(TurboUIEvent.VIEW_CHANGE, onViewChange);
turboUIManager.on(TurboUIEvent.SESSION_START, onSessionStart);

private onReady = () => { // Turbonomic UI Login Form is loaded. May want to display some loading animation graphic until this is called. // IF configured for SSO integration, this event will not be emitted };

private onSessionStart = (viewTransition: TurboUI.IViewTransition) => { // User session is logged-in and started; IViewTransition viewState information is returned // If using SSO for authentication, this is probably the first event that will be received to indicate the UI is ready // to be displayed. Recommend displaying some loading animation graphic until this is called. };

private onError = (e: TurboUI.ITurboUIManagerError) => { // Some error has occurred. Read from property 'type' which is one-of TurboUI.TurboUIManagerErrorType in order to // handle different types of errors accordingly (see error-types below) };

#### onViewChange(TurboUI.TurboUIManagerEvent.

```typescript
TurboUI.on(TurboUI.VIEW_CHANGE, onViewChange);

private onViewChange = (viewTransition: TurboUI.IViewTransition) => {
  // Turbonomic UI View has changed (e.g. user has navigated from within the child application directly)
  const { viewName, viewKey, viewUrl } = viewTransition;
  console.log(viewName);    // ----> 'HOME'
  console.log(viewKey); // ----> 'Iy92aWV3L21haW4vaG9tZS9NYXJrZXQvaHlicmlk'
  console.log(viewUrl); // ----> '#/view/main/home/Market/hybrid'
};

Some notes about workflows with VIEW_CHANGE transitions:

  1. Use-Case: Instantiate a new instance of IWO UI to a given View-State. (The view transition info will come through the SESSION_START event in this case NOT the VIEW_CHANGE for the first transition)
  • View: e.g. "HOME"
  • ScopeID: Directly link to a scoped overview
  • ViewKey: browser refresh, bookmark, or link-sharing

  1. Navigating back to existing Turbonomic UI instance from an external/parent UI view:
  • User went to Turbonomic View e.g. "HOME", then to some External/Parent View (non Turbonomic), and back to the SAME Turbonomic view as before e.g. "HOME" again.
  • Same as above but the second time going into Turbonomic they went to a different view (e.g. (Turbonomic) HOME -> (parent app) -> (Turbonomic) Plans ).

A subscriber for View Transition events will receive an object conforming to IViewTransition interface. This object received identifies:

NameTypeDescriptionAlways-IncludedDefault
viewTurboUI.TurboUIManagerViewTop-Level enumerated TurboUI Manager View (useful to indicate corresponding navigation/breadcrumbstrue
viewKeystringBase64, URL-safe encoding of the underlying TurboUI embedded view. Useful to push onto url-query string params to track for stateful reloads and url sharing/bookmarkingtrue
viewUrlstringNon-Encoded (not query-param safe) url path segment of the underlying TurboUI embedded view. Useful for human-readable logging and debuggingtrue

TurboUI.ITurboUIManagerError

TurboUI.TurboUIManagerErrorType

turboUIManager.on(TurboUIEvent.ERROR, this.onError);


private onError = (error: TurboUI.TurboUIManagerError) => {
  const errorType: TurboUI.TurboUIManagerErrorType = error.type;
  switch(errorType) {
    case TurboUIManagerErrorType.HANDSHAKE_FAILURE:
      console.warn('Failed to establish handshake with TurboUI within 10000 ms. time limit');
    case TurboUIManagerErrorType.INITIALIZATION_ERROR:
      console.warn('Some error occurred within the Turbonomic UI instance while initializing as embedded application');
    case TurboUIManagerErrorType.RESTRICTED_VIEW:
      console.warn(`View Transition Failed. ${view} is currently restricted`);
    default:
      console.error('Some unexpected error occurred');
  }
}

A subscriber for Error events will receive an object conforming to ITurboUIManagerError. Within this object is a type field which is one of ITurboUIManagerErrorType which allows parent code to handle different error cases.

NameTypeDescriptionRequiredDefault
urlstringFully Qualified URL pointing to the root of the Turbonomic instance to be embeddedtrue
handshakeTimeoutnumberMaximum time in milliseconds to wait for the handshake to be established with child Turbonomic UI instancefalse10000

License

Apache-2.0

1.4.0

11 months ago

1.3.0

3 years ago

1.2.0

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.1.0

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago