npm package: @softheon/armature
Description: This document is also available on [Softheon Wiki](https://wiki.softheon.com/Wiki/article/3861)
Latest version: 21.2.1

# Getting started

This document is also available on [Softheon Wiki](https://wiki.softheon.com/Wiki/article/3861)

## 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

```javascript
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

```javascript

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

```json
{}
```

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

```json
{}
```

Finally in your `app.module.ts` include the following line in your imports array

```javascript

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

```javascript
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

```scss
@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

```html
<sof-ar-app-template>
</sof-ar-app-template>
```

**Optional** Add footer content using the following ng-content selector

```html
<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

```html
<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:

```javascript

/**
 * 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

```javascript
 OAuthModule.forRoot({
            resourceServer: {
                allowedUrls: [],
                sendAccessToken: true
            }
        }),
```

Then add the following object to the root level of your `src/assets/baseline/appsettings.json` file

```json
 "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.

```html
<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.

```javascript
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.

```json
{
    "primaryColor": {
        "fifty": "#E6E5F0",
        "oneHundred": "#C2BFDA",
        "twoHundred": "#9994C1",
        "threeHundred": "#7069A8",
        "fourHundred": "#514895",
        "fiveHundred": "#322882",
        "sixHundred": "#2D247A",
        "sevenHundred": "#261E6F",
        "eightHundred": "#1F1865",
        "nineHundred": "#130F52",
        "a50": "rgba(50, 40, 130, 0.04)",
        "a100": "rgba(50, 40, 130, 0.08)",
        "a200": "rgba(50, 40, 130, 0.16)",
        "a300": "rgba(50, 40, 130, 0.24)",
        "a400": "rgba(50, 40, 130, 0.32)",
        "a500": "rgba(50, 40, 130, 0.40)",
        "a600": "rgba(50, 40, 130, 0.48)",
        "a700": "rgba(50, 40, 130, 0.56)",
        "a800": "rgba(50, 40, 130, 0.64)",
        "a900": "rgba(50, 40, 130, 0.72)"
    },
    "primaryContrast": {
        "fifty": "rgba(0, 0, 0, 0.87)",
        "oneHundred": "rgba(0, 0, 0, 0.87)",
        "twoHundred": "rgba(0, 0, 0, 0.87)",
        "threeHundred": "rgba(0, 0, 0, 0.87)",
        "fourHundred": "#ffffff",
        "fiveHundred": "#ffffff",
        "sixHundred": "#ffffff",
        "sevenHundred": "#ffffff",
        "eightHundred": "#ffffff",
        "nineHundred": "#ffffff"
    }
}
 ```

3. Then call `ThemeService.initPalette` providing the `ThemePaletteModel` as the argument. A snippet can be found below

```javascript
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);
  }
}
```

## 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:

```typescript
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 `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. `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. `displayNumbers`true 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

```typescript
  /** 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

```html
<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.

```html
<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.:

```css
@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:

```css
.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.

```html
<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:

```typescript
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.

```typescript
  /** 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.

```html
<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:

```html
  <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:

```css
.primary-color {
  color: #4DB6AC;
}

.sof-ar-header-button-text, .sof-ar-header-menu-list {
  font-family: 'Poppins', sans-serif !important;
}
```

```html
  <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:

```typescript
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

```javascript
  public footerConfig = new FooterConfig()

  footerConfig.showPreContent1 = true;
  footerConfig.showPreContent2 = true;
```

2. 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

```html
 <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:

```html
<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

```css
.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:

```css
.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:

```typescript
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.

```typescript
  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

```typescript
 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`

```html
 <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:

```scss
::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:

```scss
::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:

```typescript
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.

```typescript
  @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`.

```typescript
  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.

```html
<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.

```javascript
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

```html
<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

```javascript
    providers: [
      ...
      { provide: RbacConfig, useValue: {}} // your rbac config object here
      ...
    ]
```

3. Inject the OAuth2.0 role service into your component

```javascript
constructor(
  private readonly oAuthRoleService: Oauth2RoleService
) { }

```

4. Then get the newly configured Armature navigation

```javascript
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

```typescript
      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

```javascript
@NgModule({
    declarations: [
    ],
    imports: [
        RumModule
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}
```

Next, provide the `RumErrorHandlerService` as your global error handler

```javascript
@NgModule({
    declarations: [
    ],
    imports: [
        RumModule
    ],
    providers: [
      {
        provide: ErrorHandler,
        useClass: RumErrorHandlerService
      }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}
```

Finally, create a constructor and initialize Rum

```javascript
@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

```javascript
/** 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

```html
  <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

```css
::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

```html
<!-- app.component.ts -->
<div [sofArCssOverride]="cssOverride">
  ...
  your application content
  ...
</div>
```

```javascript
// 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

```javascript
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.

```html
<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.

```javascript
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

```json
{
  "subdomain": {
    "subdomains": ["subdomain", "domain"],
    "requireConfiguredSubdomain": true
  }
}
```
## Feedback tool

### Usage

In the module that will be using this functionality include the following import

```javascript
  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.

```javascript
  public showFeedbackTool = true;
```

Include a function to handle the feedback submit.

```javascript
  public handleFeedbackSubmit(userFeedback: UserFeedback) {}
```

Include this at the bottom of the .html, usually the 'thank-you' page.

```html
  // end of page ... 

  @if (showFeedbackTool) {
    <sof-ar-feedback-tool [application]="'armature'" (close)="showFeedbackTool = false" (feedbackSubmit)="handleFeedbackSubmit($event)"/>
  }
```

| Name                                                          | Description                                                          |
| -------------------------------------------                   | -------------------------------------------------------------------- |
| `@Input() private application: string`                        |