npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@softheon/armature

v17.22.8

Published

This document is also available on [Softheon Wiki](https://wiki.softheon.com/Wiki/article/3861)

Downloads

1,299

Readme

Getting started

This document is also available on Softheon Wiki

Step 1 - Create an empty project with the correct dependencies

To create a project targeting angular 17, in the directory you wish to create your project in, run npm i @angular/cli@17, once the command completes, run ng new your-project-name. This will create an angular project with the latest stable version of angular 17

It is preferred to select routing as yes and style sheet to SCSS

Then install the peer dependencies required by the Armature, they can be found below for easy reference

*"@angular/animations": "^17.1.2", *"@angular/cdk": "^17.1.2", *"@angular/common": "^17.1.2", *"@angular/compiler": "^17.1.2", *"@angular/core": "^17.1.2", *"@angular/flex-layout": "^15.0.0-beta.42", *"@angular/forms": "^17.1.2", *"@angular/material": "^17.1.2", *"@angular/platform-browser": "^17.1.2", *"@angular/platform-browser-dynamic": "^17.1.2", *"@angular/router": "^17.1.2", *"@ngx-translate/core": "^15.0.0", *"@ngx-translate/http-loader": "^8.0.0", *"angular-oauth2-oidc": "~15.0.1", *"angular-oauth2-oidc-jwks": "^15.0.1", *"rxjs": "~7.8.0", *"moment": "^2.29.4", *"ag-grid-angular": "^31.2.1", *"ag-grid-community": "~31.2.1"

After these have been installed, run the following to install armature npm i @softheon/armature

Include the HttpClientModule in the imports of your app.module.ts.

Step 2 -Armature Set Up

2.1 Configurations

Create the following directory(ies) src/app/configs/models.

inside the src/app/configs/models directory create a config.ts file.

Set the contents of the file to the following

import { BaseConfig, HeaderConfig, NavigationConfig, OidcAuthSettings, ThemePaletteModel } from '@softheon/armature';

/** The configurations - new properties can be added here to add more application specific configurations */
export class Config implements BaseConfig {
  /** the odic settings */
  public oAuthSettings: OidcAuthSettings;

  /** The header configurations */
  public header: HeaderConfig;

  /** The theme palette */
  public theme: ThemePaletteModel;

  /** The navigation config */
  public navigation: NavigationConfig;
}

cd into the src/app/configs directory and run the following command ng g service config

In the generated config.service.ts extend ConfigService class with BaseConfig<Config>. The end result should show as below


import { Injectable } from '@angular/core';
import { BaseConfigService } from '@softheon/armature';
import { Config } from './models/config';

/**
 * The Config service is used to get the applications configurations
 */
@Injectable()
export class ConfigService extends BaseConfigService<Config> {
}

In the src/assets directory create a baseline folder and a configurations folder.

In the src/assets/baseline folder create an appsettings.json file. This will be where you configure your default configurations for your applications. For now it can be an empty object as seen below

{}

In the src/assets/configurations folder create an appsettings.json file, a en.json file and a theme.json file. These will be the overrides for your languages, theme and configurations. For now it can be an empty as seen below

{}

Finally in your app.module.ts include the following line in your imports array


ArmatureModule.forRoot(ConfigService)

Make sure your ConfigService is added to the providers array in app.module.ts

2.3 Start-up service

cd into the src/app directory and run the following command ng g module core. This will create a core module for later user.

Inside the src/app/core directory create a start-up folder.

cd into src/app/core/start-up and run ng g service start-up.

In the generated start-up.service.ts implement the AbstractStartupService and create a load function that returns Promise.resolve(true). The end result can be found below

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { AbstractStartupService } from '@softheon/armature';

/** The start up service */
@Injectable({
  providedIn: 'root'
})
export class StartupService implements AbstractStartupService {
    constructor(){}

    public async load(): Promise<any> {
        return Promise.resolve(true);
    }
}

The body of the load function is where you would run your own custom start up logic if any is required.

In your app.module.ts add the following to your array of providers { provide: AbstractStartupService, useClass: StartupService }.

Note - The StartUpService should not need to be included in your providers array in app.module.ts.

2.4 Styles

In your src/style.scss file, import the following scss file at the top

@import "../node_modules/@softheon/armature/assets/styles/sof-styles.scss";

2.5 Setting the app-template selector

In your app.component.html, use the following selector to add a full header, nav and footer page layout template

<sof-ar-app-template>
</sof-ar-app-template>

Optional Add footer content using the following ng-content selector

<sof-ar-app-template>
    <ng-container sof-ar-footer-content>
        Footer Content here
    </ng-container>
</sof-ar-app-template>

Optional Add additional content between the header and nav using the following selector

<sof-ar-app-template>
    <ng-container sof-ar-template-content>
        Content here
    </ng-container>
</sof-ar-app-template>

2.6 NGX Translate

Initialize the translate module by doing the following in app.module.ts imports and including the factory towards the top of the file outside of the ngModule decorator and make sure an src/assets/i18n/en.json file exists:


/**
 * Creates the translate HTTP loader
 * This is necessary for AoT loading
 * @param http the http
 */
export function createTranslateLoader(http: HttpClient): TranslateHttpLoader {
    return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

...

 TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: (createTranslateLoader),
                deps: [HttpClient]
            }

2.7 Application log in

In your app.module.ts imports, set up the oauth module by doing the following

 OAuthModule.forRoot({
            resourceServer: {
                allowedUrls: [],
                sendAccessToken: true
            }
        }),

Then add the following object to the root level of your src/assets/baseline/appsettings.json file

 "oAuthSettings": {
        "clientId": "your-client-id",
        "issuer": "your-issuer",
        "loginUrl": "your-login-url",
        "scope": "your-scopes",
        "logInText": "SIGN IN",
        "logOutText": "SIGN OUT",
        "redirectUri": "http://localhost:4200/",
        "requireLoginOnStartup": false
    }

if you wish to use implicit flow add the following entry to the object above "responseType": "id_token token"

Note -- The logInText and logOutText support translate keys or plain text

Note -- If your application does not offer sign in, leave the values empty and set the header.settings.displayAuthInfo to false in your baseline appsettings file.

Note -- If your application requires sign in immediately, set requireLoginOnStartup to true

2.8 Turn off User Entity Service

In your app.module.ts include the following in your providers array { provide: USER_ENTITY_SERVICE_CONFIG, useValue: { getUserOnInit: false }},. This will disable the user entity look up, and can be turned on if needed for user information outside of your OIDC provider.

Theming

Follow the class definition for the theme object to supply a full material palette to the application

The navigation theme can be set by the navigation.theme object in the appsettings.json. The navigation section bellow provides additional information about this object.

Navigation Nodes

Populating the navigation.nodes property as described bellow in either your extended config service or the BaseConfigService will allow you to customize the navigation nodes that appear in the side-nav. The same classes are used as described in the navigation section below.

Additional Header Content

If you wish to provide additional header content, the following ng-content selector can be used.

<sof-ar-app-template>
   <ng-container sof-ar-header--right>
     This content will show up to the left of the pre-defined header buttons
    </ng-container>
    <ng-container sof-ar-footer-content>
        Footer Content here
    </ng-container>
</sof-ar-app-template>

Banner service

If you want notification banner you may want to use to banner service and use show message method on specific action that you want.

this.bannerService.showMessage('Example-Banner-Message');

Step 3 - Shared Component & Styling

Check out the Armature Documentation site for more information on how to use our shared components & styling.

Theme Module

In order to use the theme module, in your app.module, add the ThemeModule to the imports.

Its recommended to set the theme in an app initializer, though it can be done from other locations.

  1. Inject the ThemeService into your desired class/component/service etc
  2. Get/create a ThemePaletteModel, an example json can be found below.
{
    "primaryColor": {
        "fifty": "#E6E5F0",
        "oneHundred": "#C2BFDA",
        "twoHundred": "#9994C1",
        "threeHundred": "#7069A8",
        "fourHundred": "#514895",
        "fiveHundred": "#322882",
        "sixHundred": "#2D247A",
        "sevenHundred": "#261E6F",
        "eightHundred": "#1F1865",
        "nineHundred": "#130F52",
        "a100": "#908AFF",
        "a200": "#5F57FF",
        "a300": "#5F57FF",
        "a400": "#5F57FF",
        "a500": "#2F24FF",
        "a700": "#160AFF"
    },
    "primaryContrast": {
        "fifty": "#000000",
        "oneHundred": "#000000",
        "twoHundred": "#000000",
        "threeHundred": "#000000",
        "fourHundred": "#ffffff",
        "fiveHundred": "#ffffff",
        "sixHundred": "#ffffff",
        "sevenHundred": "#ffffff",
        "eightHundred": "#ffffff",
        "nineHundred": "#ffffff",
        "a100": "#000000",
        "a200": "#000000",
        "a300": "#000000",
        "a400": "#000000",
        "a500": "#000000",
        "a700": "#000000"
    }
}
  1. Then call ThemeService.initPalette providing the ThemePaletteModel as the argument. A snippet can be found below
export class MyClass {
  constructor(
    private readonly themeService: ThemeService
  )
  {
    const model: ThemePaletteModel = {
      // your theme here, this can be loaded from http call if needed
    };
    this.themeService.initPalette(model);
  }
}

Colors with opacity

The theme palettes all offer a rgb value through css variables, the following naming convention is used --{{palette}}-color-{{partsNumber}}-parts-rgb. So in order to get an opacity of .2 on the primary color, 500 parts the following css can be used

rgba(var(--primary-color-500-parts-rgb), .2)

Armature Navigation

<sof-ar-navigation></sof-ar-navigation> is a mobile-responsive navigation component. It structures the application view content to the right and the navigation to the left.

Navigation Setup Overview

  1. npm install
  2. Import the armature Module into your app.module.ts 'imports'.
  3. Add Armature component sof-ar-navigation to HTML component, note that the component has 3 ng-content parts
    1. sof-ar-nav-header place content that you'd like to appear within the navigation above the nodes
    2. sof-ar-nav-footer place content that you'd like to appear within the navigation underneath the nodes
    3. sof-ar-nav-content this is where your primary content (i.e. router-outlet) goes
  4. Configure the Armature Component Navigation Data [navigationData]
    1. the navigation data consists of an array of NavNode's
      1. text - the parent node text (note: this can be a translate key or string)
      2. fontAwesomeIcon (optional) - the font awesome class icon
      3. route (optional) - the route
      4. subNodes (optional) - the parent node sub-nodes
        1. text - the sub-node text (note: supports translate key or string)
        2. route - the sub-node route
  5. Configure Armature component settings in the TS
    1. [settings] - these are the required settings to configure your navigation
      1. fontAwesomeMenuIcon the Header toggle navigation icon when navigation is open
      2. fontAwesomeMenuIconClosed the Header toggle navigation icon when navigation is closed
      3. mainMenuText the main menu text that appears in the mobile SubNav
      4. headerHeight the header height
      5. menuButtonSRText the menu button screen reader text
      6. allowNavToggle whether to allow navigation toggle
    2. [advancedSettings]- these settings are optional, and only needed for advanced height/offset customizations. These will override headerHeight in [settings].
      1. topGapDesktop & topGapMobile- the navigation top gap
      2. marginTopDesktop/marginTopMobile- the navigation margin top
    3. [themeSettings] - this will colorize your navigation. Pass each parameter with a string color value. i.e. #3d3d3d or transparent or rgba(61, 61, 61, .20)
      1. contentBgColor the content background color
      2. fontColor the Nav font color
      3. bgGradientColor1 the Nav background gradient color 1
      4. bgGradientColor2 the Nav background gradient color 2
      5. borderRightColor the Nav border-right color
      6. listBorderColor the Nav border color between each list item
      7. highlightGradient1 the Nav highlight gradient color 1, Only setting this will create a solid navigation highlight.
      8. highlightGradient2 the Nav highlight gradient color 2
      9. subHighlightBorderColor the SubNav highlight border color
      10. subHighlightBgColor the SubNav highlight bg color
  6. Configure the CSS customizations in your styles.css for the menu button on mobile
  7. Note helper class, 'visible-mobile' which will hide html on desktop by applying display: none;.

Navigation Module Setup

Module.ts:

import { ArmatureModule } from '@softheon/armature';

...

@NgModule({
    imports: [
        ...
        ArmatureModule
        ...
    ],
    ...
})

Navigation Typescript Configurations

Import the necessary models from the npm package and configure the navigation component inputs in your Angular typescript component. We recommend you do this ngOnInit().

There will be 3 inputs to configure the navigation. Configure the Armature Component Navigation Data [navigationData], its settings [settings], and its color theme [themeSettings].

NavigationData

TIP: The navigation data text supports both ngx-translate keys and string literals.

The navigation data consists of an array of NavNodes:

  1. text - the parent node text (note: this can be a translate key or string)
  2. fontAwesomeIcon (optional) - the font awesome class icon
  3. route (optional) - the route
  4. stepContent (optional) - only used in stepper mode, provide information about the current step
  5. altLocation (optional) - shows the navigation node at the bottom
  6. expanded (optional) - whether or not if the navigation is expanded by default (only works if there are subnodes)
  7. subNodes (optional) - the parent node sub-nodes
    1. text - the sub-node text (note: supports translate key or string)
    2. route - the sub-node route
    3. stepContent (optional) - only used in stepper mode, provide information about the current step

Settings

The [settings] required input receives a NavigationSettings object in order to configure your navigation.

  1. fontAwesomeMenuIcon the Header toggle navigation icon when navigation is open
  2. fontAwesomeMenuIconClosed the Header toggle navigation icon when navigation is closed
  3. mainMenuText the main menu text that appears in the mobile SubNav
  4. headerHeight the header height number
  5. menuButtonSRText the menu button screen reader text
  6. menuStyle (optional - 'static' | 'stepper' | 'progress') static by default, changes the menu between static, stepper and progress
  7. hideNavigation true if hiding the navigation container, defaulted to false
  8. displayNumberstrue if the navigaiton sections should be numbered, defaulted to true
  9. progressSectionCompleteIcon the Progress menu completed section icon string
  10. progressSectionFutureIcon the Progress menu future section icon string
  11. progressSectionCurrentIcon the Progress menu current section icon string
  12. progressMenuCompleteIcon the Progress menu item complete icon string
  13. showProgressBar true if the Progress menu should also display the progress bar, defaulted to true
  14. sideNavWidthDesktop the side navigation width for desktop, defaulted to 500
  15. sideNavWidthMobile the side navigation width for mobile, defaulted to 500
  16. progressMenuWidth the progress menu dropdown width, defaulted to 280
  17. overrideNavigation overrides the navigation and enables all routes (to be used for testing) defaulted to false
  18. maxContentWidthDesktop the maximum width for the desktop content, defaulted to 100%
  19. maxContentWidthMobile the maximum width for the mobile content, defaulted to 100%
  20. useCustomMobileFooter true if the navigation is using a custom mobile footer. This hides the language options and signout buttons for mobile nav
  21. customUserName the custom user name to be displayed in the mobile side nav
  22. toggleProgressNavParentIndex the custom parent node index to be set when menu style is toggled to progress navigation
  23. toggleProgressNavChildIndex the custom child node index to be set when menu style is toggled to progress navigation
  24. allowNavToggle whether to allow navigation toggle

Theme Settings

The [themeSettings] - required input receives a ThemeSettings object in order to colorize your navigation.

TIP: Any CSS color string value is accepted i.e. #3d3d3d or transparent or rgba(61, 61, 61, .20)

  1. contentBgColor the content background color
  2. fontColor the Nav font color
  3. bgGradientColor1 the Nav background gradient color 1
  4. bgGradientColor2 the Nav background gradient color 2
  5. borderRightColor the Nav border-right color
  6. listBorderColor the Nav border color between each list item
  7. highlightGradient1 the Nav highlight gradient color 1
  8. highlightGradient2 the Nav highlight gradient color 2
  9. subHighlightBorderColor the SubNav highlight border color
  10. subHighlightBgColor the SubNav highlight bg color

Example

  /** On Init */
  public ngOnInit(): void {

    // the navigation theme settings
    this.exampleTheme = {
      bgGradientColor1: '#006494',
      bgGradientColor2: '#00838F',
      borderRightColor: 'transparent',
      contentBgColor: '#ececec',
      fontColor: '#fff',
      highlightGradient1: 'rgba(130,177,255,.5)',
      highlightGradient2: 'rgba(255,255,255, 0)',
      listBorderColor: '#CFD8DC',
      subHighlightBgColor: 'rgba(255,255,255, .20)',
      subHighlightBorderColor: '#00ACC1'
    };

    // the navigation settings
    this.exampleSettings = {
      fontAwesomeMenuIcon: 'fas fa-angle-double-left',
      fontAwesomeMenuIconClosed: 'fas fa-angle-double-right',
      mainMenuText: 'MAIN MENU',
      headerHeight: 60,
      menuButtonSRText: 'Menu Button',
      allowNagToggle: true
    };

    // the navigation
    this.exampleNav = [
      {
        text: 'demo.nav_1',
        fontAwesomeIcon: 'fad fa-home',
        route: '/overview',
        subNodes: []
      },
      {
        text: 'demo.nav_2',
        fontAwesomeIcon: 'fad fa-file-alt',
        route: '/document',
        subNodes: [
          {
            text: 'demo.nav_2a',
            route: 'documents/invoice'
          },
          {
            text: 'demo.nav_2b',
            route: '/notice'
          },
          {
            text: 'demo.nav_2c',
            route: '/tax'
          }
        ]
      },
      {
        text: 'PAYMENTS',
        fontAwesomeIcon: 'fad fa-dollar-sign',
        subNodes: [
          {
            text: 'Make a Payment',
            route: '/payment'
          },
          {
            text: 'Autopay',
            route: '/autopay'
          },
          {
            text: 'Scheduled Payments',
            route: '/scheduled'
          },
          {
            text: 'Payment History',
            route: '/history'
          },
          {
            text: 'My Payment Methods',
            route: '/payment-methods'
          }
        ]
      },
      {
        text: 'SERVICE REQUEST',
        fontAwesomeIcon: 'fad fa-hands-helping',
        route: '/service-requests',
        subNodes: []
      },
      {
        text: 'PAPERLESS SETTINGS',
        fontAwesomeIcon: 'fad fa-leaf-heart',
        route: '/paperless',
        subNodes: []
      },
      {
        text: 'FAQs',
        fontAwesomeIcon: 'fad fa-question',
        route: '/faqs',
        subNodes: []
      }
    ];
  }

Navigation HTML Setup

Add component to your app.component.html file. The component has 3 ng-content parts:

  1. sof-ar-nav-header place content that you'd like to appear within the navigation above the nodes
  2. sof-ar-nav-footer place content that you'd like to appear within the navigation underneath the nodes
  3. sof-ar-nav-content this is where your primary content (i.e. router-outlet) goes

TIP Be sure to place the sof-ar-navigation component immediately after (under) your toolbar / header.

Example

<sof-ar-navigation [navigationData]="exampleNav" [settings]="exampleSettings">
  <!-- Navigation Header -->
  <div sof-ar-nav-header>
    <p style="margin: 20px 0; text-align: center">
      [ This Content Appears in the Header ]
    </p>
  </div>
  <!-- Navigation Footer -->
  <div sof-ar-nav-footer class="visible-mobile">
    <hr/>
    <div class="mat-nav-list mat-list-base custom-nav">
      <a class="nav-item mat-list-item">
        <div class="mat-list-item-content">
          <span class="icon-styling"><i class="fad fa-globe"></i></span>
          {{'demo.nav_g' | translate}}
        </div>
      </a>
      <a class="nav-item mat-list-item">
          <div class="mat-list-item-content">
            <span class="icon-styling"><i class="fad fa-language"></i></span>
            {{'demo.nav_h' | translate}}
          </div>
        </a>
    </div>
  </div>
  <!-- Content Goes Here -->
  <div sof-ar-nav-content>
    <router-outlet></router-outlet>
  </div>
</sof-ar-navigation>

Additional Styling Customizations

Sticky Header

To make the header sticky on mobile, add the class 'sof-ar-fixed-nav' to your header component. i.e.

<div class="toolbar header-menu-padding sof-ar-fixed-nav" role="banner">

Mobile Menu Icon

You will have to create a mobile only class for your document that adds the appropriate padding to your header on mobile.

i.e.:

@media only screen and (max-width: 959px) {
  .header-menu-padding {
    padding-left: 40px; // set this value depending on the size of your button icon
  }
}

Mobile Menu Icon customizations

Custom styling for the icon depending on the header height:

.sof-ar-nav-menu-btn {
  width: 60px !important;
  height: 60px !important;
  line-height: 60px !important;
}

.sof-ar-nav-menu-icon {
  font-size: 30px;
  line-height: 30px;
}

.sof-ar-nav-menu-btn .mat-icon {
  font-size: 60px;
  width: 60px;
  height: 60px;
  line-height: 60px;
}

Additional Tips

Add the class custom-nav to the mat-nav-list div to hide the lines between each list item.

i.e.

<div sof-ar-nav-footer class="visible-mobile">
  <hr/>
  <div class="mat-nav-list mat-list-base custom-nav">
    <a class="nav-item mat-list-item">
      <div class="mat-list-item-content">
        <span class="icon-styling"><i class="fad fa-globe"></i></span>
        English
      </div>
    </a>
    <a class="nav-item mat-list-item">
        <div class="mat-list-item-content">
          <span class="icon-styling"><i class="fad fa-language"></i></span>
          Language Assistance
        </div>
      </a>
  </div>
</div>

Armature Header

<sof-ar-header></sof-ar-header> is a mobile-responsive header component.

Header Setup Overview

  1. npm install
  2. Import the armature Module into your app.module.ts 'imports'.
  3. Add Armature component sof-ar-header to HTML component, note that the component has 5 ng-content parts
    1. sof-ar-header-left this is for custom content in the left portion of the header
    2. sof-ar-header-center this is for custom content in the center portion of the header
    3. sof-ar-header-right this is for custom content in the right portion of the header
    4. sof-ar-header-menu this is for the dropdown menu
    5. sof-ar-super-header this is for the header at the very top of the page
  4. Configure Armature component settings in the TS
    1. [settings] - these are the required settings to configure your header
      1. armatureNavigation if the header is being paired with the armature navigation. this will auto create the room for the navigation icon
      2. displayLogo whether or not to display the logo, default false
      3. logoUrl the logo url
      4. logoAltText the logo alt text
      5. displayLogoText whether or not to show the logo text, default false
      6. headerLogoText the header logo text
      7. displayDropDownMenu whether or not to show the built in drop down menu, default false
      8. dropDownMenuSRText the drop down menu screen reader text
      9. dropDownAriaText the drop down menu aria text
      10. headerDropDownIcon the header menu drop down icon
      11. displaySuperHeader whether or not to show the super header
      12. createSpaceForNavToggle whether to create space for the nav toggle button, regardless of screen size
    2. [themeSettings] - this will colorize your header.
      1. headerColor the header color - uses a neutral background color based on the current theme (light or dark). can be primary, secondary, or warn
      2. iconColor using color string icon color
      3. headerDropShadow whether or not to add a drop shadow to the header
      4. superHeaderColor the super header color
      5. borderBottomColor The color of the bottom border for the header
      6. borderBottomSize The size of teh bottom border for the header

Header Module Setup

Module.ts:

import { ArmatureModule } from '@softheon/armature';

...

@NgModule({
    imports: [
        ...
        ArmatureModule
        ...
    ],
    ...
})

Header Typescript Component Setup

Import the necessary models from the npm package and configure the navigation component inputs in your Angular typescript component. We recommend you do this ngOnInit().

There will be 2 inputs to configure the header. Configure the Armature Component Header settings [settings], and its color theme [themeSettings].

The header component has the option to display a logo, logo text, or both. These are configurable with the displayLogo and displayLogoText properties in the HeaderSettings object.

These settings will display the header with a logo.

  /** Armature Header - settings */
  public exampleHeaderSettings: HeaderSettings = {
    armatureNavigation: true,
    createSpaceForNavToggle: true,
    displayLogo: true,
    logoUrl: './assets/logos/logo.svg',
    logoAltText: 'the example portal header logo',
    displayLogoText: false,
    displayDropDownMenu: true,
    dropDownAriaText: 'the header drop down menu button icon',
    dropDownMenuSRText: 'the header account button drop down options'
  };

  /** Armature Header - theme settings */
  public exampleHeaderThemeSettings: HeaderThemeSettings = {
    headerColor: '',
    headerDropShadow: true,
    iconColor: '#4DB6AC'
  };

Header HTML Setup

Add component to your app.component.html file. The component has 4 ng-content parts:

  1. sof-ar-header-left this is for custom content in the left portion of the header
  2. sof-ar-header-center this is for custom content in the center portion of the header
  3. sof-ar-header-right this is for custom content in the right portion of the header
  4. sof-ar-header-menu this is for the dropdown menu
  5. sof-ar-super-header this is for the header at the very top of the page

TIP Be sure to place the sof-ar-header component immediately before (above) your sof-ar-navigation component.

<sof-ar-header [settings]="exampleHeaderSettings" [themeSettings]="exampleHeaderThemeSettings">
  <div sof-ar-super-header></div>
  <div sof-ar-header-left></div>
  <div sof-ar-header-right class="d-inline">
    <button mat-button [matMenuTriggerFor]="exampleMenu2" aria-label="Example icon-button with a menu">
      <span class="sof-ar-header-icon primary-color">
        <i class="fad fa-globe"></i>
      </span>
      <span class="sof-ar-header-button-text">{{'demo.header_english' | translate}}</span>
      <i class="fas fa-caret-down"></i>
    </button>
    <mat-menu #exampleMenu2="matMenu" class="sof-ar-mat-menu">
      <button mat-menu-item class="sof-ar-header-menu-list">
        <span>{{'demo.header_english' | translate}}</span>
        <span class="m-l-auto secondary-color"><i class="fas fa-check"></i></span>
      </button>
      <button mat-menu-item class="sof-ar-header-menu-list">
        <span>{{'demo.header_spanish' | translate}}</span>
      </button>
    </mat-menu>
    <button mat-icon-button [matMenuTriggerFor]="exampleMenu" aria-label="Example icon-button with a menu">
      <span class="sof-ar-header-icon primary-color">
        <i class="fad fa-bell"></i>
      </span>
      <span class="sr-only">{{'demo.header_notifications' | translate}}</span>
    </button>
    <mat-menu #exampleMenu="matMenu" class="sof-ar-mat-menu">
      <button mat-menu-item class="sof-ar-header-menu-list">
        <span>{{'demo.header_notification_1' | translate}}</span>
      </button>
      <button mat-menu-item class="sof-ar-header-menu-list">
        <span>{{'demo.header_notification_2' | translate}}</span>
      </button>
    </mat-menu>
  </div>
  <ng-container sof-ar-header-menu>
    <a href="https://www.softheon.com/" mat-menu-item class="sof-ar-header-menu-list sof-ar-header-menu-border">
      <span>{{'demo.header_account' | translate}}</span>
    </a>
    <button mat-menu-item class="sof-ar-header-menu-list">
      <span>{{'demo.header_logout' | translate}}</span>
    </button>
  </ng-container>
</sof-ar-header>

<sof-ar-navigation>
  ...
</sof-ar-navigation>

Header Styling Tips

Menu List Borders

Use the class sof-ar-header-menu-border to add a border to your menu list items.

Example:

  <a href="https://www.softheon.com/" mat-menu-item class="sof-ar-header-menu-list sof-ar-header-menu-border">
    <span>My Account</span>
  </a>

Icon & Font Theming

ng-content icon and font themeing will be handled outside of the component library.

Example:

.primary-color {
  color: #4DB6AC;
}

.sof-ar-header-button-text, .sof-ar-header-menu-list {
  font-family: 'Poppins', sans-serif !important;
}
  <div sof-ar-header-right class="d-inline">
    <button mat-icon-button [matMenuTriggerFor]="exampleMenu" aria-label="Example icon-button with a menu">
      <span class="sof-ar-header-icon primary-color">
        <i class="fad fa-bell"></i>
      </span>
      <span class="sr-only">Notifications</span>
    </button>
    <mat-menu #exampleMenu="matMenu">
      <button mat-menu-item class="sof-ar-header-menu-list">
        <span>Notification 1</span>
      </button>
      <button mat-menu-item class="sof-ar-header-menu-list">
        <span>Notification 2</span>
      </button>
    </mat-menu>
  </div>

Armature Footer Component

<sof-ar-footer></sof-ar-footer> is a mobile-responsive footer shell component that is populated via ng-conent.

Footer Setup Overview

  1. npm install
  2. Import the armature Module into your app.module.ts 'imports'
  3. There are no typescript models associated with this component, skip this step
  4. Add Armature component sof-ar-footer to HTML component, note that the component has 1 ng-content part
    1. sof-ar-footer-content this is for custom content in the footer
  5. Add footer content buttons to ng-content placeholder & stylize

Footer Module Setup

Module.ts:

import { ArmatureModule } from '@softheon/armature';

...

@NgModule({
    imports: [
        ...
        ArmatureModule
        ...
    ],
    ...
})

Footer Typescript Component Setup

N/A. There is no Typescript models associated with this component.

Footer HTML Setup

Add component to your app.component.html file.

Because the footer is a shell component, additional icon and font themeing will be handled outside of the component library. That said, mat-buttons have pre-built stylings from the armature component library.

The component has 1 ng-content part:

  1. sof-ar-footer-content this is for custom content in the footer

TIP Be sure to place the sof-ar-footer inside the sof-ar-nav-content ng-content in the sof-ar-navigation component and after the router outlet.

Additional Footer Sections

There are two pre footer sections that are optional and disabled by default. These both use ng content with their own selectors. Follow the steps below to use the pre footer sections

  1. Create a FooterConfig and provide it as an input to the Armature footer component
  public footerConfig = new FooterConfig()

  footerConfig.showPreContent1 = true;
  footerConfig.showPreContent2 = true;
  1. Include an ng container with the following selectors in your html: sof-ar-footer-pre-content-1 and sof-ar-footer-pre-content-2. The final html is shown below
 <sof-ar-footer [footerConfig]="footerConfig">
    <ng-container sof-ar-footer-pre-content-1>
      content for section 1
    </ng-container>
    <ng-container sof-ar-footer-pre-content-2>
      content for section 2
    </ng-container>
    <ng-container sof-ar-footer-content>
      main footer content
    </ng-container>
  </sof-ar-footer>

Example:

<sof-ar-navigation ...>
  ...
  <ng-container sof-ar-nav-content>
    <div class="router-container">
      <router-outlet></router-outlet>
    </div>
    <sof-ar-footer>
      <ng-container sof-ar-footer-content>
        <button mat-button color="primary">{{'demo.footer.privacy-policy' | translate}}</button>
        <button mat-button color="primary">{{'demo.footer.terms-of-use' | translate}}</button>
        <button mat-button color="primary">{{'demo.footer.contact' | translate}}</button>
        <p class="visible-mobile flex-full-width">
          <small>{{'demo.footer.copyright' | translate}}</small>
        </p>
      </ng-container>
    </sof-ar-footer>
  </ng-container>
</sof-ar-navigation>

Footer Styling Tips

The footer ng-content is wrapped in a flex-box row container with flex-wrap: wrap. Below are some pre-built helper classes that can be applied to stylize your footer.

  1. Apply .visible-mobile to have content appear only on mobile screens
  2. Apply .flex-visible-mobile to the have an element be wrapped onto its own line
.flex-full-width {
  flex: 0 0 100%;
  text-align: center;
}

.visible-mobile {
  display: none;
}
  @media only screen and (max-width: 959px)  {
    .visible-mobile {
      display: block;
    }
  }

Fixed Footer Styling Tips

Here is an example CSS that can be added to your styles.css to style a fixed footer:

.sof-ar-nav-sidenav-container .mat-drawer-content.mat-sidenav-content {
  display: flex;
  flex-direction: column;
}

.router-container {
  flex: 1 0 auto;
}

sof-ar-footer {
  flex-shrink: 0;
}
sof-ar-footer, .sof-ar-footer-container button {
  font-family: 'Poppins', sans-serif !important;
}

.sof-ar-footer-container button {
  font-weight: 600;
}

Armature Site Map

<sof-ar-site-map></sof-ar-site-map> is a site map that goes into the footer.

Armature Site Map Setup Overview

  1. npm install
  2. Import the armature Module into your app.module.ts 'imports'.
  3. Add Armature component sof-ar-site-map to HTML component.
  4. Configure Armature component settings in the TS
    1. [config] - these are the required settings to configure your header
      1. sectionTitleClass the class that each section title will have, you can define the class in the host component using ::ng-deep.
      2. linkClass the global class the the link text will have, you can define the class in the host component using .
      3. graph its a 2d array (graph) of site map nodes that will define the rows and columns of the site map. Each node represents a site map section, which contains the section of the site map with the section header text and a list of links. In the following section in the typescript setup - will show the examples of how to configure the graph.
        1. sectionTitle the title of the section in the site map node.
        2. direction the direction that the links are aligned - either Horizontal or Vertical.
        3. iconLinks whether or not if the links in the section are icons.
        4. links the list of site map links in the section
          1. text the text of the link.
          2. routerLink the router link.
          3. routePath the route path - either Internal (for internal routes) or External
          4. linkClass the specific class that will take effect in place of the global linkClass.
          5. logoClass the awesomefont class for the logo

Site Map Module Setup

Module.ts:

import { ArmatureModule } from '@softheon/armature';

...

@NgModule({
    imports: [
        ...
        ArmatureModule
        ...
    ],
    ...
})

Site Map Typescript Component Setup

Import the necessary models from the npm package and configure the site map component inputs in your Angular typescript component. We recommend you do this ngOnInit().

Configure the Armature Component Site Map config [config].

The site map component has many options to display links. The following will contain several examples to show how to configure the site map.

This configuration contains two columns with text-blue style class for the section title and the text-green style class for the individual links and contains one section of links in each columns. The first column contains a section with Navigation as the title and has a vertical aligned internal links that leads to payment and document. The payment link has a text-red style. The second column contains a single external link that goes to softheon wiki.

  public siteMapComponentConfig: SiteMapConfig = {
    sectionTitleClass: 'text-blue',
    linkClass: 'text-green',
    graph:[
      [
        {
          sectionTitle: 'Navigation',
          direction: SiteMapDirection.Vertical,
          links: [
            {
              text: 'Make a Payment',
              routerLink: 'payment',
              routePath: RoutePath.Internal,
              linkClass: 'text-red'
            },
            {
              text: 'View documents',
              routerLink: 'document',
              routePath: RoutePath.Internal
            }
          ]
        }
      ],
      [
        {
          sectionTitle: 'External Links',
          direction: SiteMapDirection.Vertical,
          links: [
            {
              text: 'Softheon Wiki',
              routerLink: 'https://wiki.softheon.com/Wiki/',
              routePath: RoutePath.External
            }
          ]
        }
      ]
    ]
  }

This next configuration will contain a horizontal aligned icon links that has a external routes section and an internal route section in two separate sections in a single column

 public siteMapComponentConfig: SiteMapConfig = {
    sectionTitleClass: 'text-blue',
    linkClass: 'text-green',
    graph:[
      [
        {
          sectionTitle: 'External Links',
          direction: SiteMapDirection.Horizontal,
          iconLinks: true,
          links: [
            {
              text: 'Softheon Wiki',
              routerLink: 'https://wiki.softheon.com/Wiki/',
              routePath: RoutePath.External,
              logoClass: 'fa fa-wikipedia-w',
              linkClass: 'text-blue'
            },
            {
              text: 'Facebook',
              routerLink: 'https://www.facebook.com/',
              routePath: RoutePath.External,
              logoClass: 'fab fa-facebook',
              linkClass: 'text-blue'
            }
          ]
        },
        {
          sectionTitle: 'Internal Links',
          direction: SiteMapDirection.Horizontal,
          iconLinks: true,
          links: [
            {
              text: 'Payment',
              routerLink: 'payment',
              routePath: RoutePath.Internal,
              logoClass: 'far fa-credit-card',
              linkClass: 'text-blue'
            }
          ]
        }
      ]
    ]
  }

Site Map HTML Setup

It is recommended to use this component inside armature footer sof-ar-footer in one of the ng containers sof-ar-footer-content, sof-ar-footer-pre-content-1 or sof-ar-footer-pre-content-2

 <sof-ar-footer [footerConfig]="footerConfig">
    <ng-container sof-ar-footer-pre-content-1>
      content for section 1
    </ng-container>
    <ng-container sof-ar-footer-pre-content-2>
      content for section 2
    </ng-container>
    <ng-container sof-ar-footer-content>
      <sof-ar-site-map [config]='siteMapComponentConfig'></sof-ar-site-map>
    </ng-container>
  </sof-ar-footer>

Site Map Styling Tips

Styling the columns

You can override the sof-ar-site-map-column class to customize the columns in the site map.

Example:

::ng-deep .sof-ar-site-map-column {
  padding: 10px;
}

Custom class styling config input

Custom classes passed in the component config should be defined in the component that utilizes the sof-ar-site-map. For example if class 'link-container' is passed in the linkClass config, you can define it in the stylesheet of the host component. In the following example, it shows how you create padding for the link and change the color for the text in the link.

Example:

::ng-deep .link-container {
  padding: 10px;
}

::ng-deep .link-container > a {
  color: blue;
}

Armature Alert Banner

<sof-ar-alert-banner></sof-ar-alert-banner> is an alert banner on the navigation content. There are 4 types of banner, error, information, warn, success and 2 type of styles outline and filled.

Alert Banner Setup Overview

  1. npm install
  2. Import the armature Module into your app.module.ts 'imports'
  3. There are no typescript models associated with this component, skip this step
  4. Add Armature component sof-ar-alert-banner to HTML component

Alert Banner Module Setup

Module.ts:

import { ArmatureModule } from '@softheon/armature';

...

@NgModule({
    imports: [
        ...
        ArmatureModule
        ...
    ],
    ...
})

Alert Banner Component Setup

There is an optional config provider ALERT_BANNER_CONFIG with custom theming options.

  @NgModule({
      ...
      providers: [
          ...
        { provide: ALERT_BANNER_CONFIG, useValue: alertBannerThemeConfig }
          ...
      ],
      ...
  })

Alert Banner Config Guide

The alert config is structured as follow: the border and icon lineColor, the sidebar color for outlined banner outlineSidebar and the background color for filled banner filledBackground. Inside each of those there are the 4 type of banner: error, information, success, and warn.

  const alertBannerThemeConfig = {
    lineColor: {
      error: "#FF5200",
      information: "#987100",
      warn: "#FFC038"
    },
    outlineSidebar: {
      error: "#FF5200",
      information: "#987100",
      warn: "#FFC038"
    },
    filledBackground: {
      error: "#FFF0E0",
      information: "#F3EEE0",
      warn: "#FFF4D1"
    }
  };

Alert Service

On the sof-ar-app-template, there is a built in alert banner that can be used and can be turned off if hasAlertBanner is set to false. If hasAlertBanner is true, then the AlertBannerService can be leveraged to show alert messages.

<sof-ar-app-template [hasAlertBanner]="false">
</sof-ar-app-template>

Hybrid SAML OAuth Service

The Hybrid SAML OAuth Service allows for the management of the local/session storage containing saml assertion data and an OAuth 2.0 access token.

Injection Tokens

InjectionTokens.keyPathSuffix - required

Provides the suffix that will be used when retrieving data from local/session storage

InjectionTokens.window - required

Provides the window object to the service

InjectionTokens.tokenEndpoint - required

The endpoint to be used for refreshing the access token

GlobalInjectionTokens.tokenRefreshTimeMinutes - optional

Amount of time to wait before refreshing the access token. The default is 30 min

InjectionTokens.browserStorageImplementation - optional

Potential values: local | session

This injection token determines what implementation of browser storage will be sued. The default is local.

When using session the value that is provided through local storage will be moved into session storage. After this is done the entry in local storage will be removed.

Armature Role Based Navigation

The Armature Role Based Navigation allow a configuration to be provided indicating the roles allowed in the application and the pages/actions the roles have access to. The roles for a given user are determined through the use of an OAuth2.0 access tokens and a user info endpoint.

RBAC stands for Role Based Access Control

Configuration

Below is an example configuration for defining roles.

export const rbacConfig: RbacConfig = {
    roleConfig: {
        'Service Account': {
            pages: [
                '/documents/invoice',
                '/payment',
                '/autopay',
                '/scheduled',
                '/history',
                '/payment-methods',
                '/paperless'
            ]
        },
        pc: {
            pages: [
                '/buy/pc-games'
            ]
        },
        fanatic: {
            pages: [
                '/buy/**',
            ]
        },
        retro: {
            pages: [
                '/collect/retro-games',
                '/collect'
            ]
        },
        admin: {
            actions: [
                'god-mode'
            ]
        }
    }
};

The RbacConfig above has the following roles, Service Account, pc, fanatic, retro, admin. Any roles not provided in the config will get no access.

Defining a role with no pages or an empty pages entry results in full access

** is used to denote wild card access to child routes.

If a role has access to a child page, for example /documents/invoice they will automatically gain access to the /documents route but not the /documents/some-other-route.

If a user has multiple roles, the access for all of their roles will be merged.

If no role is found, no access is provided

Rbac Action Directive

The Role service also support a directive for showing or hiding items based on role and actions. Actions are string provided in the RBAC config that can be used through the project in the form of a directive. And example of the usage can be seen below

<button mat-icon-button [matMenuTriggerFor]="exampleMenu" aria-label="Example icon-button with a menu" *sofArRbacAction="'god-mode'">
  <span class="sof-ar-header-icon primary-color">
    <i class="fad fa-bell"></i>
  </span>
  <span class="sr-only">{{'demo.header_notifications' | translate}}</span>
</button>

The button listed above will only be visible when the role of the current user has the action god-mode configured for their role. This is done throught the *sofArRbacAction attribute that can be included on any html element.

If the role of the user doesn't have access to the action, the html element will not be displayed to them

Navigation Set up

To use the navigation follow the steps below, these are for integrating the role control with Armature Navigation Module and configurations.

  1. In your root module include the RbacModule in your application module

  2. Provide the follow Inject Tokens in your module's providers

    providers: [
      ...
      { provide: RbacConfig, useValue: {}} // your rbac config object here
      ...
    ]
  1. Inject the OAuth2.0 role service into your component
constructor(
  private readonly oAuthRoleService: Oauth2RoleService
) { }
  1. Then get the newly configured Armature navigation
this.oAuthRoleService.decodedToken$.subscribe(token => {
  this.navData = this.oAuthRoleService.getControlledNavObject(armNavData.navigation, token.claims.getRole);
});

Custom Auth Config

If an application need to switch to a different issuer for auth and requires custom logic there is a CustomAuthConfigService the application can define and setup Auth for logins.

  1. Implement a class that extends CustomAuthConfigService and define the auth config function

  2. Inject the newly defined class into the component

      providers: [
      ...
      { provide: CustomAuthConfigService, useValue: ImplementedCustomAuthConfigService } // your implemented custom auth config service here
      ...
    ]

Elastic RUM set up

In order to include RUM error handling and Route watching, the following should be included in your app.module

First, add the RumModule to your imports

@NgModule({
    declarations: [
    ],
    imports: [
        RumModule
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

Next, provide the RumErrorHandlerService as your global error handler

@NgModule({
    declarations: [
    ],
    imports: [
        RumModule
    ],
    providers: [
      {
        provide: ErrorHandler,
        useClass: RumErrorHandlerService
      }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

Finally, create a constructor and initialize Rum

@NgModule({
    declarations: [
    ],
    imports: [
        RumModule
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
  constructor(@Inject(RumService) rumService: RumService) {
        const config = new RumConfig();
        config.serverUrl = 'https://<your-rum-apm-url>/';
        config.serviceName = '<application-name>';
        rumService.initializeRum(config);
    }
}

Replace the serverUrl with your apm/rum server and replace the serviceName with an application name.

The initializeRum function provides an optional parameter for a user. By default it utilizes the armature sessionId for the userName and userId, these can be customized if desired by providing the optional values to the function.

Error Handler

This module comes with an error handler built in, that will package errors and ship them to RUM. There are two ways it looks for errors. Angular errors, such as http request failures, get captured by the RumErrorHandler instead of the default and get shipped to RUM.

The second looks at any calls being made to console.error and intercepts them. It takes the error, passes it through the error handler, which will submit the error to RUM, then lets the error be logged to the console.

Softheon Error Handler

For instances where RUM has not been set up or there are problems connecting, the softheon error handler has been introduced. By using this service errors are shipped to a provided api endpoint and can be handled by that given endpoint. Logs are shipped in the string format.

The default log level is Warn.

Error Module

Error Common Component

In order to use this component please import the ErrorModule into the parent module the component is being used in

Overview

This component provides a generic error display that can be used for a wide variety of errors. In order to use the component, first create the configuration object for it in your typescript

/** The app component */
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  public errorCommonComponentConfig: ErrorCommonConfig = new ErrorCommonConfig();
  constructor() {
    this.errorCommonComponentConfig.showErrorImage = true;
    this.errorCommonComponentConfig.headerOneText = 'my title text';
    this.errorCommonComponentConfig.headerOneClass = 'text-red';
    this.errorCommonComponentConfig.headerTwoText = 'Secondary title';
    this.errorCommonComponentConfig.headerTwoClass = 'text-blue';
    this.errorCommonComponentConfig.infoText = 'Info Text section';
    this.errorCommonComponentConfig.infoTextClass = 'text-green';
  }
}

Then pass the config to the config input of the component

  <sof-ar-error-common [config]="errorCommonComponentConfig"></sof-ar-error-common>

In this example the css classes look as follows to apply colors to the text

::ng-deep .text-red {
    color: red !important;
}

::ng-deep .text-blue {
    color: blue !important;
}

::ng-deep .text-green {
    color: green !important;
}

API

ErrorCommonComponent

| Name | Description | | ------------------------------------------- | -------------------------------------------------------------------- | | @Input() public config: ErrorCommonConfig | The configuration input to be used for rendering the error component |

ErrorCommonConfig

| Name | Description | | ------------------------- | -------------------------------------------------------------------- | | showErrorImage: boolean | Determines if the error image should be displayed | | errorImageUrl: string | The url to be used for the error image | | headerOneText: string | The text to be used for primary header text | | headerOneClass: string | Space delimitated classes to be applied to the primary header text | | headerTwoText: string | The text to be used for the secondary header text | | headerTwoClass: string | Space delimitated classes to be applied to the secondary header text | | infoText: string | The info text for the error component | | infoTextClass: string | Space delimitated classes to be applied to the info text |

CSS Overrides

This section will describe how to utilize the Armature CSS Override directive

Usage

  1. Include the ThemeModule or ArmatureModule in your AppModule.
  2. In you app.component.html include the following attribute [sofArCssOverride]
  3. In your app.component.ts create a cssOverride public property.
  4. In ngOnInit initialize the property to have your desired overrides, an example object can be found bellow.

html Snippet

<!-- app.component.ts -->
<div [sofArCssOverride]="cssOverride">
  ...
  your application content
  ...
</div>
// app.component.ts

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  public cssOverride: Array<CssOverride>;

  public ngOnInit(): void {
    this.cssOverride = 
    [
          {
              selector: 'tag',
              parameter: 'body',
              attributes: [
                  {
                      name: 'font-family',
                      value: '"Comic Sans MS", cursive, sans-serif'
                  }
              ]
          }
      ];
  }
}

CssOverride Configuration

The directive uses an array of CssOverride objects. The definition for the object can be found bellow

CssOverride

| property | type | possible values | description | | ---------- | ------------------ | -------------------- | ---------------------------------------------------------------- | | selector | string | 'tag', 'id', 'class' | The type of search to perform on the dom to select html elements | | parameter | string | any string | The value that will be searched for the given selector | | attributes | Array<Attribute> | Array of Attribute | The css styles to add to the found html elements |

The selector indicates how the dom will be searched for html elements

  • tag - searches by html element tag name, ie. body, div, span
  • id - searches by element id, returns only 1 element, ie. myElementId
  • class - searches by class name, ie. some-css-class

Attribute

| property | type | possible values | description | | -------- | -------- | ----------------- | ------------------------------------------------------------------- | | name | string | any css attribute | The name of the css attribute to modify on returned elements styles | | value | string | any string | The value to set for the css attribute |

Saving/Printing a specified component

This section will describe how any component for an application can be saved/printed

Setup

There are few steps that must be done in order to use this functionality

First: In the module that will be using this functionality include the following import

import { SofArComponentSavePrintModule } from '@softheon/armature';

@ngModule({
  declarations: [...],
  imports: [
    ...
    SofArComponentSavePrintModule
    ...
  ]
})

Last: Include the following component in a component that will be on the page at the time the user will select to save/print. This can be done in the app.component.ts or in a specific route in the application.

<sof-ar-component-save-print></sof-ar-component-save-print>

Usage

In this example, the print command will be executed by an application defined button in a component. The save/print functionality is not limited to a component, it can be executed from a service/directive/pipe etc.

import { Component, OnInit } from '@angular/core';
import { ComponentSavePrintService } from '@softheon/armature';
import { SomeOtherComponent } from './some/local/component/location';

/** The save print component */
@Component({
  selector: 'app-save-print',
  templateUrl: './save-print.component.html',
  styleUrls: ['./save-print.component.scss']
})
export class SavePrintComponent implements OnInit {

  /**
   * The constructor
   * @param componentSavePrintService The save/print component service
   */
  constructor(
    private readonly componentSavePrintService: ComponentSavePrintService
  ) { }

  /** Angular life cycle hook for component initialization */
  public ngOnInit(): void {
  }

  /** Downloads the pdf of the page */
  public downloadPdf(): void {
    this.componentSavePrintService.savePrintComponent(SomeOtherComponent);
  }
}

The savePrintComponent function takes the type of component that will be saved/printed as the only argument. This component does not have to be the same as the component executing the save/print function, it can be any component in the application including routes.

Limitations

There is currently no way to pass in custom inputs to the component being save/printed. This can be prevented by having a component host the component in question with the correct default inputs and providing the host component to the function rather the desired component.

Subdomain Routing

Armature support subdomain routing including loading configurations specific to the subdomain, with some additional logic to help with ensuring users can't use the site when they shouldn't be able to.

In order to use subdomain routing in your appsettings.json at the root level add a subdomain section. This section has two properties, subdomains and requireConfiguredSubdomain. The subdomains section is a white list of subdomains, this should be configured to only include the subdomain, for example if the url is https://subdomain.domain.host.com/route, there would be an entry for subdomain in the subdomains array.

The requireConfiguredSubdomain ,when true, means when the application start ups with a detected subdomain, it must also find configurations in its assets/configurations directory for that subdomain in the format of subdomain.appsettings.json. If no configurations are found, the application will not start up. When this is set to false, the application can load with out subdomain specific configurations but still requires an entry in the subdomains sections.

Leave the entire subdomain configuration section blank to ignore this feature.

There is a case that can happen with the following example https://subdomain.domain.host.com/route. For this case there must be entry in the subdomains sections for the url to load, but also and entry for domain in the subdomains section for https://domain.host.com/route to be an available url.

Below is a sample subdomain configuration partial

{
  "subdomain": {
    "subdomains": ["subdomain", "domain"],
    "requireConfiguredSubdomain": true
  }
}

Feedback tool

Usage

In the module that will be using this functionality include the following import

  import { FeedbackToolModule } from '@softheon/armature';

  @ngModule({
    declarations: [...],
    imports: [
      ...
      FeedbackToolModule
      ...
    ]
  })

Include this variable in the .ts of the page that is using this component, the 'close' event will set to false & destroy the feedback component, remove it from the dom.

  public showFeedbackTool = true;

Include a function to handle the feedback submit.

  public handleFeedbackSubmit(userFeedback: UserFeedback) {}

Include this at the bottom of the .html, usually the 'thank-you' page.

  // end of page ... 

  @if (showFeedbackTool) {
    <sof-ar-feedback-tool [application]="'armature'" (close)="showFeedbackTool = false" (feedbackSubmit)="handleFeedbackSubmit($event)"/>
  }

| Name | Description | | ---------------------