# nxn-frontend

> This document explains the various uses of the nxn-frontend codebase.

Latest version **2.0.104-rc.4** (published 2023-11-16) · 0 weekly downloads

## Install

```sh
npm install nxn-frontend
pnpm add nxn-frontend
yarn add nxn-frontend
bun add nxn-frontend
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; large bundle.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.104-rc.4 |
| Published | 2023-11-16 |
| First published | 2023-11-16 |
| Weekly downloads | 0 |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=10 <=14 |
| Dependencies | 61 |
| Unpacked size | 14.9 MB |
| Known vulnerabilities | 0 |
| Install scripts | yes |
| Maintainers | adc5czy |

## Links

- npm: https://www.npmjs.com/package/nxn-frontend
- Repository: http://git.bnymellon.net/nexen/nxn-frontend
- npm.io page: https://npm.io/package/nxn-frontend

## Dependencies (61)

- [d3](https://npm.io/package/d3.md) 5.7.0
- [rxjs](https://npm.io/package/rxjs.md) ~6.5.2
- [bower](https://npm.io/package/bower.md) ^1.8.8
- [jspdf](https://npm.io/package/jspdf.md) ~1.4.1
- [redux](https://npm.io/package/redux.md) 4.0.0
- [d3-dsv](https://npm.io/package/d3-dsv.md) 1.0.10
- [lodash](https://npm.io/package/lodash.md) ~4.17.4
- [moment](https://npm.io/package/moment.md) ~2.19.3
- [nxn-ui](https://npm.io/package/nxn-ui.md) 0.7.277
- [sqr-ui](https://npm.io/package/sqr-ui.md) 0.98.7
- [nxn-css](https://npm.io/package/nxn-css.md) 0.2.443
- [nxn-efi](https://npm.io/package/nxn-efi.md) 0.0.155-EFI.1601050727356
- [hammerjs](https://npm.io/package/hammerjs.md) ^2.0.8
- [lodash-es](https://npm.io/package/lodash-es.md) ~4.17.4
- [nxn-forms](https://npm.io/package/nxn-forms.md) 0.0.150-FORMS.1601562804553
- [pptxgenjs](https://npm.io/package/pptxgenjs.md) 2.4.0
- [@types/cli](https://npm.io/package/@types/cli.md) ^0.11.19
- [nxn-common](https://npm.io/package/nxn-common.md) 0.0.549
- [sqr-common](https://npm.io/package/sqr-common.md) 0.0.127
- [yte-common](https://npm.io/package/yte-common.md) 0.0.97-CTSNXN22771.1601052264885
- [rxjs-compat](https://npm.io/package/rxjs-compat.md) ~6.5.2
- [@angular/cdk](https://npm.io/package/@angular/cdk.md) 6.4.7
- [@angular/core](https://npm.io/package/@angular/core.md) 6.1.10
- [@angular/http](https://npm.io/package/@angular/http.md) 6.1.10
- [nx-components](https://npm.io/package/nx-components.md) 0.0.121
- [nxn-bignumber](https://npm.io/package/nxn-bignumber.md) 0.0.7-bignumber.1601050920042
- [nxn-wl-assets](https://npm.io/package/nxn-wl-assets.md) 2.28.4
- [@angular/forms](https://npm.io/package/@angular/forms.md) 6.1.10
- [@nxn/shell-lib](https://npm.io/package/@nxn/shell-lib.md) 2.0.34
- [iframe-resizer](https://npm.io/package/iframe-resizer.md) ~3.6.6
- [nxn-dashboards](https://npm.io/package/nxn-dashboards.md) 1.0.113
- [redux-devtools](https://npm.io/package/redux-devtools.md) ~3.4.0
- [visualizations](https://npm.io/package/visualizations.md) 0.0.169
- [@angular/common](https://npm.io/package/@angular/common.md) 6.1.10
- [@angular/router](https://npm.io/package/@angular/router.md) 6.1.10
- [ag-grid-angular](https://npm.io/package/ag-grid-angular.md) 20.2.0
- [jspdf-autotable](https://npm.io/package/jspdf-autotable.md) ~2.3.5
- [moment-timezone](https://npm.io/package/moment-timezone.md) ~0.5.5
- [@angular/upgrade](https://npm.io/package/@angular/upgrade.md) 6.1.10
- [nxn-digitalpulse](https://npm.io/package/nxn-digitalpulse.md) 0.0.111
- [nxn-ui-angularjs](https://npm.io/package/nxn-ui-angularjs.md) 0.7.277
- [sqr-ui-angularjs](https://npm.io/package/sqr-ui-angularjs.md) 0.98.7
- [@angular/compiler](https://npm.io/package/@angular/compiler.md) 6.1.10
- [@angular/material](https://npm.io/package/@angular/material.md) 6.4.7
- [ag-grid-community](https://npm.io/package/ag-grid-community.md) 20.2.0
- [angular-translate](https://npm.io/package/angular-translate.md) 2.18.1
- [ag-grid-enterprise](https://npm.io/package/ag-grid-enterprise.md) 20.2.0
- [@angular/animations](https://npm.io/package/@angular/animations.md) 6.1.10
- [@ngx-translate/core](https://npm.io/package/@ngx-translate/core.md) 10.0.2
- [@angular-redux/store](https://npm.io/package/@angular-redux/store.md) 9.0.0
- [nx-components-assets](https://npm.io/package/nx-components-assets.md) 0.0.18
- [nxn-common-angularjs](https://npm.io/package/nxn-common-angularjs.md) 0.0.549
- [@types/iframe-resizer](https://npm.io/package/@types/iframe-resizer.md) 3.5.6
- [nxn-reporting-angularjs](https://npm.io/package/nxn-reporting-angularjs.md) 2.8.5-CTSNXN22771.1600837863019
- [nxn-sbp-forms-angularjs](https://npm.io/package/nxn-sbp-forms-angularjs.md) 2.0.16-CTSNXN22771.1600837592341
- [@angular/platform-server](https://npm.io/package/@angular/platform-server.md) 6.1.10
- [nxn-dashboards-angularjs](https://npm.io/package/nxn-dashboards-angularjs.md) 1.0.113
- [@angular/platform-browser](https://npm.io/package/@angular/platform-browser.md) 6.1.10
- [@ngx-translate/http-loader](https://npm.io/package/@ngx-translate/http-loader.md) 2.0.1
- [nxn-digitalpulse-angularjs](https://npm.io/package/nxn-digitalpulse-angularjs.md) 0.0.111-digitalpulse.1601055919959
- [@angular/platform-browser-dynamic](https://npm.io/package/@angular/platform-browser-dynamic.md) 6.1.10

## Recent versions

- 2.0.104-rc.4 (latest) — 2023-11-16

## README

# nxn-frontend
This document explains the various uses of the nxn-frontend codebase.

## References
* [Design Document](https://share.ams.bnymellon.net/sites/CTSProjectRepository/nexen/Project%20Documents/Design/NexenDesign-v3.docx) 
* [Running NEXEN Frontend](https://confluence.bnymellon.net/display/NDOS/Setting+Up+the+NEXEN+Frontend)

## Quick Start
For yarn/bower install errors be sure to configure your local system as per the [documentation](https://confluence.bnymellon.net/display/NDOS/Installing+Windows+Development+Tools)

To quickly serve and run nxn-frontend:

```bash
yarn install
bower install
grunt build-notests
grunt serve
```

## Grunt Commands

### Serving nxn-frontend
The nxn-frontend code can be served in various ways. The following are the available controls:

* Serve source files
    * `grunt serve --proxies no_proxies` mock nxn-service and mock services
    * `grunt serve --proxies all_proxies` **proxy a local nxn-service**, and **proxy services**
    * `grunt serve --proxies nxn_svc` **proxy a local nxn-service**, and mock services
    * `grunt serve --proxies all_no_nxn_svc` mock nxn-service, and **proxy services**
    * `grunt serve --proxies <proxy_option> --pluginProxy allPlugins` 
                     <proxy_option> can be no_proxies or all_proxies or nxn_svc or all_no_nxn_svc 
                     **Apply proxy options along with plugin proxies for all the plugins**
    * `grunt serve --proxies <proxy_option> --pluginProxy <plugin_name>` 
                     <proxy_option> can be no_proxies or all_proxies or nxn_svc or all_no_nxn_svc 
                     **Apply proxy options along with plugin proxies for specified plugin**
    * `grunt serve --pluginProxy allPlugins` mock nxn-service, mock services and **proxy all the locally linked plugins**
    * `grunt serve --pluginProxy <plugin_name>` mock nxn-service, mock services and **proxy one locally linked plugin** 
* Serve minified distribution files (must already have generated `/dist`, e.g. `grunt build-notests`)
    * `grunt serve:dist --proxies no_proxies` Serve distribution, mock nxn-service and mock services
    * `grunt serve:dist --proxies all_proxies` Serve distribution, **proxy a local nxn-service**, and **proxy services**
    * `grunt serve:dist --proxies nxn_svc` Serve distribution, **proxy a local nxn-service**, and mock services
    * `grunt serve:dist --proxies all_no_nxn_svc` Serve distribution, mock nxn-service, and **proxy services**
    * `grunt serve:dist --proxies <proxy_option> --pluginProxy allPlugins` 
                        <proxy_option> can be no_proxies or all_proxies or nxn_svc or all_no_nxn_svc 
                        **Serve Distribution and Apply proxy options along with plugin proxies for all the plugins**
    * `grunt serve:dist --proxies <proxy_option> --pluginProxy <plugin_name>` 
                         <proxy_option> can be no_proxies or all_proxies or nxn_svc or all_no_nxn_svc 
                         **Serve Distribution and Apply proxy options along with plugin proxies for specified plugin**                
    * `grunt serve:dist --pluginProxy allPlugins` Serve distribution, mock nxn-service, mock services and **proxy all the locally linked plugin**
    * `grunt serve:dist --pluginProxy <plugin_name>` Serve distribution, mock nxn-service, mock services and **proxy one locally linked plugin** 
* Serve a white label client
    * `grunt serve --wlKey=<clientWLCookieValue>` serve with the specified client look and feel. To get supported values
    for clientWLCookieValue use the keys of the resourceMap variable in the file mocks/whitelabel/whiteLabelCtrl.js. If
    you did not log out properly and the next time grunt serve shows a look and feel that you do not want, delete 
    cookies and run grunt serve command once more.

To debug proxy rules, add `--verbose` at the end.

`grunt serve` is shorthand for `grunt serve --proxies no_proxies`

To serve multiple instances, you will need to set different ports for the server and the livereload feature.

```
grunt serve --connectPort=9090 --livereload=35730
```

### Test Commands

All tests are executed when running `grunt build` or `grunt test`.

#### LINT Validation

```
grunt nxn-tslint
```

#### Code Formatting

```
grunt format
```
#### Karma Unit Tests

`grunt test-unit`

The above commands utilize the following commands to execute either AngularJS/Angular and Unit/Dist tests. If you
run the following manually, be sure to compile the TypeScript via `grunt ts copy:dist`.

* `grunt karma:angularJSUnit`, tests AngularJS specs in hybrid environment without bundles  
* `grunt karma:angularJSDist`, tests AngularJS specs in hybrid environment with bundles  
* `grunt karma:angularUnit`, tests Angular specs in a pure Angular environment without bundles
* `grunt karma:angularDist`, NOT SUPPORTED YET. See CTSNXN-15148

Add the `--karmaDebug` command line option to run the Karma server without automatically running tests or terminating
so it can be run manually in a GUI browser. This is useful for debugging Karma.

For plugin executions see: [grunt-nxn-plugins:Readme.md](https://git.bnymellon.net/nexen/grunt-nxn-plugins/blob/master/Readme.md#testing)

**Before** running any plugin specific karma commands you should run `grunt build-notests` to ensure the core code is compiled.
It should be run every time you update nxn-frontend.

#### Protractor Integration Tests

`grunt test-integration` executes all integration tests

`grunt update-chrome-driver` will update selenium driver with the right version
for more information see <https://confluence.bnymellon.net/x/xEu_Jw>.
`grunt test-integration:chrome` executes all integration tests for Chrome

`grunt test-integration --protractorSpec <spec-name>` executes only the specified test; 
The path for `<spec-name>` is relative to `./test/e2e/`:

`grunt test-integration:chrome --protractorSpec plugins/<pluginName>/test/e2e/<spec name>` executes an e2e test from the <pluginName> plugin

`grunt dist-integration:chrome --protractorSpec plugins/<pluginName>/test/e2e/<spec name>` executes an e2e test from the <pluginName> plugin using the minified distribution files

For example: `grunt test-integration:chrome --protractorSpec login/login.spec.js`
`grunt test-integration:chrome --protractorSpec plugins/slm/test/e2e/slm.spec.js` executes a plugin test from the slm plugin

### Build
The following command performs a build which will create a distribution directory: 

`grunt build` runs all validation, unit-tests, and integration-tests

`grunt build-noprotractor` runs all validation and ONLY unit-tests

`grunt build-notests` runs all validation and NO unit or integration tests


### Debugging Karma test failures
1. In `Gruntfile.js` > initConfig section > `karma`
 - set all `singleRun` to false

2. In `test/karma.conf.js`, 
 - set `config.browsers` to empty array
 - set `config.singleRun` to `false`
 - set `config.logLevel` to `config.LOG_DEBUG` 
 - comment out the coverage preprocessors
 
3. `grunt ts karma:unit --verbose --debug;`  
 - the terminal should wait for a browser ("No captured browser, ...") 

4. Open chrome to `http://localhost:9876/debug.html`
 - Use F12 to open the developer console so you can see Network activity & Sources

5. `fdescribe` or `fit` on the test that is failing

6. Add `debugger` statements or breakpoints to stop execution

7. When finished, revert all of these changes


## Debugging in intellij (with breakpoints)

1. Intellij > `Run` > `Edit Configurations`
2. `New` > `JavaScript Debug`
  - url: `http://localhost:9876/debug.html`
  - browser: `Chrome`
3. Set a breakpoint in your ts code (or add a `debugger;` statement)
4. `grunt ts karma:angularUnit --karmaDebug;`
    - The command line will wait with a message like `Karma v1.7.1 server started at http://0.0.0.0:9876/`
5. `Run` > `Debug...` > "Whatever you named your config"
    - This will start the browser
6. When finished...
  - use `CTRL+C` to terminate the command line
  - Close the spawned instance of Chrome

NOTE: the port might be 9876, 9877, ... depending on how many instances are running.


# Debugging SystemJs
These steps help you trace import requests. 

1. In `./appConfig.js`, switch to the systemjs source:
- From:`node_modules/systemjs/dist/system.js`
- To:  `node_modules/systemjs/dist/system.src.js`

2. In `node_modules/systemjs/dist/system.src.js`
Add these lines to the top of the `normalize` function, [see here](https://github.com/systemjs/systemjs/blob/0.20.19/dist/system.src.js#L1621)

```javascript
    function normalize(key, parentKey) {
    
        //---------------------------------------
        // Print imports to console
        //---------------------------------------
        var msg = "[system.normalize] \nimport:\t'" + key + "'";
        if (parentKey) {
            msg += "\nfrom: \t'" + parentKey + "'";
        } else {
            msg += " (top-level request)";
        }
        console.info(msg);
        console.info("");
        //---------------------------------------
        
        var config = this[CONFIG];
        // ... the rest of the function here ...
    }
```

# AOT
AOT is enabled for production builds(grunt serve:dist) not local builds(grunt serve).
Please follow AOT guidelines to resolve AOT-related error: https://angular.io/guide/aot-compiler

# API Documentation

To view the API Docs, run grunt serve and navigate to /docs for AngularJS and /docs/angular for Angular. (e.g. http://localhost:9000/docs).
Methods that should not be exposed to Plugin Teams should have @internal inside the jsdoc (e.g. /** @internal */) of the method or property.
Plugin developers and 2nd party developers should run grunt serve.
Core developers should run grunt serve --internalDocs.

# Running NEXEN Hybrid with the NDP Shell
Integrating the NEXEN Portal with the NEXEN Distributed Portal requires additional NDP-specific metadata and assets.
This is normally handled by the NPX reverse-proxy, but in order to manage the risk of switching NEXEN Portal to NPX,
we have implemented multiple bootstrap options for NEXEN Portal:

* LEGACY - Angular-hybrid application only, no NDP integration.
* NPX_INJECT - NEXEN Portal has been processed by NPX
* NDP_FETCH - NEXEN Portal will download NDP resources itself, and has not been processed by NPX.

## Running NDP Shell via NEXEN App Server (NPX mock) - NPX_INJECT Mode
To run the NEXEN Hybrid with the NDP Shell in a similar way to how it will run when NPX injects the shell scripts and payloads, you can do as follows:

1. Run `grunt serve` or `grunt serve:dist` to serve NEXEN Hybrid in one terminal
2. In a separate terminal run `yarn nexenapp`. Note that the NEXEN App configuration is in the `nexenappdev.json` file
3. You can access the application running through the NEXEN App server on `http://localhost:4500`. Access /shellMocks to change mocks for the different payloads that are injected. 

## Lazy Load the NDP Shell via Orchestration Service - NDP_FETCH Mode.
1. Run `grunt serve` or `grunt serve:dist` to serve NEXEN Hybrid in one terminal
2. Access the application on `http://localhost:9000` 
3. Set an `ndp` cookie on `localhost:9000` to `nonpx`
   - Add `?ndp=nonpx` to set ndp cookie to `nonpx`
   - Add `?ndp=` or `?ndp=anyvalue` to unset the ndp cookie
4. You can use the userName *ndpDelay* or *ndpError* to test what happens when the orchestration service api is slow or fails.

In order to manage risk, the new NDP integration implemented is encapsulated within a new set of index-templates
(`ndp_*.html`) generated from the same `index.tpl` used to generate the non-NDP `index_*.html` templates. The primary
difference is the NDP-templates requires delaying the application bootstrap until the NDP data has been received, or
timed-out; while the original non-NDP-templates immediately load the application.

# NDP Flags
When running NEXEN in a browser through NPX, you can control the NEXEN Shell's integration via the `shell` query param.

- Add `?shell=false` to show FRONTEND (legacy hybrid header/footer)
- Add `?shell=both`  to show both SHELL and FRONTEND

# Note about how Hybrid Loads
The NEXEN Portal uses a mix of "old javascript", non-module based that pollute window object (JS built
with Grunt), and "new javascript", encapsulated within ECMAScript Modules (TS built with Angular CLI & Webpack).
Since we are using SystemJS (old javascript) to load the Angular application (new javascript), we can't use
ESM (import/export) natively and therefore rely on Webpack to convert the Angular modules into non-ESM
javascript.

Browsers load scripts in a specific order based on their type (omitted vs "module"), defer, and async attributes.

A side-effect of this architecture is that the entire NEXEN Portal application loads within the non-module
script loading phase.

This is a problem for the NEXEN Shell (a module based application) since it should load first. In order for the
NEXEN Shell script to load before the NEXEN Portal, we must wait to load the NEXEN Portal application until the
window is loaded. This will ensure that all scripts, old and new (type="module"), are loaded before
bootstrapping the NEXEN Portal application and allow the NEXEN Shell to be loaded.

# MyBNYM Testing
MyBNYM is a special operating mode for NEXEN that allows users to access NEXEN via Desktop SSO. The following are ways
of testing MyBNYM locally.

## Login as MyBNYM
1. Clear all cookies
1. http://localhost:9000/apps/login
1. Open the brower's dev console and run `localStorage.setItem('my', true)`
1. Change the `wlCookie` to `polaris` (Dev Tool > Application > Cookies)
1. Login using `desktopSSO` user and any password

## Step up to Level 10
1. Attempt to access any L10 State, like "All Dashboards"
2. An empty dialog will appear. (There are no mocks for the L10 stepup)
3. Open the browser's dev console and run `handleStepupSuccess()`
4. The dialog will close as if it was submitted, and the user should now be at L10.

---
_Source: https://npm.io/package/nxn-frontend · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
