Skip to content

Instantly share code, notes, and snippets.

@rodrigomf24
Last active February 19, 2018 21:55
Show Gist options
  • Save rodrigomf24/b0d898b3464b82521ed5992f96d0cceb to your computer and use it in GitHub Desktop.
Save rodrigomf24/b0d898b3464b82521ed5992f96d0cceb to your computer and use it in GitHub Desktop.
level-1-component-documentation

Siemens Portal Navigation Components (SPN)

Overview

The purpose of the components that compose the SPN is to provide the Siemens portal applications a unified navigation whose content can be generated dynamically based on the context selected by the end users.

The SPN consists of three components: Level-1, Level-2, and Level-3. (described bellow). Each component is in charge of providing the ember application its routing context.

Requirements

  • The components should support the different context navigation from all Siemens portal applications.
  • The components should integrate with any ember application.
  • The level-1 component should enforce the context selection from the application user. Each context should have an index route.
  • There should be a service (SPN Service) that maintains the selected contexts from the level-1 and level-2 components.
  • There should be a base service for ember applications that use the Ember DS (Data Store) and Apollo (Graphql). This base service should be used by applications that implement the level-1 component in order to provide default model actions.
  • The level-1 component selected context should drive the content in the level-2 and level-2 components

SIEMENS PORTAL NAVIGATION COMPONENTS ANATOMY

LEVEL-1 COMPONENT

The following is an example of how the level-1 component would be implemented in an ember application. The level-1 component will provide a navigation bar to select the application context.

{{#level-one-navigation}}
    {{#block-slot 'app-name'}}
      {{level-one-navigation/app-name
        appName='Dummy App'
        icon='polymer'
      }}
    {{/block-slot}}
    {{#block-slot 'fleet-navigations' as |fleetNavigation|}}
      {{level-one-navigation/fleet-navigation
        service="customer"
        placeholder="Select Customer"
        onContextSelected=(action fleetNavigation.setContext 'customer')
        selectedContext=fleetNavigation.availableContext.customer
        shouldNotRedirectOnSelected=(not (not fleetNavigation.availableContext.site))
      }}
      {{level-one-navigation/fleet-navigation
        service="site"
        placeholder="Select Site"
        shouldUpdateContent=fleetNavigation.shouldUpdateContent
        disabled=(not fleetNavigation.availableContext.customer)
        onContextSelected=(action fleetNavigation.setContext 'site')
        selectedContext=fleetNavigation.availableContext.site
        shouldNotRedirectOnSelected=(not (not fleetNavigation.availableContext.unit))
      }}
      {{level-one-navigation/fleet-navigation
        service="unit"
        placeholder="Select Unit"
        shouldUpdateContent=fleetNavigation.shouldUpdateContent
        disabled=(not fleetNavigation.availableContext.site)
        selectedContext=fleetNavigation.availableContext.unit
        onContextSelected=(action fleetNavigation.setContext 'unit')
      }}
    {{/block-slot}}
  {{/level-one-navigation}}

component: level-one-navigation

This is the root component for the level-1 navigation.

{{#level-one-navigation as |levelOneNavigation|}}
	....
{{/level-one-navigation}}

It won't receive any attributes since all the logic to keep all the contexts and communication with the level-1 context service will be handled from the component class.


component:level-one-navigation/app-name

This component will render the content for the application name section in the level-1 component.

{{level-one-navigation/app-name
  appName="Health Advisor"
  icon='fa-home'
  onClick=(route-action 'redirect' 'auth.health-advisor')
}}

design is still under review

attribute description
appName application name
icon class to append in the i element that will render an icon next to the application name
onClick ember action triggered when the application name is clicked

component:level-one-navigation/fleet-navigation

This component will render the content and handle the functionality to allow a user to select the application context.

{{level-one-navigation/fleet-navigation
  service='unitService'
  placeholder='Select a unit'
  shouldUpdateContent=levelOneNavigation.shouldUpdateContent
  disabled=(not levelOneNavigation.availableContext.customer)
  onContextSelected=(action levelOneNavigation.setContext 'site')
  selectedContext=levelOneNavigation.availableContext.site
  shouldNotRedirectOnSelected=(not (not levelOneNavigation.availableContext.unit))
}}

design is still under review

attribute description
service name of the service that will handle model actions and provide the context information from the application that is implementing the component
placeholder text to render when there's not an option selected
onContextSelected ember action to call when a context is selected, in the example we call the levelOneNavigation component class setContext action in order to set a unit context in its scope
plantId this is not a required attribute, the attribute will vary based on the given context, it will be used mainly by the service

LEVEL-2 COMPONENT

The following is an example of how the level-2 component would be implemented in an ember application. The level-2 component will provide the sidebar navigation for the SPN.

{{#level-two-navigation as |levelTwoNavigation|}}
  {{#level-two-navigation/parent-node title="Risk Analysis" icon="fa-home" as |parentNode|}}
    {{level-two-navigation/node linkedRoute='health-advisor.risk-analysis.child-one' displayName='child-one' icon='fa-home'}}
    {{level-two-navigation/node linkedRoute='health-advisor.risk-analysis.child-two' displayName='child-two' icon='fa-home'}}
    {{level-two-navigation/node linkedRoute='health-advisor.risk-analysis.child-three' displayName='child-three' icon='fa-home'}}
  {{/level-two-navigation/parent-node}}
{{/level-two-navigation}}

component:level-two-navigation

This component is used to define a menu item that contains child menu items.

{{#level-two-navigation/parent-node
   label="Risk Analysis"
   route="my.application.route"
   icon="fa-home" as |parentNode|}}
	...
{{/level-two-navigation/parent-node}}
attribute description
label menu item label
route route path to be used in a link-to component in order to redirect the user when the menu item is clicked, this is an optional attribute
icon class to append in the i element that will render an icon next to the menu item title

component:level-two-navigation

This component is used to define a menu item.

{{level-two-navigation/node
	label='child-one'
	route='health-advisor.risk-analysis.child-one'
	icon='fa-home'
}}
attribute description
label menu item label
route route path to be used in a link-to component in order to redirect the user when the menu item is clicked
icon class to append in the i element that will render an icon next to the menu item title

LEVEL-3 COMPONENT

The following is an example of how the leve-3 component would be implemented in an ember application. The level-3 component will provide a list of breadcrumbs based on the selected context from the level-2 component for the SPN.

{{level-three-navigation
	breadcrumbClass="my-custom-class"
	breadcrumbWrapperClass="my-customer-wrapper-class"
}}
attribute description
breadcrumbClass class string to append for each breadcrumb
breadcrumbWrapperClass class string to append in the wrapper div for the breadcrumbs

This component generates its content based on the selected context from the level-1 and level-2 components stored in the SPN service.


SPN Service

This service will handle all the core logic to persist the selected contexts in the level-1 and level-2 components. The following is a sample of the service structure.

import Service from '@ember/service';

const BASE_CONTEXT = Ember.Object.create({
	clear(key) {...}
});

export default Service.extend({
  levelOneContexts: Ember.Object.extend(BASE_CONTEXT).create(),
  levelTwoContexts: Ember.Object.extend(BASE_CONTEXT).create(),

  setContext(key, value, context) {
    ...
    this.get(context)[key] = context;
  },

  getContext(key, context) {
    this.get(context)[key];
  },

  removeContext(clearAll=false, context) {
    ...
    this.get(context).clear(key);
  }
});

Base Model Service

This service will provide the required methods and properties for applications that will implement the level one navigation.

import Service from '@ember/service';

export default Service.extend({
  modelName: null,
  options: Ember.A([]),
  selectedOption: null,
  init() {
	this._setList();
  },
  getList() {...},
  _setList() {...},
  _getSelectedOption() {...}
  _setSelectedOption() {...}
});

Example of the fleet-navigation component class

import Component from '@ember/component';

export default Component.extend({
	modelService: Ember.computed('service', function() {
		const service = this.get('service');
		return Ember.getOwner(this).lookup(`service:${service}`);
	}),
	setOptions: () => {
		const service = this.get('modelService');
		if (!servie) {
			throw new Error('Model service is undefined');
		}
		const options = service.getList();
		if (!this._validOptions(options)) {
			throw new Error('Options returned from getList are invalid');
		}
		this.set('options', options);
	}.on('init')
	_validOptions(options = []) {
		if (!Array.isArray(options)) return false;
		return true;
	}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment