master 9dfa15c5c4b7 cached
267 files
604.7 KB
137.2k tokens
655 symbols
1 requests
Download .txt
Showing preview only (672K chars total). Download the full file or copy to clipboard to get everything.
Repository: catalogicsoftware/ngx-dynamic-dashboard-framework
Branch: master
Commit: 9dfa15c5c4b7
Files: 267
Total size: 604.7 KB

Directory structure:
gitextract_fareezle/

├── .gitignore
├── LICENSE
├── README.md
├── angular.json
├── build.sh
├── e2e/
│   ├── app.e2e-spec.ts
│   ├── app.po.ts
│   └── tsconfig.e2e.json
├── karma.conf.js
├── ngx-dynamic-dashboard-framework.iml
├── package.json
├── protractor.conf.js
├── semantic.json
├── src/
│   ├── app/
│   │   ├── about/
│   │   │   ├── about-component.ts
│   │   │   ├── about.module.ts
│   │   │   ├── model.ts
│   │   │   ├── service.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── add-gadget/
│   │   │   ├── add-gadget-component.ts
│   │   │   ├── add-gadget.module.ts
│   │   │   ├── gadget-factory.ts
│   │   │   ├── gadgetLibraryResponse.ts
│   │   │   ├── service.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── api-token/
│   │   │   └── api-token.service.ts
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   ├── app.module.ts
│   │   ├── board/
│   │   │   ├── board.component.ts
│   │   │   ├── board.module.ts
│   │   │   └── view.html
│   │   ├── configuration/
│   │   │   ├── configuration-component.ts
│   │   │   ├── configuration.module.ts
│   │   │   ├── styles.css
│   │   │   ├── tab-artificial-intelligence/
│   │   │   │   ├── ai-configuration-tab.component.ts
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tab-boards/
│   │   │   │   ├── boards-configuration-tab.component.ts
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tab-endpoint/
│   │   │   │   ├── endpoint-configuration-tab.component.ts
│   │   │   │   ├── endpoint.help.ts
│   │   │   │   ├── endpoint.model.ts
│   │   │   │   ├── endpoint.service.ts
│   │   │   │   ├── endpointDetail.component.ts
│   │   │   │   ├── endpointDetail.html
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tab-options/
│   │   │   │   ├── options-configuration-tab.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tabs.model.ts
│   │   │   └── view.html
│   │   ├── datalist/
│   │   │   ├── action-model.ts
│   │   │   ├── data-list.component.ts
│   │   │   ├── data-list.module.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── detail/
│   │   │   ├── detail.component.ts
│   │   │   ├── detail.model.ts
│   │   │   ├── detail.module.ts
│   │   │   ├── detail.resolver.ts
│   │   │   ├── filter.pipe.ts
│   │   │   ├── service.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── dynamic-form/
│   │   │   ├── dynamic-form-module.ts
│   │   │   ├── dynamic-form-property.component.html
│   │   │   ├── dynamic-form-property.component.ts
│   │   │   ├── dynamic-form.component.html
│   │   │   ├── dynamic-form.component.ts
│   │   │   ├── property-base.ts
│   │   │   ├── property-checkbox.ts
│   │   │   ├── property-control.service.ts
│   │   │   ├── property-dropdown.ts
│   │   │   ├── property-dynamicdropdown.ts
│   │   │   ├── property-hidden.ts
│   │   │   ├── property-number.ts
│   │   │   ├── property-textbox.ts
│   │   │   └── styles-props.css
│   │   ├── error/
│   │   │   ├── error-handler.component.ts
│   │   │   ├── error-handler.ts
│   │   │   ├── error-model.ts
│   │   │   ├── error.module.ts
│   │   │   ├── styles-error.css
│   │   │   └── view.html
│   │   ├── facet/
│   │   │   ├── capitalize-first-character-pipe.ts
│   │   │   ├── facet-component.ts
│   │   │   ├── facet-model.ts
│   │   │   ├── facet-tag-processor.ts
│   │   │   ├── facet.module.ts
│   │   │   ├── filter-list-component.ts
│   │   │   ├── filter-tag-component.ts
│   │   │   └── styles.css
│   │   ├── gadgets/
│   │   │   ├── _common/
│   │   │   │   ├── base-chart-models/
│   │   │   │   │   ├── bar.model.ts
│   │   │   │   │   └── series.model.ts
│   │   │   │   ├── gadget-base.ts
│   │   │   │   ├── gadget-config-model.ts
│   │   │   │   ├── gadget-header-component.ts
│   │   │   │   ├── gadget-header.html
│   │   │   │   ├── gadget-operation-control-component.ts
│   │   │   │   ├── gadget-property.service.ts
│   │   │   │   ├── gadget-shared.module.ts
│   │   │   │   ├── help-modal-component.ts
│   │   │   │   ├── help-modal.html
│   │   │   │   ├── igadget.ts
│   │   │   │   ├── styles-gadget.css
│   │   │   │   ├── vis-drill-down-component.ts
│   │   │   │   └── vis-drill-down.html
│   │   │   ├── barchart/
│   │   │   │   ├── barchart-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── bubble/
│   │   │   │   ├── bubble-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── cpu/
│   │   │   │   ├── cpu-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── cpum/
│   │   │   │   ├── cpu.model.ts
│   │   │   │   ├── cpum-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── disk/
│   │   │   │   ├── disk-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── donut/
│   │   │   │   ├── donut-gadget.component.ts
│   │   │   │   ├── drill-down-component.ts
│   │   │   │   ├── drill-down-style.css
│   │   │   │   ├── drill-down.html
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── edge-service-list/
│   │   │   │   ├── edge-service-list-gadget.component.ts
│   │   │   │   ├── service-list.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── gadget.module.ts
│   │   │   ├── job-analysis/
│   │   │   │   ├── ja.css
│   │   │   │   ├── job-analysis-gadget.component.ts
│   │   │   │   ├── model.json
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── memory/
│   │   │   │   ├── memory-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── news/
│   │   │   │   ├── news-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── piechart/
│   │   │   │   ├── piechart-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── port-connection/
│   │   │   │   ├── port-connection-gadget.component.ts
│   │   │   │   ├── port-connection.css
│   │   │   │   ├── result-view.component.ts
│   │   │   │   ├── result-view.html
│   │   │   │   ├── service.model.ts
│   │   │   │   ├── service.ts
│   │   │   │   ├── solution-view.component.ts
│   │   │   │   ├── solution-view.html
│   │   │   │   └── view.html
│   │   │   ├── property-list/
│   │   │   │   ├── property-list-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── service-list/
│   │   │   │   ├── service-list-gadget.component.ts
│   │   │   │   ├── service-list.ts
│   │   │   │   └── view.html
│   │   │   ├── statistic/
│   │   │   │   ├── service.ts
│   │   │   │   ├── statistic-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── storage-object-list/
│   │   │   │   ├── service.ts
│   │   │   │   ├── storage-object-list.component.ts
│   │   │   │   ├── style.css
│   │   │   │   └── view.html
│   │   │   ├── todo/
│   │   │   │   ├── service.ts
│   │   │   │   ├── todo-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── trend/
│   │   │   │   ├── service.ts
│   │   │   │   ├── trend-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   └── trend-line/
│   │   │       ├── service.ts
│   │   │       ├── trend-line-gadget.component.ts
│   │   │       └── view.html
│   │   ├── grid/
│   │   │   ├── cell.component.ts
│   │   │   ├── grid.component.ts
│   │   │   ├── grid.html
│   │   │   ├── grid.module.ts
│   │   │   ├── grid.service.ts
│   │   │   └── styles-grid.css
│   │   ├── layout/
│   │   │   ├── layout-component.ts
│   │   │   ├── layout.module.ts
│   │   │   ├── model.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── menu/
│   │   │   ├── IEvent.ts
│   │   │   ├── menu-service.ts
│   │   │   ├── menu.component.ts
│   │   │   ├── menu.module.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── notification/
│   │   │   ├── notification-component.css
│   │   │   ├── notification-component.html
│   │   │   ├── notification-component.spec.ts
│   │   │   ├── notification-component.ts
│   │   │   ├── notification-service.spec.ts
│   │   │   ├── notification-service.ts
│   │   │   ├── notification.model.ts
│   │   │   ├── notification.module.ts
│   │   │   ├── notificationDetail.component.ts
│   │   │   └── notificationDetail.html
│   │   ├── routing.module.ts
│   │   ├── services/
│   │   │   ├── configuration-sample-boards-prod.model.ts
│   │   │   ├── configuration-sample-boards.model.ts
│   │   │   ├── configuration-sample-default-board.ts
│   │   │   ├── configuration.service.ts
│   │   │   ├── runtime.service.ts
│   │   │   └── websocket-service.ts
│   │   ├── toast/
│   │   │   ├── message.ts
│   │   │   ├── reverse.pipe.spec.ts
│   │   │   ├── reverse.pipe.ts
│   │   │   ├── toast.component.css
│   │   │   ├── toast.component.html
│   │   │   ├── toast.component.spec.ts
│   │   │   ├── toast.component.ts
│   │   │   ├── toast.module.ts
│   │   │   ├── toast.service.spec.ts
│   │   │   └── toast.service.ts
│   │   └── typeahead-input/
│   │       ├── styles.css
│   │       ├── typeahead-input.component.ts
│   │       ├── typeahead-input.module.ts
│   │       └── view.html
│   ├── assets/
│   │   ├── .gitkeep
│   │   └── api/
│   │       ├── chart-mock-bar-model.json
│   │       ├── chart-mock-bubble-model.json
│   │       ├── chart-mock-pie-model.json
│   │       ├── connection-model.json
│   │       ├── cpu-model.json
│   │       ├── disk-help-model.json
│   │       ├── disk-model.json
│   │       ├── donut-model.json
│   │       ├── gadget-library-model-prod.json
│   │       ├── gadget-library-model.json
│   │       ├── http-codes.json
│   │       ├── news-model.json
│   │       ├── port-model.json
│   │       ├── stat-database-model.json
│   │       ├── stat-job-model.json
│   │       ├── stat-undefined-model.json
│   │       ├── stat-vm-model.json
│   │       ├── stat-volume-model.json
│   │       ├── storage-model.json
│   │       ├── todo-model.json
│   │       ├── trend-model.json
│   │       ├── trendline-help-model.json
│   │       └── version-model.json
│   ├── environments/
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.css
│   ├── test.ts
│   ├── tsconfig.app.json
│   ├── tsconfig.spec.json
│   └── typings.d.ts
├── tsconfig.json
└── tslint.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries

# webpack stuff
dist

# node_modules
node_modules

# semantic
semantic



# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml

# Gradle:
.idea/**/gradle.xml
.idea/**/libraries

# Mongo Explorer plugin:
.idea/**/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

documentation/

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) [year] [fullname]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================

# NGX Dynamic Dashboard Framework

## Natural Language Processing (NLP) integration
![Image of Main Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/nlp.gif)

## Sample Board 1
![Image of Main Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/images/sb1.png)

## Add Board and Gadget 
![Image of Add Gadget To Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/add.gif)

## Layout
![Image Layout](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/layout.gif)

## Example JSON document
The following JSON document describes a single board along with its layout, gadgets and their properites.

```json
{
  "board": [
    {
      "title": "Board Sample 1",
      "structure": "3-6-3",
      "id": 9,
      "boardInstanceId": 1,
      "rows": [
        {
          "columns": [
            {
              "styleClass": "three wide",
              "gadgets": [
                {
                  "componentType": "NewsGadgetComponent",
                  "name": "News",
                  "description": "What's new",
                  "icon": "images/news.png",
                  "instanceId": 1500253814523,
                  "tags": [
                    {
                      "facet": "Informational",
                      "name": "news"
                    },
                    {
                      "facet": "List",
                      "name": "news"
                    }
                  ],
                  "config": {
                    "propertyPages": [
                      {
                        "displayName": "Run",
                        "groupId": "run",
                        "position": 10,
                        "properties": [
                          {
                            "value": "news",
                            "key": "endpoint",
                            "label": "News URL",
                            "required": false,
                            "order": 3,
                            "controlType": "dynamicdropdown"
                          },
                          {
                            "value": "News",
                            "key": "title",
                            "label": "Title",
                            "required": false,
                            "order": 1,
                            "controlType": "textbox"
                          },
                          {
                            "value": 2,
                            "key": "instanceId",
                            "required": false,
                            "order": -1,
                            "controlType": "hidden"
                          }
                        ]
                      }
                    ]
                  }
                }
              ]
            },
            {
              "styleClass": "six wide",
              "gadgets": [
                {
                  "componentType": "CPUGadgetComponent",
                  "name": "CPU Chart",
                  "description": "Monitors CPU utilization for application.",
                  "icon": "images/cpu.png",
                  "instanceId": 1499912922910,
                  "tags": [
                    {
                      "facet": "Performance",
                      "name": "real-time"
                    },
                    {
                      "facet": "Chart",
                      "name": "bar"
                    }
                  ],
                  "config": {
                    "propertyPages": [
                      {
                        "displayName": "Run",
                        "groupId": "run",
                        "position": 10,
                        "properties": [
                          {
                            "value": "CPU Utilization",
                            "key": "title",
                            "label": "Title",
                            "required": false,
                            "order": 1,
                            "controlType": "textbox"
                          },
                          {
                            "value": "Carlosappliance - Process Monitor",
                            "key": "endpoint",
                            "label": "API Endpoints",
                            "required": false,
                            "order": 3,
                            "controlType": "dynamicdropdown"
                          },
                          {
                            "value": 999,
                            "key": "instanceId",
                            "required": false,
                            "order": -1,
                            "controlType": "hidden"
                          }
                        ]
                      },
                      {
                        "displayName": "Chart",
                        "groupId": "chart",
                        "position": 11,
                        "properties": [
                          {
                            "value": true,
                            "key": "chart_properties",
                            "label": "Show chart details",
                            "required": false,
                            "order": 3,
                            "controlType": "checkbox"
                          }
                        ]
                      }
                    ]
                  }
                },
                {
                  "componentType": "TrendGadgetComponent",
                  "name": "Trend",
                  "description": "General trends.",
                  "icon": "images/trend.png",
                  "instanceId": 1499912901569,
                  "tags": [
                    {
                      "facet": "Performance",
                      "name": "trend"
                    },
                    {
                      "facet": "Chart",
                      "name": "area"
                    }
                  ],
                  "config": {
                    "propertyPages": [
                      {
                        "displayName": "Run",
                        "groupId": "run",
                        "position": 10,
                        "properties": [
                          {
                            "value": "Devappliance",
                            "key": "endpoint",
                            "label": "API Endpoints",
                            "required": false,
                            "order": 2,
                            "controlType": "dynamicdropdown"
                          },
                          {
                            "value": "Trend",
                            "key": "title",
                            "label": "Title",
                            "required": false,
                            "order": 1,
                            "controlType": "textbox"
                          },
                          {
                            "value": 2,
                            "key": "instanceId",
                            "required": false,
                            "order": -1,
                            "controlType": "hidden"
                          }
                        ]
                      },
                      {
                        "displayName": "Chart",
                        "groupId": "chart",
                        "position": 11,
                        "properties": [
                          {
                            "value": true,
                            "key": "chart_properties",
                            "label": "Show chart details",
                            "required": false,
                            "order": 3,
                            "controlType": "checkbox"
                          }
                        ]
                      }
                    ]
                  }
                }
              ]
            },
            {
              "styleClass": "three wide",
              "gadgets": []
            }
          ]
        }
      ]
    }
  ]
}
```

## Alert/Notification
![Image Notification](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/notification.gif)

## Sample Realtime Web Socket Based Gadget
![Image of Add Gadget To Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/websocket-realtime.gif)

## Sample Board 2
![Image of Main Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/images/sb2.png)

## Drag and Drop
![Image of Add Board To Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/drag-drop.gif)

## Facet Filter
![Image of Filter Board To Screen](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/filter.gif)



> Note: This project is under heavy construction and is not intended for general production use yet. As such, we are not accepting bugs at the moment and documentation is quite lacking.

This is an angular (ngx) based dashboard framework that is inspired by JIRA's dashboard implementation and https://github.com/angular-dashboard-framework/angular-dashboard-framework

The primary projects leveraged:
* Angular  - https://angularjs.org/
* ngx-charts (angular based d3 charts) - https://github.com/swimlane/ngx-charts
* Semantic-UI - https://semantic-ui.com/
* ng2-dnd drag and drop - https://github.com/akserg/ng2-dnd
* AI Natural Language Processing - The board includes two options for AI, Wit.Ai and IBM Watson.
* Wit.ai - Natural Language Processing site has been integrated via JSONP
* IBM Watson - IBM Watson does not support JSONP so the code relies on a backend implementation of the IBM Watson SDK.
I offer sample backend code based on Spring Boot within the comments of the Runtime Service

Features:
* Leverages Angular's dynamic data driven forms approach for gadget property pages and properties - https://angular.io/guide/dynamic-form
* Dynamic component strategy for creating gadget instances during runtime - https://angular.io/guide/dynamic-component-loader
* Faceted gadget search approach leveraging tags
* Support multiple board creation
* Drag and Drop support
* Multiple Data Source/Endpoint management
* Web Socket support
* Completely customizable and configurable

# Getting Started Developing a Gadget

The code includes a very simple Todo gadget that can be used as an example for getting started developing your own gadget. The following steps uses that Todo Gadget as a reference. You focus on defining the gadget and the rest of the framework will deal with making it available to the Add Gadget Modal, drag and drop, instance creation, tracking, persistence and cleanup, etc.

## Define the Gadget Component, Service and View

* Todo Component  [todo-gadget.component.ts](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/gadgets/todo/todo-gadget.component.ts)
* Todo View [view.html](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/gadgets/todo/view.html)
* Todo Service [service.ts](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/gadgets/todo/service.ts)
* Sample mock service data [todo-model.json](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/assets/api/todo-model.json)

## Define the gadget's model

The model is used to dynamically create and render the gadget and its property page forms. This model is an entry into a model array used for all gadgets. You will simply add an entry to the model's array. See the Todo entry.
Add an entry for the gadget in the library model array [gadget-library-model.json](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/assets/api/gadget-library-model.json)

## Add the gadget entry to the gadget factory class

Add an entry for your gadget in the factory gadget class [gadget-factory.ts](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/add-gadget/gadget-factory.ts)

## Gadget Icon

Define an image/icon for your gadget [todo.png](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/assets/images/todo.png)

## Gadget Module References

* Import the gadget's component into the board module [board.module.ts](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/board/board.module.ts)
* Import the gadget's service into the grid module [grid.module.ts](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/grid/grid.module.ts)
* Import the gadget's component and service into the gadget module [gadget.module.ts](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework/blob/master/src/app/gadgets/gadget.module.ts)

![Todo Gadget](https://github.com/catalogicsoftware/Angular-2-Dashboard-Framework/blob/master/src/assets/documentation/gifs/TodoGadget.gif)

# NgADF

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.x.

## Setup

Clone this repository then run `npm install`

## Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.


## Build

Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--aot --prod` flag for ahead of time compilation and production mode. 

The title of that issue suggests an issue with AOT but in my testing `--prod` seems to be the problem. 

## Running unit tests

Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
Before running the tests make sure you are serving the app via `ng serve`.

## Source Code Documentation

This project uses the compodoc project : https://github.com/compodoc/compodoc

Run `npm install -g @compodoc/compodoc` to install compodoc globally
Run `compodoc -p tsconfig.json -n 'NGX Dynamic Dashboard Framework'` to generate the documentation. It will be placed in the documentation folder
Run `compodoc -s` to serve up the documentation site at http://localhost:8080

## Spring Boot Backend Project

There is an accompanying java based backend project that serves up some of the endpoints used by the board.

[https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework-microservice](https://github.com/catalogicsoftware/ngx-dynamic-dashboard-framework-microservice)

It is a maven based project so you will need to do the following: 
* Install and configure Maven. 
* Copy the dist directory produced from this project's build into the 
`static` folder of the microservice project. 
* Build the microservice project using `<directory path to maven bin folder>/mvn install`  from within the project's root directory. 
* Launch the microservice over the default port: `http://localhost:8080` using `java -jar <path to the microservice root folder>/target/ngxdd-x.y.z.jar`


## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).



================================================
FILE: angular.json
================================================
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ng-adf": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.app.json",
            "polyfills": "src/polyfills.ts",
            "assets": [
              "src/assets",
              "src/favicon.ico"
            ],
            "styles": [
              "src/styles.css",
              "node_modules/semantic-ui/dist/semantic.min.css",
              "node_modules/ng2-dnd/bundles/style.css",
              "node_modules/material-design-icons/iconfont/material-icons.css"
            ],
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/semantic-ui/dist/semantic.min.js",
              "node_modules/d3-shape/dist/d3-shape.min.js"
            ]
          },
          "configurations": {
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "ng-adf:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ng-adf:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "ng-adf:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "karmaConfig": "./karma.conf.js",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/semantic-ui/dist/semantic.min.js",
              "node_modules/d3-shape/build/d3-shape.min.js"
            ],
            "styles": [
              "src/styles.css",
              "node_modules/semantic-ui/dist/semantic.min.css",
              "node_modules/ng2-dnd/bundles/style.css"
            ],
            "assets": [
              "src/assets",
              "src/favicon.ico"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": []
          }
        }
      }
    },
    "ng-adf-e2e": {
      "root": "",
      "sourceRoot": "e2e",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "./protractor.conf.js",
            "devServerTarget": "ng-adf:serve"
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "e2e/tsconfig.e2e.json"
            ],
            "exclude": []
          }
        }
      }
    }
  },
  "defaultProject": "ng-adf",
  "cli": {
    "warnings": {
      "typescriptMismatch": false
    }
  },
  "schematics": {
    "@schematics/angular:component": {
      "prefix": "app",
      "styleext": "css"
    },
    "@schematics/angular:directive": {
      "prefix": "app"
    }
  }
}

================================================
FILE: build.sh
================================================
#!/bin/bash

#ng config -g cli.warnings.versionMismatch false

npm install

ng build --prod --aot



================================================
FILE: e2e/app.e2e-spec.ts
================================================
import { NgADFPage } from './app.po';

describe('ng-adf App', () => {
  let page: NgADFPage;

  beforeEach(() => {
    page = new NgADFPage();
  });

  it('should display message saying app works', () => {
    page.navigateTo();
    expect(page.getParagraphText()).toEqual('app works!');
  });
});


================================================
FILE: e2e/app.po.ts
================================================
import { browser, element, by } from 'protractor';

export class NgADFPage {
  navigateTo() {
    return browser.get('/');
  }

  getParagraphText() {
    return element(by.css('app-root h1')).getText();
  }
}


================================================
FILE: e2e/tsconfig.e2e.json
================================================
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/e2e",
    "module": "commonjs",
    "target": "es5",
    "types":[
      "jasmine",
      "node"
    ]
  }
}


================================================
FILE: karma.conf.js
================================================
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client:{
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    files: [
      
    ],
    preprocessors: {
      
    },
    mime: {
      'text/x-typescript': ['ts','tsx']
    },
    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
      fixWebpackSourcePaths: true
    },
    
    reporters: config.angularCli && config.angularCli.codeCoverage
              ? ['progress', 'coverage-istanbul']
              : ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};


================================================
FILE: ngx-dynamic-dashboard-framework.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/dist" />
      <excludeFolder url="file://$MODULE_DIR$/tmp" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>

================================================
FILE: package.json
================================================
{
  "name": "ng-dadf",
  "version": "0.0.0",
  "license": "MIT",
  "ngPackage": {
    "lib": {
      "entryFile": "public_api.ts"
    }
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "7.2.3",
    "@angular/cdk": "^7.3.1",
    "@angular/common": "7.2.3",
    "@angular/compiler": "^7.2.3",
    "@angular/core": "^7.2.3",
    "@angular/forms": "7.2.3",
    "@angular/http": "7.2.3",
    "@angular/material": "^7.3.1",
    "@angular/platform-browser": "7.2.3",
    "@angular/platform-browser-dynamic": "7.2.3",
    "@angular/router": "7.2.3",
    "@swimlane/ngx-charts": "10.0.0",
    "core-js": "^2.5.7",
    "d3": "^5.7.0",
    "d3-shape": "^1.2.2",
    "jquery": "^3.3.1",
    "material-design-icons": "^3.0.1",
    "ng2-cookies": "1.0.12",
    "ng2-dnd": "^5.0.2",
    "npm": "^6.4.1",
    "reflect-metadata": "0.1.12",
    "rxjs": "^6.4.0",
    "semantic-ui": "^2.4.2",
    "socket.io-client": "^2.1.1",
    "sockjs-client": "^1.3.0",
    "stompjs": "^2.3.3",
    "tslib": "^1.9.0",
    "zone.js": "^0.8.29"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.13.0",
    "@angular/cli": "^7.3.0",
    "@angular/compiler-cli": "^7.2.3",
    "@types/jasmine": "2.8.9",
    "@types/node": "~10.12.2",
    "codelyzer": "~4.5.0",
    "jasmine-core": "~3.3.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "^3.1.1",
    "karma-chrome-launcher": "~2.2.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^2.0.4",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "^5.4.1",
    "ts-node": "~7.0.1",
    "tslint": "^5.11.0",
    "typescript": "^3.2.4"
  }
}


================================================
FILE: protractor.conf.js
================================================
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {
  allScriptsTimeout: 11000,
  specs: [
    './e2e/**/*.e2e-spec.ts'
  ],
  capabilities: {
    'browserName': 'chrome'
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'jasmine',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    print: function() {}
  },
  beforeLaunch: function() {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },
  onPrepare() {
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
  }
};


================================================
FILE: semantic.json
================================================
{
  "base": "semantic/",
  "paths": {
    "source": {
      "config": "src/theme.config",
      "definitions": "src/definitions/",
      "site": "src/site/",
      "themes": "src/themes/"
    },
    "output": {
      "packaged": "dist/",
      "uncompressed": "dist/components/",
      "compressed": "dist/components/",
      "themes": "dist/themes/"
    },
    "clean": "dist/"
  },
  "permission": false,
  "autoInstall": true,
  "rtl": false,
  "version": "2.4.2"
}

================================================
FILE: src/app/about/about-component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    AfterViewInit, Component, Output, EventEmitter, Input
} from '@angular/core';

import {environment} from '../../environments/environment';
import {AboutService} from "./service";


/**
 * Message Modal - clasable modal with message
 *
 * Selector message-modal
 *
 * Methods
 *      popMessageModal - display a message modal for a sepcified duration
 *      showMessageModal - show the message modal
 *      hideMessageModal - hide the message modal
 */
@Component({
    selector: 'app-about-modal',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css']

})
export class AboutComponent implements AfterViewInit {

    modalHeader = 'About';
    apiVersion: string;

    messageModal: any;
    env: any;

    constructor(private _aboutService: AboutService) {

        this.env = environment;
    }


    ngAfterViewInit() {

        this.getVersion();

    }

    getVersion() {

        this._aboutService.getAPIVersion().subscribe(data => {

            this.apiVersion = data['version'];

        });

    }


}


================================================
FILE: src/app/about/about.module.ts
================================================
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {AboutComponent} from './about-component';
import {AboutService} from "./service";

@NgModule({
    imports: [
        CommonModule
    ],
    declarations: [AboutComponent],
    exports: [AboutComponent],
    providers: [AboutService]
})
export class AboutModule {
}


================================================
FILE: src/app/about/model.ts
================================================
/**
 * Created by jayhamilton on 1/31/17.
 */
export const boardLayouts = [

    {
        id: 0,
        boardInstanceId: 0,
        title: 'one-narrow',
        checked: false,
        structure: '8',
        rows: [{
            columns: [
                {
                    styleClass: 'eight wide',

                }]
        }]
    },
    {
        id: 1,
        boardInstanceId: 1,
        title: 'single',
        checked: false,
        structure: '14',
        rows: [{
            columns: [
                {
                    styleClass: 'fourteen wide',

                }]
        }]
    },
    {
        id: 2,
        boardId: 2,
        title: 'narrow-right',
        checked: false,
        structure: '10-6',
        rows: [{
            columns: [
                {
                    styleClass: 'ten wide',

                },
                {
                    styleClass: 'six wide',

                }]
        }]
    },
    {
        id: 3,
        boardInstanceId: 3,
        title: 'wide-center',
        checked: false,
        structure: '4-8-4',
        rows: [{
            columns: [
                {
                    styleClass: 'four wide',

                },
                {
                    styleClass: 'eight wide',

                },
                {
                    styleClass: 'four wide',

                }]
        }]
    },
    {
        id: 4,
        boardInstanceId: 4,
        title: 'narrow-left',
        checked: false,
        structure: '4-12',
        rows: [{
            columns: [
                {
                    styleClass: 'four wide',

                },
                {
                    styleClass: 'twelve wide',

                }]
        }]
    },
    {
        id: 5,
        boardInstanceId: 5,
        title: 'two-even',
        checked: true,
        structure: '6-6',
        rows: [{
            columns: [
                {
                    styleClass: 'six wide',

                },
                {
                    styleClass: 'six wide',

                }]
        }]
    },
    {
        id: 6,
        boardInstanceId: 6,
        title: 'three-even',
        checked: false,
        structure: '5-5-5',
        rows: [{
            columns: [
                {
                    styleClass: 'five wide',

                },
                {
                    styleClass: 'five wide',

                },
                {
                    styleClass: 'five wide',

                }
            ]
        }]
    },
    {
        id: 7,
        boardInstanceId: 7,
        title: 'wide-top',
        checked: false,
        structure: '16/8-8',
        rows: [
            {
                columns: [
                    {
                        styleClass: 'sixteen wide'
                    }
                ]
            },
            {
                columns: [
                    {
                        styleClass: 'eight wide'
                    },
                    {
                        styleClass: 'eight wide'
                    }
                ]
            }
        ]
    },
    {
        id: 8,
        boardInstanceId: 8,
        title: 'ngadmin',
        checked: false,
        structure: '4-4-4-4/8-4-4',
        rows: [
            {
                columns: [
                    {
                        styleClass: 'four wide'
                    },
                    {
                        styleClass: 'four wide'
                    },
                    {
                        styleClass: 'four wide'
                    },
                    {
                        styleClass: 'four wide'
                    }
                ]
            },
            {
                columns: [
                    {
                        styleClass: 'eight wide'
                    },
                    {
                        styleClass: 'four wide'
                    },
                    {
                        styleClass: 'four wide'
                    }
                ]
            }
        ]
    },
    {
        id: 9,
        boardInstanceId: 9,
        title: 'google-layout',
        checked: false,
        structure: '3-6-3',
        rows: [
            {
                columns: [
                    {
                        styleClass: 'three wide'
                    },
                    {
                        styleClass: 'six wide'
                    },
                    {
                        styleClass: 'three wide'
                    }
                ]
            }
        ]
    }

];


================================================
FILE: src/app/about/service.ts
================================================
import {Injectable} from "@angular/core";
import {environment} from "../../environments/environment";
import {HttpClient} from "@angular/common/http";
import {RuntimeService} from "../services/runtime.service";
import {catchError} from "rxjs/operators";

@Injectable()
export class AboutService {

    env: any;

    constructor(private _http: HttpClient) {
        this.env = environment;
    }


    getAPIVersion() {

        let url: string;

        if (this.env.production == true) {

            url = '/version';

        } else {

            url = '/assets/api/version-model.json';

        }

        return this._http.get(url)
            .pipe(
                catchError(RuntimeService.handleError)
            );
    }

}

================================================
FILE: src/app/about/styles.css
================================================

ul{
    text-align: center;
}
h2, h3, h4{
    color:white !important;
    font-weight: normal !important;
}


================================================
FILE: src/app/about/view.html
================================================
<br>

<div style="text-align: center">
    <h2>{{modalHeader}}</h2>
</div>

<hr>

<br>
<br>

<div style="text-align: center">
    <h4>{{env.productName}}</h4>
</div>


<div style="text-align: center">
    <h4>Version {{env.productVersion}}</h4>
</div>

<br>
<br>

<div style="text-align: center">
    <h4>API Version</h4>
</div>

<div style="text-align: center">
    <h4>{{apiVersion}}</h4>
</div>





      

================================================
FILE: src/app/add-gadget/add-gadget-component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    ViewChild, ElementRef, AfterViewInit, Component, Output, EventEmitter
} from '@angular/core';

import {
    style, trigger, animate, transition
} from '@angular/animations';

import {AddGadgetService} from './service';
import {Facet} from '../facet/facet-model';
import {FacetTagProcessor} from '../facet/facet-tag-processor';

declare var jQuery: any;

/**
 * Message Modal - clasable modal with message
 *
 * Selector message-modal
 *
 * Methods
 *      popMessageModal - display a message modal for a sepcified duration
 *      showMessageModal - show the message modal
 *      hideMessageModal - hide the message modal
 */
@Component({
    selector: 'app-add-gadget-modal',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css'],
    animations: [
        trigger(
            'showHideAnimation',
            [
                transition(':enter', [   // :enter is alias to 'void => *'
                    style({opacity: 0}),
                    animate(750, style({opacity: 1}))
                ]),
                transition(':leave', [   // :leave is alias to '* => void'
                    animate(750, style({opacity: 0}))
                ])
            ])
    ]

})
export class AddGadgetComponent implements AfterViewInit {

    @Output() addGadgetEvent: EventEmitter<any> = new EventEmitter();

    gadgetObjectList: any[] = [];
    gadgetObjectTitleList: string[] = [];
    placeHolderText = 'Begin typing gadget name';
    layoutColumnOneWidth = 'six';
    layoutColumnTwoWidth = 'ten';
    listHeader= 'Gadgets';
    facetTags: Array<Facet>;

    color = 'white';

    typeAheadIsInMenu = false;

    modalicon: string;
    modalheader: string;
    modalmessage: string;

    @ViewChild('messagemodal_tag') messagemodalRef: ElementRef;

    messageModal: any;

    constructor(private _addGadgetService: AddGadgetService) {

        this.getObjectList();
    }

    actionHandler(actionItem, actionName) {
        this.addGadgetEvent.emit(actionItem);
        this.hideMessageModal();

    }


    showMessageModal(icon: string, header: string, message: string) {
        this.modalicon = icon;
        this.modalheader = header;
        this.modalmessage = message;
        this.messageModal.modal('show');

    }

    showComponentLibraryModal(header: string) {

        this.modalheader = header;
        this.messageModal.modal('show');
    }

    hideMessageModal() {
        this.modalicon = '';
        this.modalheader = '';
        this.modalmessage = '';
        this.messageModal.modal('hide');
    }

    ngAfterViewInit() {
        this.messageModal = jQuery(this.messagemodalRef.nativeElement);
    }

    getObjectList() {

        this._addGadgetService.getGadgetLibrary().subscribe(data => {
            this.gadgetObjectList.length = 0;
            const me = this;
            data.library.forEach(function (item) {

                    me.gadgetObjectList.push(item);
                    me.gadgetObjectTitleList.push(item.name);
            });
            const facetTagProcess = new FacetTagProcessor(this.gadgetObjectList);
            this.facetTags = facetTagProcess.getFacetTags();
        });

    }
}


================================================
FILE: src/app/add-gadget/add-gadget.module.ts
================================================
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {AddGadgetComponent} from './add-gadget-component';
import {AddGadgetService} from './service';
import {HttpClientModule} from '@angular/common/http';
import {DataListModule} from '../datalist/data-list.module';
import {MatButtonModule} from '@angular/material';

@NgModule({
    imports: [
        CommonModule,
        DataListModule,
        HttpClientModule,
        MatButtonModule,
    ],
    declarations: [
        AddGadgetComponent
    ],
    providers: [
        AddGadgetService
    ],
    exports: [
        AddGadgetComponent
    ]
})
export class AddGadgetModule {
}



================================================
FILE: src/app/add-gadget/gadget-factory.ts
================================================
import {CPUGadgetComponent} from '../gadgets/cpu/cpu-gadget.component';
import {MemoryGadgetComponent} from '../gadgets/memory/memory-gadget.component';
import {PropertyListGadgetComponent} from '../gadgets/property-list/property-list-gadget.component';
import {DiskGadgetComponent} from '../gadgets/disk/disk-gadget.component';
import {ServiceListGadgetComponent} from '../gadgets/service-list/service-list-gadget.component';
import {StatisticGadgetComponent} from '../gadgets/statistic/statistic-gadget.component';
import {TrendGadgetComponent} from '../gadgets/trend/trend-gadget.component';
import {NewsGadgetComponent} from '../gadgets/news/news-gadget.component';
import {JobAnalysisGadgetComponent} from '../gadgets/job-analysis/job-analysis-gadget.component';
import {TrendLineGadgetComponent} from '../gadgets/trend-line/trend-line-gadget.component';
import {EdgeServiceListGadgetComponent} from '../gadgets/edge-service-list/edge-service-list-gadget.component';
import {CPUMGadgetComponent} from '../gadgets/cpum/cpum-gadget.component';
import {PortConnectionGadgetComponent} from '../gadgets/port-connection/port-connection-gadget.component';
import {StorageObjectListComponent} from '../gadgets/storage-object-list/storage-object-list.component';
import {DonutGadgetComponent} from '../gadgets/donut/donut-gadget.component';
import {TodoGadgetComponent} from '../gadgets/todo/todo-gadget.component';
import {BubbleGadgetComponent} from "../gadgets/bubble/bubble-gadget.component";
import {BarChartGadgetComponent} from "../gadgets/barchart/barchart-gadget.component";
import {PieChartGadgetComponent} from "../gadgets/piechart/piechart-gadget.component";

/**
 * Created by jayhamilton on 6/30/17.
 */

export class GadgetFactory {


    /**
     * todo - return new instances  instead of the same instance. This requires the creation of new configuration options.
     * @param gadgetType
     * @returns {any}
     */

    static getComponentType(gadgetType): any {

        switch (gadgetType) {

            case 'DonutGadgetComponent':
                return DonutGadgetComponent;
            case 'CPUGadgetComponent':
                return CPUGadgetComponent;
            case 'MemoryGadgetComponent':
                return MemoryGadgetComponent;
            case 'PropertyListGadgetComponent':
                return PropertyListGadgetComponent;
            case 'DiskGadgetComponent':
                return DiskGadgetComponent;
            case 'ServiceListGadgetComponent':
                return ServiceListGadgetComponent;
            case 'StatisticGadgetComponent':
                return StatisticGadgetComponent;
            case 'TrendGadgetComponent':
                return TrendGadgetComponent;
            case 'NewsGadgetComponent':
                return NewsGadgetComponent;
            case'JobAnalysisGadgetComponent':
                return JobAnalysisGadgetComponent;
            case'TrendLineGadgetComponent':
                return TrendLineGadgetComponent;
            case'EdgeServiceListGadgetComponent':
                return EdgeServiceListGadgetComponent;
            case 'CPUMGadgetComponent':
                return CPUMGadgetComponent;
            case 'PortConnectionGadgetComponent':
                return PortConnectionGadgetComponent;
            case 'StorageObjectListComponent':
                return StorageObjectListComponent;
            case 'TodoGadgetComponent': // todo gadget
                return TodoGadgetComponent;
            case 'BubbleGadgetComponent': // todo gadget
                return BubbleGadgetComponent;
            case 'BarChartGadgetComponent': // todo gadget
                return BarChartGadgetComponent;
            case 'PieChartGadgetComponent': // todo gadget
                return PieChartGadgetComponent;
            default:
                return null;// todo add default gadget that would be displayed. Useful for troubleshooting new gadget dev

        }
    }
}


================================================
FILE: src/app/add-gadget/gadgetLibraryResponse.ts
================================================
interface GadgetLibraryResponse {
    library: any[];
}


================================================
FILE: src/app/add-gadget/service.ts
================================================
/**
 * Created by jayhamilton on 2/7/17.
 */
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../environments/environment'

@Injectable()
export class AddGadgetService {

    env: any;

    constructor(private _http: HttpClient) {
        this.env = environment;
    }

    getGadgetLibrary() {
        let gadgetLibraryJson = '';

        if (this.env.production == true) {
            gadgetLibraryJson = 'gadget-library-model-prod.json';

        } else {
            gadgetLibraryJson = 'gadget-library-model.json';
        }
        return this._http.get<GadgetLibraryResponse>('/assets/api/' + gadgetLibraryJson);
    }

}


================================================
FILE: src/app/add-gadget/styles.css
================================================
.modal{
    background-color:#f7f7f7;

}


================================================
FILE: src/app/add-gadget/view.html
================================================
<div class="ui long modal" #messagemodal_tag>
    <div class="header">
        <h2>{{modalheader}}</h2>
    </div>

    <app-data-list

            [objectList]="gadgetObjectList"
            [objectTitleList]="gadgetObjectTitleList"
            [placeHolderText]="placeHolderText"
            [typeAheadIsInMenu]="typeAheadIsInMenu"
            [layoutColumnOneWidth]="layoutColumnOneWidth"
            [layoutColumnTwoWidth]="layoutColumnTwoWidth"
            [listHeader]="listHeader"
            [facetTags]="facetTags">

            <ng-template  let-item="$implicit">

                <div [@showHideAnimation] class="ui segment" style="background-color:white;">
                    <div class="ui large middle aligned divided list">
                        <div class="item">
                            <div class="right floated content">
                                <!-- todo : if there are more than one action display a button with
                                vertical ellipse and implement onHover to show all action buttons
                                -->
                                <a *ngIf="item.actions.length == 1"
                                   mat-raised-button
                                   routerLink="."
                                   (click)="actionHandler(item, item.actions[0].name)" color="primary">
                                    {{item.actions[0].name}}
                                </a>
                            </div>
                            <img class="ui image" src="{{item.icon}}">
                            <div class="content">
                                <div class="header">{{item.name}}</div>
                                {{item.description}}
                            </div>
                        </div>
                    </div>
                    <div class="ui bottom attached">
                        <button *ngFor="let tag of item.tags" class="ui basic gray compact button">{{tag.name}}
                        </button>
                    </div>
                </div>

            </ng-template>

        </app-data-list>

    <div class="actions">
        <div class="ui approve button">Close</div>
    </div>
</div>
      

================================================
FILE: src/app/api-token/api-token.service.ts
================================================
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';

@Injectable()
export class APITokenService {

    private apiToken: string;
    private credentials = {url: '', user: '', password: ''};

    constructor(private _http: HttpClient) {
    }

    public getAPITokenForCredentials(_credentials: any) {
        let headers = new HttpHeaders();

        this.credentials = _credentials;

        headers = headers.append('Content-Type', 'application/json');
        headers = headers.append('Authorization', 'Basic ' + B64encode(this.credentials.user + ':' + this.credentials.password));

        return this._http.post(this.credentials.url, '', {headers: headers});

    }

    public setAPIToken(apiToken: string) {
        this.apiToken = apiToken;
    }

    public getAPIToken() {
        return this.apiToken;
    }
}

function B64encode(data: string) {

    var c1, c2, c3;
    var Base64 = {
        _keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', encode: function (e) {
            var t = '';
            var n, r, i, s, o, u, a;
            var f = 0;
            e = Base64._utf8_encode(e);
            while (f < e.length) {
                n = e.charCodeAt(f++);
                r = e.charCodeAt(f++);
                i = e.charCodeAt(f++);
                s = n >> 2;
                o = (n & 3) << 4 | r >> 4;
                u = (r & 15) << 2 | i >> 6;
                a = i & 63;
                if (isNaN(r)) {
                    u = a = 64
                } else if (isNaN(i)) {
                    a = 64
                }
                t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
            }
            return t
        }, decode: function (e) {
            var t = '';
            var n, r, i;
            var s, o, u, a;
            var f = 0;
            e = e.replace(/[^A-Za-z0-9\+\/\=]/g, '');
            while (f < e.length) {
                s = this._keyStr.indexOf(e.charAt(f++));
                o = this._keyStr.indexOf(e.charAt(f++));
                u = this._keyStr.indexOf(e.charAt(f++));
                a = this._keyStr.indexOf(e.charAt(f++));
                n = s << 2 | o >> 4;
                r = (o & 15) << 4 | u >> 2;
                i = (u & 3) << 6 | a;
                t = t + String.fromCharCode(n);
                if (u != 64) {
                    t = t + String.fromCharCode(r);
                }
                if (a != 64) {
                    t = t + String.fromCharCode(i);
                }
            }
            t = Base64._utf8_decode(t);
            return t;
        }, _utf8_encode: function (e) {
            e = e.replace(/\r\n/g, '\n');
            var t = '';
            for (var n = 0; n < e.length; n++) {
                var r = e.charCodeAt(n);
                if (r < 128) {
                    t += String.fromCharCode(r);
                } else if (r > 127 && r < 2048) {
                    t += String.fromCharCode(r >> 6 | 192);
                    t += String.fromCharCode(r & 63 | 128);
                } else {
                    t += String.fromCharCode(r >> 12 | 224);
                    t += String.fromCharCode(r >> 6 & 63 | 128);
                    t += String.fromCharCode(r & 63 | 128);
                }
            }
            return t;
        }, _utf8_decode: function (e) {
            var t = '';
            var n = 0;
            var r = c1 = c2 = 0;
            while (n < e.length) {
                r = e.charCodeAt(n);
                if (r < 128) {
                    t += String.fromCharCode(r);
                    n++
                } else if (r > 191 && r < 224) {
                    c2 = e.charCodeAt(n + 1);
                    t += String.fromCharCode((r & 31) << 6 | c2 & 63);
                    n += 2
                } else {
                    c2 = e.charCodeAt(n + 1);
                    c3 = e.charCodeAt(n + 2);
                    t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
                    n += 3
                }
            }
            return t;
        }
    }

    return Base64.encode(data);

}

================================================
FILE: src/app/app.component.css
================================================


================================================
FILE: src/app/app.component.html
================================================
<!--
The grid is primarily controlled by MenuService Events. You can change the behavior by
changing the MenuComponent and have it call methods within the Grid component via Output Events within the Menu component or by using the @ViewChild approach.

In the current code, the MenuService is shared by the GridComponent and MenuComponent. The MenuComponent relays events from the various components that make up the MenuComponent. The GridComponent listens for those events via an Observable. The GridComponent will also raise/emit an event that will be picked up by the MenuComponent via the MenuService through an Observable as well.
-->
<app-menu-component></app-menu-component>
<router-outlet></router-outlet>


================================================
FILE: src/app/app.component.spec.ts
================================================
import { TestBed, async } from '@angular/core/testing';
import 'rxjs/Rx';

import { AppComponent } from './app.component';
import {RoutingModule} from './routing.module';


describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
        imports: [
            RoutingModule
        ]
    }).compileComponents();
  }));

  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));

  /*
  it(`should have as title 'app works!'`, async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app works!');
  }));

  it('should render title in a h1 tag', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('app works!');
  }));

  */
});


================================================
FILE: src/app/app.component.ts
================================================
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';
}


================================================
FILE: src/app/app.module.ts
================================================
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {AppComponent} from './app.component';
import {RoutingModule} from './routing.module';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {HttpClientJsonpModule, HttpClientModule} from '@angular/common/http';
import {DetailModule} from './detail/detail.module';
import {MenuModule} from './menu/menu.module';
import {BoardModule} from './board/board.module';

@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        RoutingModule,
        FormsModule,
        HttpClientModule,
        BoardModule,
        MenuModule,
        DetailModule,
        HttpClientJsonpModule
    ],
    declarations: [
        AppComponent,
    ],

    bootstrap: [AppComponent]
})
export class AppModule {
}


================================================
FILE: src/app/board/board.component.ts
================================================
import { Component} from '@angular/core';
/**a
 * Board component
 *
 */
@Component({
    moduleId: module.id,
    templateUrl: './view.html'

})
export class BoardComponent {

}


================================================
FILE: src/app/board/board.module.ts
================================================
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {GridModule} from '../grid/grid.module';
import {BoardComponent} from './board.component';
import {CPUMGadgetComponent} from '../gadgets/cpum/cpum-gadget.component';
import {EdgeServiceListGadgetComponent} from '../gadgets/edge-service-list/edge-service-list-gadget.component';
import {TrendLineGadgetComponent} from '../gadgets/trend-line/trend-line-gadget.component';
import {JobAnalysisGadgetComponent} from '../gadgets/job-analysis/job-analysis-gadget.component';
import {NewsGadgetComponent} from '../gadgets/news/news-gadget.component';
import {TrendGadgetComponent} from '../gadgets/trend/trend-gadget.component';
import {StatisticGadgetComponent} from '../gadgets/statistic/statistic-gadget.component';
import {DiskGadgetComponent} from '../gadgets/disk/disk-gadget.component';
import {PropertyListGadgetComponent} from '../gadgets/property-list/property-list-gadget.component';
import {ServiceListGadgetComponent} from '../gadgets/service-list/service-list-gadget.component';
import {CPUGadgetComponent} from '../gadgets/cpu/cpu-gadget.component';
import {MemoryGadgetComponent} from '../gadgets/memory/memory-gadget.component';
import {PortConnectionGadgetComponent} from '../gadgets/port-connection/port-connection-gadget.component';
import {StorageObjectListComponent} from '../gadgets/storage-object-list/storage-object-list.component';
import {DonutGadgetComponent} from '../gadgets/donut/donut-gadget.component';
import {TodoGadgetComponent} from '../gadgets/todo/todo-gadget.component';  // todo gadget
import {BubbleGadgetComponent} from "../gadgets/bubble/bubble-gadget.component";
import {BarChartGadgetComponent} from "../gadgets/barchart/barchart-gadget.component";
import {PieChartGadgetComponent} from "../gadgets/piechart/piechart-gadget.component";

@NgModule({
    imports: [
        CommonModule,
        GridModule.withComponents([
            MemoryGadgetComponent,
            CPUGadgetComponent,
            ServiceListGadgetComponent,
            PropertyListGadgetComponent,
            DiskGadgetComponent,
            StatisticGadgetComponent,
            TrendGadgetComponent,
            NewsGadgetComponent,
            JobAnalysisGadgetComponent,
            TrendLineGadgetComponent,
            EdgeServiceListGadgetComponent,
            CPUMGadgetComponent,
            PortConnectionGadgetComponent,
            StorageObjectListComponent,
            DonutGadgetComponent,
            TodoGadgetComponent  // todo gadget
            , BubbleGadgetComponent,
            BarChartGadgetComponent,
            PieChartGadgetComponent

        ]),
    ],
    providers: [],
    declarations: [
        BoardComponent
    ]
})
export class BoardModule {
}


================================================
FILE: src/app/board/view.html
================================================
<!--

The grid is primarily controlled by MenuService Events. You can change the behavior by
changing the MenuComponent and have it call methods within the Grid component via Output Events within the Menu component or by using the @ViewChild approach.

In the current code, the MenuService is shared by the GridComponent and MenuComponent. The MenuComponent relays events from the various components that make up the MenuComponent. The GridComponent listens for those events via an Observable. The GridComponent will also raise/emit an event that will be picked up by the MenuComponent via the MenuService through an Observable as well.

-->
<app-grid-component></app-grid-component>



================================================
FILE: src/app/configuration/configuration-component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    ViewChild, ElementRef, AfterViewInit, Component, Output, EventEmitter, Input
} from '@angular/core';
import {
     style, state, trigger, animate, transition
} from '@angular/animations';

import {tabsModel} from './tabs.model';
import {environment} from '../../environments/environment'


declare var jQuery: any;

/**
 * Message Modal - clasable modal with message
 *
 * Selector message-modal
 *
 * Methods
 *      popMessageModal - display a message modal for a sepcified duration
 *      showMessageModal - show the message modal
 *      hideMessageModal - hide the message modal
 */
@Component({
    selector: 'app-configuration-modal',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css'],
    animations: [

        trigger('contentSwitch', [
            state('inactive', style({
                opacity: 0
            })),
            state('active', style({
                opacity: 1
            })),
            transition('inactive => active', animate('750ms ease-in')),
            transition('active => inactive', animate('750ms ease-out'))
        ])
    ]


})
export class ConfigurationComponent implements AfterViewInit {

    @Output() dashboardCreateEvent: EventEmitter<any> = new EventEmitter();
    @Output() dashboardEditEvent: EventEmitter<any> = new EventEmitter();
    @Output() dashboardDeleteEvent: EventEmitter<any> = new EventEmitter();
    @Input() dashboardList: any [];


    newDashboardItem = '';


    modalicon: string;
    modalheader: string;
    modalconfig: string;
    env:any;

    @ViewChild('boardconfigmodal_tag') boardconfigmodalaRef: ElementRef;
    configModal: any;
    currentTab: string;
    tabsModel: any[];

    constructor() {

        Object.assign(this, {tabsModel});
        this.setCurrentTab(0);
        this.env = environment;

    }


    showConfigurationModal(header: string) {
        this.modalheader = header;
        this.configModal.modal('show');
    }

    hideMessageModal() {
        this.modalicon = '';
        this.modalheader = '';
        this.modalconfig = '';
        this.configModal.modal('hide');
    }

    createBoard(name: string) {
        if (name !==  '') {
            this.dashboardCreateEvent.emit(name);
            this.newDashboardItem = '';
        }
        console.log("Creating new board event from configuration component: " + name);
    }

    editBoard(name: string) {
        this.dashboardEditEvent.emit(name);
    }

    deleteBoard(name: string) {
        this.dashboardDeleteEvent.emit(name);
    }


    ngAfterViewInit() {
        this.configModal = jQuery(this.boardconfigmodalaRef.nativeElement);
        this.configModal.modal('hide');
    }

    setCurrentTab(tab_index) {
        this.currentTab = this.tabsModel[tab_index].displayName;
    }

}


================================================
FILE: src/app/configuration/configuration.module.ts
================================================
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {EndpointConfigurationTabComponent} from './tab-endpoint/endpoint-configuration-tab.component';
import {EndPointDetailComponent} from './tab-endpoint/endpointDetail.component';
import {EndPointService} from './tab-endpoint/endpoint.service';
import {BoardsConfigurationTabComponent} from './tab-boards/boards-configuration-tab.component';
import {DndModule} from 'ng2-dnd';
import {
    MatButtonModule,
    MatCheckboxModule,
    MatIconModule,
    MatInputModule,
    MatOptionModule,
    MatSelectModule,
    MatSlideToggleModule,
    MatChipsModule
} from '@angular/material';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {AIConfigurationTabComponent} from './tab-artificial-intelligence/ai-configuration-tab.component';
import {OptionsConfigurationTabComponent} from "./tab-options/options-configuration-tab.component";
import {ConfigurationComponent} from "./configuration-component";
import {OptionsService} from "./tab-options/service";

@NgModule({
    imports: [
        CommonModule,
        DndModule.forRoot(),
        MatButtonModule,
        MatIconModule,
        MatCheckboxModule,
        MatInputModule,
        MatSelectModule,
        MatOptionModule,
        FormsModule,
        ReactiveFormsModule,
        MatSlideToggleModule,
        MatChipsModule
    ],
    declarations: [
        BoardsConfigurationTabComponent,
        EndpointConfigurationTabComponent,
        EndPointDetailComponent,
        AIConfigurationTabComponent,
        OptionsConfigurationTabComponent,
        ConfigurationComponent
    ],
    providers: [

        EndPointService,
        OptionsService
    ],
    exports: [
        BoardsConfigurationTabComponent,
        EndpointConfigurationTabComponent,
        EndPointDetailComponent,
        OptionsConfigurationTabComponent,
        ConfigurationComponent
    ]
})
export class ConfigurationModule {
}


================================================
FILE: src/app/configuration/styles.css
================================================

.ui.tabular.menu .active.item {
    border-top: 3px solid #3f51b5 !important;
}

.ui.attached.segment {
    margin: 0;
    width: 100%;
}

================================================
FILE: src/app/configuration/tab-artificial-intelligence/ai-configuration-tab.component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    Component
} from '@angular/core';

import {environment} from '../../../environments/environment';


@Component({
    selector: 'app-ai-config-tab',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css']
})
export class AIConfigurationTabComponent {

    token;
    ibmwatsonuid;
    ibmwatsonpwd;
    ibmwatsoncid;

    ai_engines = [
        {value: 'watson', viewValue: 'Watson'},
        {value: 'witai', viewValue: 'WitAI'},
        {value: ' ', viewValue: ' '}
    ];
    selectedAIEngineValue: string;
    env: any;

    constructor() {
        /**
         * todo - get this information from a backend store
         * **/

        this.env = environment;

        if (this.env.experimental) {

            this.token = localStorage.getItem('Wit.aiToken');
            this.ibmwatsonuid = localStorage.getItem('ibmwatsonuid');
            this.ibmwatsonpwd = localStorage.getItem('ibmwatsonpwd');
            this.ibmwatsoncid = localStorage.getItem('ibmwatsoncid');
            this.selectedAIEngineValue = localStorage.getItem('ai_engine');
        }
    }

    selectChange(selectControl) {

        console.log(selectControl.value);
        this.selectedAIEngineValue = selectControl.value;
        localStorage.setItem('ai_engine', selectControl.value);

    }

    save() {

        /**
         * todo - get this information from a backend store
         * **/
        if (!environment.production) {
            localStorage.setItem('Wit.aiToken', this.token);
            localStorage.setItem('ibmwatsonuid', this.ibmwatsonuid);
            localStorage.setItem('ibmwatsonpwd', this.ibmwatsonpwd);
            localStorage.setItem('ibmwatsoncid', this.ibmwatsoncid);
        }
    }

}


================================================
FILE: src/app/configuration/tab-artificial-intelligence/styles.css
================================================
.ui.menu{
    margin-bottom: .1em !important;
}


.ui.secondary.pointing.menu .active.item {
    color:  #3f51b5 !important;
    font-weight: 500 !important;
    border-color: #3f51b5 !important;
    border-width: medium !important;
    font-family: 'Roboto', sans-serif !important;
    font-size: 1.4em;
}

.ui.secondary.pointing.menu .item {
    color: rgba(0, 0, 0, 0.3) !important;
    font-weight: 500 !important;
    font-family: 'Roboto', sans-serif !important;
    font-size: 1.4em;
}

.ui.secondary.pointing.menu {
    border-bottom: none !important;
}

.ui.tabular.menu .active.item {

    border-top-width: 3px !important;
    border-top-color: #3f51b5 !important;

}

input {
    padding: 5px;
    font-weight: 300 !important;
    font-family: 'Roboto', sans-serif !important;
    font-size: 1.1em;
    outline: none !important;
}

#content {
    background: #3f51b5;
    width: 120px;
    margin-left: auto;
    margin-right: auto;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

label {
    font-family: 'Roboto', sans-serif;
    font-size: 1.3em !important;
    color: #4a4d50 !important;
}

label.endpoint {
    font-size: 1em !important;
    line-height: 1.5em !important;
}

td.detail {

    background-color: white !important;

}

.c-col {

    background-color: #ddebf5 !important;
    border: none !important;
    width: 5% !important;
    color: #788ca0 !important;

}

.ui.table thead th td {
    color: #788ca0 !important;
}


.ui.table {
    color: rgba(97, 97, 97, 0.68) !important
}

.inLine {
    display: inline-block;
    padding-left: 4px;
    padding-right: 4px;
}

.ui.tabular.menu + .attached:not(.top).segment, .ui.tabular.menu + .attached:not(.top).segment + .attached:not(.top).segment {
    border-bottom: none !important;
}

.example-full-width {
    width: 100%;
}

.grid-row {
    display: flex;
    align-items: center;
    justify-content: space-around;
}

================================================
FILE: src/app/configuration/tab-artificial-intelligence/view.html
================================================
<div *ngIf="env.boardConfiguration.ai == true" class="ui equal width fields centered grid container">

    <div class="row">
        <div class="field four wide column">
        </div>
        <div class="field eight wide column">
            <mat-form-field>
                <mat-select placeholder="Select an AI engine" (selectionChange)="selectChange($event)" [value]="selectedAIEngineValue">
                    <mat-option *ngFor="let ai_engine of ai_engines" [value]="ai_engine.value">
                        {{ ai_engine.viewValue }}
                    </mat-option>
                </mat-select>
            </mat-form-field>
        </div>
        <div class="field four wide column">
        </div>
    </div>

    <div *ngIf="selectedAIEngineValue === '' || selectedAIEngineValue === 'witai'">
        <div class="row">
            <div class="field four wide column">
            </div>
            <div class="field eight wide column">

                <h3>Wit.ai Access Token</h3>
                <mat-form-field class="example-full-width">
                    <input matInput type="password" placeholder='Enter the access token string from Wit.ai'
                           [(ngModel)]='token'>
                </mat-form-field>
                <a
                        mat-raised-button
                        routerLink="."
                        (click)="save()" color="primary">
                    Save
                </a>
            </div>
            <div class="field four wide column">
            </div>
        </div>
    </div>
    <div *ngIf="selectedAIEngineValue === 'watson'">
        <div class="row">
            <div class="field four wide column">
            </div>
            <div class="field eight wide column">

                <h3>IBM Watson User</h3>
                <mat-form-field class="example-full-width">
                    <input matInput type="text" placeholder='Enter the IBM Watson User Id'
                           [(ngModel)]='ibmwatsonuid'>
                </mat-form-field>
                <h3>IBM Watson Password</h3>
                <mat-form-field class="example-full-width">
                    <input matInput type="password" placeholder='Enter the IBM Watson Password'
                           [(ngModel)]='ibmwatsonpwd'>
                </mat-form-field>

                <h3>IBM Watson Classifier ID</h3>
                <mat-form-field class="example-full-width">
                    <input matInput type="text" placeholder='Enter the IBM Watson Classifier Id'
                           [(ngModel)]='ibmwatsoncid'>
                </mat-form-field>
                <a
                        mat-raised-button
                        routerLink="."
                        (click)="save()" color="primary">
                    Save
                </a>
            </div>
            <div class="field four wide column">
            </div>
        </div>
    </div>

</div>

<div *ngIf="env.boardConfiguration.ai == false">
    This feature is not ready yet!
</div>




================================================
FILE: src/app/configuration/tab-boards/boards-configuration-tab.component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    Component, Output, EventEmitter, Input
} from '@angular/core';

import {ConfigurationService} from '../../services/configuration.service';
import {environment} from '../../../environments/environment'

/**
 * Message Modal - clasable modal with message
 *
 * Selector message-modal
 *
 * Methods
 *      popMessageModal - display a message modal for a sepcified duration
 *      showMessageModal - show the message modal
 *      hideMessageModal - hide the message modal
 */
@Component({
    selector: 'app-boards-config-tab',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css']

})
export class BoardsConfigurationTabComponent {

    @Output() dashboardCreateEvent: EventEmitter<any> = new EventEmitter();
    @Output() dashboardEditEvent: EventEmitter<any> = new EventEmitter();
    @Output() dashboardDeleteEvent: EventEmitter<any> = new EventEmitter();
    @Input() dashboardList: any [];


    newDashboardItem = '';
    env: any;

    constructor(private _configurationService: ConfigurationService) {

        this.env = environment;

    }


    createBoard(name: string) {
        if (name !== '') {
            this.dashboardCreateEvent.emit(name);
            this.newDashboardItem = '';
        }
    }

    editBoard(name: string) {
        this.dashboardEditEvent.emit(name);
    }

    deleteBoard(name: string) {
        this.dashboardDeleteEvent.emit(name);
    }

}


================================================
FILE: src/app/configuration/tab-boards/styles.css
================================================


input {
    padding: 5px;
    font-weight: 300 !important;
    font-family: 'Roboto', sans-serif !important;
    font-size: 1.1em;
    outline: none !important;
}


label {
    font-family: 'Roboto', sans-serif;
    font-size: 1.3em !important;
    color: #4a4d50 !important;
}

label.endpoint {
    font-size: 1em !important;
    line-height: 1.5em !important;
}

td.detail {

    background-color: white !important;

}

.index-column {

    background-color: #ddebf5 !important;
    border: none !important;
    width: 5% !important;
    color: #788ca0 !important;

}

.ui.table thead th td {
    color: #788ca0 !important;
}

.ui.table {
    color: rgba(97, 97, 97, 0.68) !important
}

.inLine {
    display: inline-block;
    padding-left: 4px;
    padding-right: 4px;
}


.example-full-width {
    width: 100%;
}

.grid-row {
    display: flex;
    align-items: center;
    justify-content: space-around;
}

================================================
FILE: src/app/configuration/tab-boards/view.html
================================================
<table class="ui padded table" dnd-sortable-container [sortableData]="dashboardList">
    <thead>
    <th class="index-column">#</th>
    <th>name</th>
    <th></th>
    </thead>
    <tr class="ui basic segment" *ngFor="let board of dashboardList; let i = index" dnd-sortable
        [sortableIndex]="i">
        <td class="index-column">{{i + 1}}</td>
        <td>{{board}}</td>
        <td style="text-align:right">
            <a mat-mini-fab routerLink="." (click)="deleteBoard(board)">
                <mat-icon>clear</mat-icon>
            </a>
        </td>
    </tr>
</table>

<div class="ui basic segment">

    <div class="grid-row">
        <mat-form-field class="example-full-width">
            <input [(ngModel)]="newDashboardItem" matInput placeholder="Enter Dashboard Name">
        </mat-form-field>

        <a mat-mini-fab routerLink="." color='primary' (click)="createBoard(newDashboardItem)">
            <mat-icon>add</mat-icon>
        </a>
    </div>

</div>

================================================
FILE: src/app/configuration/tab-endpoint/endpoint-configuration-tab.component.ts
================================================
/**
 * Created by jayhamilton on 5/31/17.
 */
import {Component} from '@angular/core';
import {EndPoint} from './endpoint.model';
import {EndPointService} from './endpoint.service';
import {environment} from '../../../environments/environment';

@Component({
    selector: 'app-endpoint-config-tab',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css']


})
export class EndpointConfigurationTabComponent {

    env:any;

    endPoints: EndPoint[];

    currentEndPoint: EndPoint = new EndPoint('', '', '', '', '', '',
        '', '', '',{'tags':[]});

    constructor(private _endPointService: EndPointService) {

        this.env = environment;

        this._endPointService.getEndPoints().subscribe(data => {
            this.endPoints = data['endPoint'];

            if (this.endPoints && this.endPoints.length) {
                this.setSelectedEndPoint(this.endPoints[0]);
            }

        });
    }

    setSelectedEndPoint(endPoint: EndPoint) {
        this.currentEndPoint = endPoint;
    }

    createEndPoint(endPoint: EndPoint) {

        if (!this.endPoints) {
            this.endPoints = [];
        }

        this.endPoints.push(endPoint);

        this.persistInMemoryDataToStore();

        this.setSelectedEndPoint(endPoint);
    }

    updateEndPoint(endPoint: EndPoint) {

        this.deleteEndPoint(endPoint);
        this.createEndPoint(endPoint);

    }

    deleteEndPoint(endPoint: EndPoint) {

        // find endPoint in memory by name for now (need to use the id) and remove it
        this.endPoints.forEach(item => {

            if (item.name === endPoint.name) {
                const index = this.endPoints.indexOf(item);
                if (index > -1) {
                    this.endPoints.splice(index, 1);
                }
            }
        });


        this.persistInMemoryDataToStore();

        if (this.endPoints && this.endPoints.length === 0) {
            this.currentEndPoint.name = '';
            this.currentEndPoint.address = '';
            this.currentEndPoint.description = '';
            this.currentEndPoint.credential = '';
            this.currentEndPoint.credentialType = '';
            this.currentEndPoint.tokenAPI = '';
            this.currentEndPoint.tokenAPIProperty = '';
            this.currentEndPoint.user = '';
        }else{
            this.setSelectedEndPoint(this.endPoints[0])
        }
    }

    persistInMemoryDataToStore() {

        const endpointModel = {
            endPoint: this.endPoints
        };
        // persist in memory structure
        this._endPointService.saveEndPoint(endpointModel).subscribe(data => {

            /**
             * todo - error handling
             */
        });

    }

}




================================================
FILE: src/app/configuration/tab-endpoint/endpoint.help.ts
================================================
/**
 * Created by jayhamilton on 5/18/17.
 */


================================================
FILE: src/app/configuration/tab-endpoint/endpoint.model.ts
================================================
export interface TAG {
    name: string;
}

export class EndPoint {
    public id: number;
    public name: string;
    public address: string;
    public user: string;
    public credentialType: string;
    public credential: string;
    public description: string;
    public tokenAPI: string;
    public tokenAPIProperty: string;
    public tokenAPIHeader: string;
    public tags: any;

    constructor(name: string,
                address: string,
                user: string,
                credential: string,
                credentialType: string,
                description: string,
                tokenAPI: string,
                tokenAPIProperty: string,
                tokenAPIHeader: string,
                tags: any) {

        this.name = name;
        this.address = address;
        this.user = user;
        this.credential = credential;
        this.credentialType = credentialType;
        this.description = description;
        this.tokenAPI = tokenAPI;
        this.tokenAPIProperty = tokenAPIProperty;
        this.tokenAPIHeader = tokenAPIHeader;
        Object.assign(this, tags);
        this.id = 0;
    }

}

export const credentialScheme = ['none', 'password', 'ssh key', 'OAuth Secret'];



================================================
FILE: src/app/configuration/tab-endpoint/endpoint.service.ts
================================================
/**
 * Created by jayhamilton on 2/7/17.
 */
import {Injectable} from '@angular/core';

import {Observable} from 'rxjs';
import {EndPoint} from './endpoint.model';
import {HttpClient} from '@angular/common/http';


@Injectable()
export class EndPointService {


    constructor(private _http: HttpClient) {
    }

    getEndPoints() {
        if (localStorage.getItem('endpoint') == null) {

            return new Observable(observer => {
                const base = {endPoint: []};
                const mockBarChart = new EndPoint(
                    'Chart Mock Bar Data Source',
                    '/assets/api/chart-mock-bar-model.json',
                    'test user',
                    'testCredential',
                    'unknown',
                    'Predefined data source that cannot be modified or removed.',
                    'token API',
                    'token API Header',
                    'token API Property',
                    {'tags':[{'name':'bar'},{'name':'chart'}]}
                );
                base.endPoint.push(mockBarChart);
                const mockPieChart = new EndPoint(
                    'Chart Mock Pie Data Source',
                    '/assets/api/chart-mock-pie-model.json',
                    'test user',
                    'testCredential',
                    'unknown',
                    'Predefined data source that cannot be modified or removed',
                    'token API',
                    'token API Header',
                    'token API Property',
                    {'tags':[{'name':'pie'},{'name':'chart'}]}
                );
                base.endPoint.push(mockPieChart);
                const memoryEndpoint = new EndPoint(
                    'Memory',
                    '/metric?measure=memory',
                    'test user',
                    'testCredential',
                    'unknown',
                    'Predefined data source that cannot be modified or removed',
                    'token API',
                    'token API Header',
                    'token API Property',
                    {'tags':[{'name':'memory'}]}
                );
                base.endPoint.push(memoryEndpoint);

                localStorage.setItem('endpoint', JSON.stringify(base));
                observer.next(base);
                return () => {
                };
            });
        } else {

            return new Observable(observer => {
                const data = JSON.parse(localStorage.getItem('endpoint'));
                observer.next(data);
                return () => {
                };
            });

        }
    }

    saveEndPoint(endpoint: any) {

        return new Observable(observer => {

            localStorage.setItem('endpoint', JSON.stringify(endpoint));
            observer.next({});
            return () => {
            };

        });

    }
}


================================================
FILE: src/app/configuration/tab-endpoint/endpointDetail.component.ts
================================================
/**
 * Created by jayhamilton on 5/16/17.
 */
import {AfterViewInit, Component, EventEmitter, Input, OnChanges, Output} from '@angular/core';
import {FormGroup, FormBuilder, Validators} from '@angular/forms';

import {credentialScheme, EndPoint, TAG} from './endpoint.model';
import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {MatChipInputEvent} from "@angular/material";

@Component({
    selector: 'app-endpoint-detail',
    moduleId: module.id,
    templateUrl: './endpointDetail.html',
    styleUrls: ['./styles.css']
})

/**
 *
 * TODO- Redo this entire file and add a state machine. This code is very fragile.
 */

export class EndPointDetailComponent implements OnChanges, AfterViewInit {

    @Input() currentEndPoint: EndPoint;

    @Output() createEvent: EventEmitter<EndPoint> = new EventEmitter();
    @Output() updateEvent: EventEmitter<EndPoint> = new EventEmitter();
    @Output() deleteEvent: EventEmitter<EndPoint> = new EventEmitter();

    preDefinedEndPoints = ["memory", "mock"];

    currentState: string;
    preDefined = false;

    endPointForm: FormGroup;
    credentialScheme = credentialScheme;
    useCredentials = false;

    //chip/tag list control
    selectable = true;
    removable = true;
    visible = true;
    addOnBlur = false;
    tagPlaceHolderText = '';
    formTags = {tags: []};

    readonly separatorKeysCodes: number[] = [ENTER, COMMA];

    addTag(event: MatChipInputEvent): void {
        const input = event.input;
        const value = event.value;

        // Add tag
        if ((value || '').trim()) {
            this.formTags.tags.push({name: value.trim()});
        }

        // Reset the input value
        if (input) {
            input.value = '';
        }

        if (this.currentState == 'reset') {
            this.currentState = 'update';
        }
    }

    removeTag(tag: TAG): void {
        const index = this.formTags.tags.indexOf(tag);

        if (index >= 0) {
            this.formTags.tags.splice(index, 1);
        }
        if (this.currentState == 'reset') {
            this.currentState = 'update';
        }
    }

    checkPredefinition() {

        this.preDefined = false;
        for (let x = 0; x < this.preDefinedEndPoints.length; x++) {
            if (this.currentEndPoint.name.toLocaleLowerCase().trim().indexOf(this.preDefinedEndPoints[x].toLocaleLowerCase().trim()) >= 0) {

                this.disableControls();
                this.preDefined = true;
            }
        }
    }

    ngAfterViewInit() {

        this.checkPredefinition();
    }

    ngOnChanges() {

        this.enableControls();
        this.resetForm();
        this.populateFormWithCurrentEndpointValues();
        this.checkPredefinition();
    }

    populateFormWithCurrentEndpointValues() {

        this.endPointForm.setValue({
            name: this.currentEndPoint.name,
            address: this.currentEndPoint.address,
            user: this.currentEndPoint.user,
            credentialType: this.currentEndPoint.credentialType,
            credential: this.currentEndPoint.credential,
            description: this.currentEndPoint.description,
            tokenAPI: this.currentEndPoint.tokenAPI,
            tokenAPIProperty: this.currentEndPoint.tokenAPIProperty,
            tokenAPIHeader: this.currentEndPoint.tokenAPIHeader
        });
        this.formTags.tags = this.currentEndPoint.tags.slice();
    }

    constructor(private fb: FormBuilder) {

        let me = this;

        this.createForm();

        this.endPointForm.valueChanges.forEach(
            (value => {
                if (this.currentState !== 'create') {
                    me.setFormState();
                }
            })
        );
    }

    disableControls() {

        this.endPointForm.get('name').disable();
        this.endPointForm.get('address').disable();
        this.endPointForm.get('description').disable();
        this.removable = false;
        this.selectable = false;
        this.tagPlaceHolderText = "";

    }

    enableControls() {

        this.endPointForm.get('name').enable();
        this.endPointForm.get('address').enable();
        this.endPointForm.get('description').enable();
        this.removable = true;
        this.selectable = true;
        this.tagPlaceHolderText = "Add tag...";

    }


    setFormState() {

        /**
         * todo - implement state machine
         */

        if (this.endPointForm.get('name').pristine) {

            // something other than name changed so this must be an update
            if (this.endPointForm.dirty) {
                this.currentState = 'update';
            }
        } else {
            // name change so assume user wants to perform save as
            this.currentState = 'save as';
        }

        // reset state when a form is clean
        if (this.endPointForm.pristine) {
            this.currentState = 'reset';
        }
    }

    createForm() {

        this.endPointForm = this.fb.group({

            name: ['', Validators.required],
            address: ['', Validators.required],
            user: '',
            credentialType: '',
            credential: '',
            tokenAPI: '',
            tokenAPIProperty: '',
            tokenAPIHeader: '',
            description: ''
        });
    }

    createEndPoint() {

        this.enableControls();

        const ep: EndPoint = new EndPoint(
            this.endPointForm.value.name,
            this.endPointForm.value.address,
            this.endPointForm.value.user,
            this.endPointForm.value.credential,
            this.endPointForm.value.credentialType,
            this.endPointForm.value.description,
            this.endPointForm.value.tokenAPI,
            this.endPointForm.value.tokenAPIProperty,
            this.endPointForm.value.tokenAPIHeader,
            this.formTags
        );

        this.createEvent.emit(ep);
        this.currentState = 'reset';
    }

    updateEndPoint() {

        this.currentEndPoint.name = this.endPointForm.value.name;
        this.currentEndPoint.address = this.endPointForm.value.address;
        this.currentEndPoint.user = this.endPointForm.value.user;
        this.currentEndPoint.credential = this.endPointForm.value.credential;
        this.currentEndPoint.credentialType = this.endPointForm.value.credentialType;
        this.currentEndPoint.description = this.endPointForm.value.description;
        this.currentEndPoint.tokenAPI = this.endPointForm.value.tokenAPI;
        this.currentEndPoint.tokenAPIProperty = this.endPointForm.value.tokenAPIProperty;
        this.currentEndPoint.tokenAPIHeader = this.endPointForm.value.tokenAPIHeader;
        this.currentEndPoint.tags = this.formTags.tags.slice();

        this.updateEvent.emit(this.currentEndPoint);
        this.currentState = 'reset';
    }

    newEndPoint() {

        this.enableControls();
        this.resetForm();
        this.selectable = true;
        this.removable = true;
        this.preDefined = false;
        this.tagPlaceHolderText = "Add tag..."
        /**
         * The create state is used to display the save icon even if the form is being edited
         * todo - implmenet state machine
         */
        this.currentState = 'create';
    }

    resetEndPoint() {
        this.ngOnChanges();

    }

    deleteEndPoint() {

        this.deleteEvent.emit(this.currentEndPoint);
        this.resetForm();
    }

    resetForm() {
        this.endPointForm.reset();
        if (this.formTags.tags && this.formTags.tags.length) {
            this.formTags.tags = [];
        }
    }
}



================================================
FILE: src/app/configuration/tab-endpoint/endpointDetail.html
================================================
<div class="ui right aligned grid">
    <div class="right aligned column">

        <span *ngIf="currentState == 'save as' && endPointForm.valid">
         <a mat-mini-fab routerLink="." color='primary' (click)="createEndPoint()"><mat-icon>content_copy</mat-icon></a>
            &nbsp;save as&nbsp;
        </span>

        <span *ngIf="currentState == 'update' && endPointForm.valid">
            <a mat-mini-fab routerLink="." color='primary' (click)="updateEndPoint()"><mat-icon>save</mat-icon></a>
            &nbsp;update&nbsp;
        </span>


        <span *ngIf="currentState == 'create' && endPointForm.valid">
            <a mat-mini-fab routerLink="." color='primary' (click)="createEndPoint()"><mat-icon>save</mat-icon></a>
            &nbsp;save&nbsp;
        </span>

        <span *ngIf="endPointForm.dirty && currentState != 'create'">
            <a mat-mini-fab routerLink="." color='primary' (click)="resetEndPoint()"><mat-icon>undo</mat-icon></a>
            &nbsp;undo&nbsp;
        </span>

        <span>
            <a mat-mini-fab routerLink="." color='primary' (click)="newEndPoint()"><mat-icon>add</mat-icon></a>
            &nbsp;create&nbsp;
        </span>

        <span *ngIf="currentEndPoint.name !='' && currentState != 'create' && preDefined == false">
            <a mat-mini-fab routerLink="." (click)="deleteEndPoint()"> <mat-icon>clear</mat-icon></a>
            &nbsp;remove&nbsp;
        </span>

    </div>
</div>

<br>

<form [formGroup]="endPointForm" novalidate class="ui form">
    <div class="field">
        <div class="ui left icon input">
            <input formControlName="name"  type="text" placeholder="Name">
            <i class="tag icon"></i>
        </div>
    </div>

    <div class="field">
        <div class="ui left icon input">
            <input formControlName="address"  type="text" placeholder="URL">
            <i class="marker icon"></i>
        </div>
    </div>
    <div class="field">
        <div class="ui">
            <textarea rows="2" class="form-control" formControlName="description" placeholder="Description"></textarea>
        </div>
    </div>
    <mat-form-field  class="example-chip-list">
        <mat-chip-list #chipList>
            <mat-chip *ngFor="let tag of formTags.tags" [selectable]="selectable"
                      [removable]="removable" (removed)="removeTag(tag)">
                {{tag.name}}
                <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
            </mat-chip>
            <input [disabled]="preDefined" type="" placeholder={{tagPlaceHolderText}}
                   [matChipInputFor]="chipList"
                   [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
                   [matChipInputAddOnBlur]="addOnBlur"
                   (matChipInputTokenEnd)="addTag($event)">
        </mat-chip-list>
    </mat-form-field>

    <div *ngIf="useCredentials">
            <div class="field">
                <label>
                    <select class="ui transparent" formControlName="credentialType">
                        <option *ngFor="let credentialType of credentialScheme" [value]="credentialType">
                            {{credentialType}}
                        </option>
                    </select>
                </label>
            </div>
            <div class="field">
                <div class="ui left icon input">
                    <input formControlName="user" type="text" placeholder="User">
                    <i class="user icon"></i>
                </div>
            </div>

            <div class="field">
                <div class="ui left icon input">
                    <input formControlName="credential" type="password" placeholder="Credential">
                    <i class="key icon"></i>
                </div>
            </div>

            <div class="field">
                <div class="ui left icon input">
                    <input formControlName="tokenAPI" type="string" placeholder="Token API">
                    <i class="key icon"></i>
                </div>
            </div>
            <div class="field">
                <div class="ui left icon input">
                    <input formControlName="tokenAPIProperty" type="string" placeholder="Token API Property">
                    <i class="key icon"></i>
                </div>
            </div>

        </div>
</form>







================================================
FILE: src/app/configuration/tab-endpoint/styles.css
================================================

td.selected {
    background-color: #3f51b5 !important;
    color: white;
    font-weight: bold;

}

.ui.table {
    border: none !important;
    color: rgba(97, 97, 97, 0.68) !important;
}

.ui.form .field > label {
    color: rgba(97, 97, 97, 0.68) !important;
    line-height: 3em !important;
}

.ui.form select{
    color: rgba(97, 97, 97, 0.68) !important;
    height: 3em !important;
}

.ui.form input{

    color: rgba(97, 97, 97, 0.68) !important;

}
.ui.table tr td{
    border:none !important;
}

.ui.form textarea{

    color: rgba(97, 97, 97, 0.68) !important;
}

tr {
     cursor: pointer;
}
.example-chip-list {
    width: 100%;
}


================================================
FILE: src/app/configuration/tab-endpoint/view.html
================================================
<div *ngIf="env.boardConfiguration.endpoint == true" class="ui equal width fields grid container">

    <div class="field six wide column">

        <table class="ui selectable celled table">
            <tbody>
            <tr *ngFor="let endPoint of endPoints" (click)="setSelectedEndPoint(endPoint)">
                <td [ngClass]="{'selected': endPoint.name == currentEndPoint.name}">{{endPoint.name}}</td>
            </tr>
            </tbody>
        </table>
    </div>
    <div class="field ten wide column">

        <div *ngIf="currentEndPoint">

            <app-endpoint-detail [currentEndPoint]=currentEndPoint
                            (createEvent)="createEndPoint($event)"
                            (updateEvent)="updateEndPoint($event)"
                            (deleteEvent)="deleteEndPoint($event)"
            ></app-endpoint-detail>
        </div>

    </div>
</div>

<div *ngIf="env.boardConfiguration.endpoint == false">
    This feature is not ready yet!
</div>





================================================
FILE: src/app/configuration/tab-options/options-configuration-tab.component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    Component
} from '@angular/core';
import {OptionsService} from "./service";
import {ToastService} from "../../toast/toast.service";

@Component({
    selector: 'app-options-config-tab',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css']
})
export class OptionsConfigurationTabComponent {

    enableHover: boolean;
    displayGadgetOptionsInSideBar:boolean;

    constructor(private _optionsService: OptionsService, private _toastService: ToastService) {

        this.enableHover = this._optionsService.getBoardOptions()['enableHover'];
        this.displayGadgetOptionsInSideBar = this._optionsService.getBoardOptions()['displayGadgetOptionsInSideBar'];
    }

    onHooverOptionChange(value) {

        this._optionsService.setBoardOptions(
            {
                "enableHover": value['checked'],
                "displayGadgetOptionsInSideBar": this.displayGadgetOptionsInSideBar

            });
        this._toastService.sendMessage("The board configuration has changed!",null);
    }

    onDisplayGadgetOptionsInSideBarChange(value) {

        this._optionsService.setBoardOptions( {
            "enableHover": this.enableHover,
            "displayGadgetOptionsInSideBar": value['checked']

        });
        this._toastService.sendMessage("The board configuration has changed!",null);

    }

}


================================================
FILE: src/app/configuration/tab-options/service.ts
================================================
import {Injectable} from "@angular/core";
import {Subject,Observable} from "rxjs";


@Injectable()
export class OptionsService {

    optionsCollectionName = 'dashboardOptions';
    defaultOptions = {
        'enableHover': false,
        'displayGadgetOptionsInSideBar': false
    };

    private globalOptionsChangeEventSubject: Subject<any> = new Subject<any>();

    constructor() {
    }

    public getBoardOptions() {

        let databaseOptions = JSON.parse(localStorage.getItem(this.optionsCollectionName));

        if (databaseOptions == null) {
            this.persistDefautBoardOptions();
            return this.defaultOptions;
        } else {
            return databaseOptions;
        }
    }

    private persistDefautBoardOptions(){

        localStorage.setItem(this.optionsCollectionName, JSON.stringify(this.defaultOptions))

    }
    public setBoardOptions(options: any) {

        /**
         * Todo this will need to change to support the update to individual options. Currently there is only one
         * option but once there is more than one this method must change to take the input and update just that
         * property of the options object.
         */

        localStorage.removeItem(this.optionsCollectionName);

        /**
         *  Raise an event to listeners, primarily the gadgets, when the global options change. The listeners can use
         * the event to change their behavior
         */
        this.globalOptionsChangeEventSubject.next(options);

        return localStorage.setItem(this.optionsCollectionName, JSON.stringify(options));

    }


    /**
     * The gadget-base can use this method to subscribe to events that are created when the global options change.
    */
    listenForGlobalOptionsChanges(): Observable<string> {
        return this.globalOptionsChangeEventSubject.asObservable();
    }
}


================================================
FILE: src/app/configuration/tab-options/styles.css
================================================


================================================
FILE: src/app/configuration/tab-options/view.html
================================================
<br>
The following options control various aspects of the board's and gadget's behavior. Changes take effect immediately.
<br>
<br>

<mat-slide-toggle
        [checked]="enableHover"
        (change)="onHooverOptionChange($event)">
    Always show the gadget buttons in the title. By default buttons show/hide when you hover over the title.
</mat-slide-toggle>
<br>
<br>
<mat-slide-toggle
        [checked]="displayGadgetOptionsInSideBar"
        (change)="onDisplayGadgetOptionsInSideBarChange($event)">
    (Experimental) When set the options are displayed in the side bar. Otherwise it is displayed within the gadget.
</mat-slide-toggle>

================================================
FILE: src/app/configuration/tabs.model.ts
================================================
export const tabsModel: ({ groupId: string; displayName: string } | { groupId: string; displayName: string })[] = [
    {
        groupId: 'boards',
        displayName: 'Boards'
    },
    {
        groupId: 'options',
        displayName: 'Options'
    },
    {
        groupId: 'endpoint',
        displayName: 'Data Source Registration'
    },
    {
        groupId: 'ai',
        displayName: 'AI Configuration'
    }

];


================================================
FILE: src/app/configuration/view.html
================================================
<div class="ui long modal" #boardconfigmodal_tag>
    <div class="header">
        <h2>{{modalheader}}</h2>
    </div>


    <div class="ui top attached tabular menu">

        <a *ngFor="let tab of tabsModel; let i = index" class="item"
           [ngClass]="{'active': tab.displayName == currentTab }"
           attr.data-tab="{{tab.groupId}}" (click)="setCurrentTab(i)">{{tab.displayName}}</a>

    </div>

    <div *ngFor="let tab of tabsModel; let i = index" [ngClass]="{'active': tab.displayName == currentTab }"
         class="ui bottom attached tab segment"
         attr.data-tab="{{tab.groupId}}" [@contentSwitch]="tab.displayName == currentTab ? 'active':'inactive'">


        <div *ngIf="tab.groupId == 'boards'">

            <app-boards-config-tab  (dashboardCreateEvent)="createBoard($event)"
                                   (dashboardEditEvent)="editBoard($event)"
                                   (dashboardDeleteEvent)="deleteBoard($event)"
                                   [dashboardList]="dashboardList"></app-boards-config-tab>
        </div>

        <div *ngIf="tab.groupId == 'endpoint'">

            <app-endpoint-config-tab></app-endpoint-config-tab>

        </div>

        <div *ngIf="tab.groupId == 'ai'">

            <app-ai-config-tab></app-ai-config-tab>

        </div>

        <div *ngIf="tab.groupId == 'options'">

            <app-options-config-tab></app-options-config-tab>

        </div>
    </div>


    <div class="actions">
        <button class="ui button" (click)="hideMessageModal()">Close </button>
    </div>
</div>

================================================
FILE: src/app/datalist/action-model.ts
================================================
interface ActionInterface {
    name: string;
    item: any;
}


================================================
FILE: src/app/datalist/data-list.component.ts
================================================
import {Component, ContentChild, Input, TemplateRef} from '@angular/core';
import {Facet} from '../facet/facet-model';

@Component({
    selector: 'app-data-list',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['./styles.css']
})
export class DataListComponent {

    @Input() objectList: any[];
    @Input() objectTitleList: string[];
    @Input() placeHolderText: string;
    @Input() layoutColumnOneWidth: string;
    @Input() layoutColumnTwoWidth: string;
    @Input() listHeader: string;
    @Input() typeAheadIsInMenu: boolean;
    @Input() facetTags: Array<Facet>;

    @ContentChild(TemplateRef) template: TemplateRef<any>;


    color = 'white';
    objectListCopy: any[] = [];

    filterListByTags(filterList: string[]) {

        this.copyObjectList();
        this.objectList = this.objectListCopy.filter(object => {

            let tagFound = false;

            if (!filterList.length) {
                return true;
            } else {
                object.tags.forEach(tag => {

                    filterList.forEach(filter => {

                        if (tag.name.toLocaleLowerCase() === filter.toLocaleLowerCase()) {
                            tagFound = true;
                        }
                    });
                });

                return tagFound;
            }
        });

    }

    filterListBySearchString(searchString: string) {

        this.copyObjectList();
        this.objectList = this.objectListCopy.filter(object => {

            if (searchString.localeCompare('') === 0) {
                return true;
            } else {

                if (object.name.toLowerCase().indexOf(searchString.toLowerCase()) !== -1) {

                    return true;
                }
            }

        });
    }

    /**
     * todo - find a better way to manage the list that is displayed and filtered.
     */
    copyObjectList() {
        if (this.objectListCopy.length === 0) {
            this.objectList.forEach(item => {
                this.objectListCopy.push(item);
            });
        }
    }
}



================================================
FILE: src/app/datalist/data-list.module.ts
================================================
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FacetModule} from '../facet/facet.module';
import {HttpClientModule} from '@angular/common/http';
import {TypeAheadInputModule} from '../typeahead-input/typeahead-input.module';
import {DataListComponent} from './data-list.component';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';

@NgModule({
    imports: [
        CommonModule,
        FacetModule,
        TypeAheadInputModule,
        HttpClientModule,
        BrowserAnimationsModule
    ],
    declarations: [
        DataListComponent
    ],
    providers: [],
    exports: [
        DataListComponent
    ]
})
export class DataListModule {
}


================================================
FILE: src/app/datalist/styles.css
================================================
.content {
    background-color:#f7f7f7;
    margin-top: 25px;
    margin-left: 25px;
    padding:5px;
}

hr {
    height: 2px !important;
    color: rgba(110, 110, 110, 0.1) !important;
    background: rgba(110, 110, 110, 0.1) !important;
    font-size: 0;
    border: 0;

}
.list-content{
    max-height: 700px;
    overflow-y: scroll;
    margin-top: 20px;
    padding-right: 10px
}


================================================
FILE: src/app/datalist/view.html
================================================
<div class="content">
    <div class="ui grid">
        <div class="{{layoutColumnOneWidth}} wide column">
            <app-typeahead-input
                    [searchList]="objectTitleList"
                    [placeHolderText]="placeHolderText"
                    [typeAheadIsInMenu]="typeAheadIsInMenu"
                    (selectionEvent)="filterListBySearchString($event)">
            </app-typeahead-input>
            <app-filter-list #filterComponent
                             [facet_tags]="facetTags"
                             (tagSelectEvent)="filterTag.updateFilterList($event)">

            </app-filter-list>
        </div>
        <div class="{{layoutColumnTwoWidth}} wide column">
            <br>
            <app-filter-tag #filterTag
                            (updateFilterListEvent)="filterListByTags($event)">

            </app-filter-tag>

            <div class="list-content">
                <ng-template ngFor [ngForOf]="objectList" [ngForTemplate]="template"></ng-template>
            </div>
        </div>
    </div>
</div>

================================================
FILE: src/app/detail/detail.component.ts
================================================
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, NavigationEnd, Router} from "@angular/router";
import {EndPointService} from "../configuration/tab-endpoint/endpoint.service";
import {RuntimeService} from "../services/runtime.service";
import {DetailService} from "./service";


/**a
 * Detail component
 *
 */
@Component({
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['styles.css']
})
export class DetailComponent implements OnInit {

    chartType: string;
    chartSeries: string;
    chartMetric: string;
    endPointName: string;
    data = [];
    searchText: string;
    navRoutes: Array<string> = [];
    navigationSubscription: any;
    objectAsArray = [];


    constructor(private _router: Router,
                private _route: ActivatedRoute,
                private _endPointService: EndPointService,
                private _detailService: DetailService
    ) {
        this.navigationSubscription = this._router.events.subscribe((e: any) => {
            // If it is a NavigationEnd event re-initalise the component
            if (e instanceof NavigationEnd) {
                this.getObjectsByMetric(true);
            }
        });
    }

    ngOnInit() {
        this.chartType = this._route.snapshot.queryParams['chartType'];
        this.chartSeries = this._route.snapshot.queryParams['chartSeries'];
        this.chartMetric = this._route.snapshot.queryParams['chartMetric'];
        this.endPointName = this._route.snapshot.queryParams['endPointName'];
        this.getObjectsByMetric(false);

    }

    getObject(record: any) {
        this.clearDetailDisplay();

        Object.keys(record).forEach(key => {

            if (key.indexOf("link") < 0) {
                this.objectAsArray.push({"key": key, "value": record[key]});
            }
        })
    }

    getObjectsByHateoasLink(detail: any) {
        this.clearDetailDisplay();

        let href = "";
        detail.links.forEach(link => {
            if (link.rel == 'self') {
                href = link.href;
            }
        });

        let navArray = href.split('/');

        //trying to get data for the current record so do nothing. Avoid this altogether by removing the link from the table.
        if (navArray[navArray.length - 1] == this.navRoutes[this.navRoutes.length - 1]) {
            return;
        }

        this.navRoutes.push(navArray[navArray.length - 1]);

        this._detailService.getDetail(href).subscribe(data => {
            this.data = data.slice();
        });
    }


    getObjectsByMetric(isReload: boolean) {
        this.clearDetailDisplay();

        this._detailService.getDetailByChartSeriesSelected(this.chartType, this.chartSeries, this.chartMetric, this.endPointName).subscribe(data => {
            this.data = data.slice();
        });

        if (!isReload) {
            this.navRoutes.push(this.chartMetric);
        } else {

            /**
             * todo - this won't work for many routes.
             */
            while (this.navRoutes.length > 1) {
                this.navRoutes.splice(this.navRoutes.length - 1, 1);
            }
        }
    }

    goHome() {
        this._router.navigate(["/main-board"]);
    }

    gotToRoute(nav: string, disabled: boolean) {

        if (!disabled) {


            this._router.navigate(['/detail'], {
                queryParams:
                    {
                        chartType: this.chartType,
                        chartSeries: this.chartSeries,
                        chartMetric: this.chartMetric,
                        endPointName: this.endPointName
                    }
            });
        }
    }

    clearDetailDisplay() {
        this.objectAsArray = [];
    }
}


================================================
FILE: src/app/detail/detail.model.ts
================================================
interface DetailModel {
    name: string;
    data: any;
}


================================================
FILE: src/app/detail/detail.module.ts
================================================
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {MatCheckboxModule} from '@angular/material';
import {FormsModule} from '@angular/forms';
import {DetailComponent} from './detail.component';
import {DetailService} from "./service";
import {FilterPipe} from "./filter.pipe";


@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        MatCheckboxModule
    ],
    declarations: [
        DetailComponent,
        FilterPipe
    ],
    providers: [
        DetailService
    ],
    exports: [
        DetailComponent
    ]
})
export class DetailModule {
}



================================================
FILE: src/app/detail/detail.resolver.ts
================================================
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs';


export class DetailResolver implements Resolve <DetailModel> {

    data: DetailModel;

    constructor(detailData: DetailModel) {
        this.data = detailData;
    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DetailModel> | Promise<DetailModel> | DetailModel {

        return this.data;
    };

}


================================================
FILE: src/app/detail/filter.pipe.ts
================================================
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
    name: 'filter'
})
export class FilterPipe implements PipeTransform {
    transform(items: any[], searchText: string): any[] {
        if(!items) return [];
        if(!searchText) return items;


        searchText = searchText.toLowerCase();
        return items.filter( it => {
            return it.node.toLowerCase().includes(searchText)
                || it.master.toLowerCase().includes(searchText)
                || it.jobName.toLowerCase().includes(searchText)
                || it.status.toLowerCase().includes(searchText);
        });
    }
}


================================================
FILE: src/app/detail/service.ts
================================================
import {Injectable} from "@angular/core";
import {HttpClient, HttpParams} from "@angular/common/http";
import {RuntimeService} from "../services/runtime.service";
import {environment} from "../../environments/environment";
import {catchError} from "rxjs/operators";

@Injectable()
export class DetailService {

    constructor(private _http: HttpClient) {
        this.configure();
    }
    testURL = "http://localhost:8080";
    detailURL= "/detail";

    configure() {

        if (!environment.production) {
            this.detailURL = this.testURL + this.detailURL;
        }

    }
    getDetailByChartSeriesSelected(chartType: string, chartSeries: string, chartMetric: string, endPointName: string) {

        /**
         * Todo - review these parameters and make them more meaningful. The goal is to send to the service
         * a pameterized URL /endpointURL?detailParameter={value or id}
         */
        let p = new HttpParams();
        p = p.append("detailParam", chartSeries);
        p = p.append("detailMetric", chartMetric);

        return this._http.get<Array<any>>(this.detailURL, {params: p})
            .pipe(
                catchError(RuntimeService.handleError)
            );

    }
    getDetail(url: string) {

        return this._http.get<Array<any>>(url)
            .pipe(
                catchError(RuntimeService.handleError)
            );

    }

    getRecord(url: string) {

        return this._http.get<Array<any>>(url)
            .pipe(
                catchError(RuntimeService.handleError)
            );

    }
}

================================================
FILE: src/app/detail/styles.css
================================================
a,
a label {
    cursor: pointer;
}

.field {
    background: #4a95c3;
    color: white;
}

.ui .breadcrumb {
    font-size: 1.28571429rem;
}

.detail-right-header {
    color: #616161;
    font-size: 1.2rem;
    float: right;
}

.detail-left-header {
    color: #616161;
    font-size: 1.2rem;

}
.label{
    background: transparent;
}

.active{
    color:grey !important;
    font-weight: normal !important;
}

================================================
FILE: src/app/detail/view.html
================================================
<div class="ui centered stackable grid" style="margin-left: 5px; margin-right: 5px">
    <div class="row">
        <div class="three wide column"></div>
        <div class="ten wide column left aligned">

            <div class="ui breadcrumb">
                <a class="section" (click)="goHome()">Board</a>

                <span *ngFor="let nav of navRoutes,let i = index">
                    <span class="divider">/</span>
                    <a class="section" (click)="gotToRoute(nav, navRoutes.length -1 == i)"
                           [ngClass]="{'active': navRoutes.length -1 == i }">{{nav}}</a>
                </span>

            </div>

            <div class="ui segment">
                <div class="ui top right attached label"><a href="http://localhost:8080/detail/downloadFile" target="_self" ><i class="big grey download icon"></i></a></div>

                <div class="ui  basic segment">
                     <span class="detail-left-header">
                        Type: {{chartSeries}}
                    </span>
                    <span class="detail-right-header">
                       Count: {{data.length}} Tasks
                    </span>

                </div>
                <div class="ui fluid icon input">
                    <i class="search icon"></i>
                    <input [(ngModel)]="searchText" placeholder="search text goes here">
                </div>
                <table class="ui celled compact fixed table">
                    <thead>
                    <tr>
                        <th></th>
                        <th style="text-align: center">Status</th>
                        <th>Master</th>
                        <th>Job Name</th>
                        <th>Sub Type</th>
                        <th>Job Id</th>
                        <th>Task Id</th>
                        <th>Node</th>
                        <th>Disk</th>
                        <th>Task Start</th>
                        <th>Task End</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr *ngFor="let task of data | filter : searchText; let i = index ">
                        <td [ngClass]="{'negative': task.status != 'Completed', 'positive': task.status == 'Completed' }">
                            {{i + 1}}
                        </td>
                        <td style="text-align: center"><i class="icon large "[ngClass]="{
                        'red ban': task.status != 'Completed',
                        'green check': task.status == 'Completed'
                        }"></i></td>
                        <td>{{task.master}}</td>
                        <td>{{task.jobName}}</td>
                        <td>{{task.subType}}</td>
                        <td><a (click)="getObjectsByHateoasLink(task)">{{task.jobId}}</a></td>
                        <td><a (click)="getObject(task)">{{task.taskId}}</a></td>
                        <td>{{task.node}}</td>
                        <td>{{task.disk}}</td>
                        <td>{{task.taskStart}}</td>
                        <td>{{task.taskEnd}}</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>

        <div class="three wide column">
            <div class="ui breadcrumb">
                &nbsp;
            </div>
            <div class="ui  segment" *ngIf="objectAsArray.length">
                <div class="ui top right attached label"><i class="big download icon"></i></div>

                <div class="ui  basic segment">
                    <span class="detail-left-header">Detail</span>
                </div>

                <table class="ui celled compact fixed table">
                    <tr *ngFor="let property of objectAsArray; ">
                        <td class="field">{{property.key}}</td>
                        <td>{{property.value}}</td>
                    </tr>

                </table>
            </div>
        </div>
    </div>
</div>



================================================
FILE: src/app/dynamic-form/dynamic-form-module.ts
================================================
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {DynamicFormComponent} from './dynamic-form.component';
import {DynamicFormPropertyComponent} from './dynamic-form-property.component';
import {PropertyControlService} from './property-control.service';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';


@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        ReactiveFormsModule
    ],
    declarations: [
        DynamicFormComponent,
        DynamicFormPropertyComponent
    ],
    providers: [PropertyControlService],
    exports: [
        DynamicFormComponent,
        DynamicFormPropertyComponent
    ]
})
export class DynamicFormModule {
}


================================================
FILE: src/app/dynamic-form/dynamic-form-property.component.html
================================================
<div [formGroup]="form">

    <div class="field">
        <label [attr.for]="property.key">{{property.label}}</label>

        <div [ngSwitch]="property.controlType">

            <input *ngSwitchCase="'textbox'"
                   [formControlName]="property.key"
                   [id]="property.key"
                   [type]="property.type">

            <select *ngSwitchCase="'dropdown'"
                    [formControlName]="property.key"
                    [id]="property.key">

                <option *ngFor="let opt of property.options"
                        [value]="opt.value">{{opt.key}}
                </option>
            </select>

            <!--todo - fix checkbox type. The value is not properly set by the data so using hard coded type -->
            <input *ngSwitchCase="'checkbox'"
                   [formControlName]="property.key"
                   [id]="property.key"
                   [type]="'checkbox'"
                   (change)="property.value = $event.target.checked"
                   [(ngModel)]="property.value"
                   [attr.checked]="property.value ? true : null">

            <input *ngSwitchCase="'number'"
                   [formControlName]="property.key"
                   [id]="property.key"
                   [type]="'number'">


            <input *ngSwitchCase="'hidden'"
                   [formControlName]="property.key"
                   [id]="property.key"
                   [type]="property.type">

            <select *ngSwitchCase="'dynamicdropdown'"
                    [formControlName]="property.key"
                    [id]="property.key"
                    (change)="property.value = $event.target.toString()">

                <option></option>
                <option *ngFor="let opt of endPoints"
                        [value]="opt.name">{{opt.name}}
                </option>

            </select>
        </div>
    </div>

    <div [@showHideAnimation] class="ui error message" *ngIf="!isValid">{{property.label}} is required</div>


</div>

================================================
FILE: src/app/dynamic-form/dynamic-form-property.component.ts
================================================
/**
 * Created by jayhamilton on 2/5/17.
 */
import {AfterViewInit, Component, Input} from '@angular/core';
import {FormGroup} from '@angular/forms';
import {PropertyBase} from './property-base';
import {EndPointService} from '../configuration/tab-endpoint/endpoint.service';

import {
    style, trigger, animate, transition
} from '@angular/animations';

@Component({
    moduleId: module.id,
    selector: 'app-df-property',
    templateUrl: './dynamic-form-property.component.html',
    styleUrls: ['./styles-props.css'],
    animations: [

        trigger(
            'showHideAnimation',
            [
                transition(':enter', [   // :enter is alias to 'void => *'
                    style({opacity: 0}),
                    animate(750, style({opacity: 1}))
                ]),
                transition(':leave', [   // :leave is alias to '* => void'
                    animate(750, style({opacity: 0}))
                ])
            ])
    ]
})
export class DynamicFormPropertyComponent implements AfterViewInit {
    @Input() property: PropertyBase<any>;
    @Input() form: FormGroup;
    @Input() gadgetTags: any[];//todo - use to control what endpoints are displayed
    endPoints: string[] = [];

    get isValid() {

        return this.form.controls[this.property.key].valid;
    }

    constructor(private endPointService: EndPointService) {

        this.updateEndPointList();
    }

    updateEndPointList() {

        this.endPointService.getEndPoints().subscribe(data => {

            this.endPoints = data['endPoint'].slice();

        });
    }

    ngAfterViewInit() {

        //filter endpoints based on the gadgets tags

        let me = this;
        let eligibleEndpoints = [];

        this.endPoints.forEach(function (point, index, object) {

            let found = false;
            point['tags'].forEach(tag => {

                me.gadgetTags.forEach(_gt => {

                    if (_gt.name.trim().toLowerCase() === tag.name.trim().toLowerCase()) {
                        found = true;
                    }
                })
            });

            if (found) {
               eligibleEndpoints.push(point);
            }
        });

        this.endPoints = eligibleEndpoints.slice();

    }
}


================================================
FILE: src/app/dynamic-form/dynamic-form.component.html
================================================
<div class="ui form" style="text-align: left !important">
    <form (ngSubmit)="onSubmit()" [formGroup]="form">

        <div class="proppages ui top attached tabular menu" #tabComponentTag>
            <a *ngFor="let tab of propertyPages; let i = index" class="item" #tabComponentTag
               [ngClass]="{'active': tab.groupId == currentTab }"
               attr.data-tab="{{tab.groupId}}" (click)="setCurrentTab(tab)">{{tab.displayName}} </a>
        </div>

        <div [@contentSwitch]="page.groupId == currentTab ? 'active':'inactive'"
             *ngFor="let page of propertyPages; let i = index" [ngClass]="{'active': page.groupId == currentTab }"
             class="proppages ui bottom attached tab segment"
             attr.data-tab="{{page.groupId}}">


            <div *ngFor="let property of page.properties"
                 class="form-row">
                <app-df-property
                        [property]="property"
                        [form]="form"
                        [gadgetTags]="gadgetTags"
                >

                </app-df-property>
                <br>
            </div>

        </div>
        <div class="form-row field">
            <button class="ui green submit button" type="submit" [disabled]="!form.valid || !form.dirty"> Save</button>
        </div>
    </form>

    <div *ngIf="showMessage" [@showHideAnimation] class="form-row">
        <br>
        <div class="ui success message">Saved!</div>
    </div>

</div>


================================================
FILE: src/app/dynamic-form/dynamic-form.component.ts
================================================
/**
 * Created by jayhamilton on 2/5/17.
 */
import {
    Component, Input, OnInit, Output, EventEmitter,
    ChangeDetectorRef, AfterViewInit
} from '@angular/core';

import {
    style, state, trigger, animate, transition
} from '@angular/animations';

import {FormGroup} from '@angular/forms';

import {PropertyControlService} from './property-control.service';
import {ConfigurationService} from '../services/configuration.service';
import {EndPointService} from '../configuration/tab-endpoint/endpoint.service';
import {EndPoint} from '../configuration/tab-endpoint/endpoint.model';


@Component({
    /* solves error: Expression has changed after it was checked exception resolution - https://www.youtube.com/watch?v=K_BRcal-JfI*/
    // changeDetection: ChangeDetectionStrategy.OnPush,
    moduleId: module.id,
    selector: 'app-dynamic-form',
    templateUrl: './dynamic-form.component.html',
    styleUrls: ['./styles-props.css'],
    animations: [

        trigger('contentSwitch', [
            state('inactive', style({
                opacity: 0
            })),
            state('active', style({
                opacity: 1
            })),
            transition('inactive => active', animate('750ms ease-in')),
            transition('active => inactive', animate('750ms ease-out'))
        ]),
        trigger(
            'showHideAnimation',
            [
                transition(':enter', [   // :enter is alias to 'void => *'
                    style({opacity: 0}),
                    animate(750, style({opacity: 1}))
                ]),
                transition(':leave', [   // :leave is alias to '* => void'
                    animate(750, style({opacity: 0}))
                ])
            ])
    ],
    providers: [PropertyControlService]
})
export class DynamicFormComponent implements OnInit, AfterViewInit {

    @Input() gadgetTags: any[];//todo - use to control what endpoints are displayed
    @Input() propertyPages: any[];
    @Input() instanceId: number;
    @Output() updatePropertiesEvent: EventEmitter<any> = new EventEmitter(true);
    currentTab = 'run';
    endPoints: EndPoint[];
    state = 'inactive';
    lastActiveTab = {};

    form: FormGroup = new FormGroup({});
    payLoad = '';
    showMessage = false;

    constructor(private pcs: PropertyControlService,
                private configService: ConfigurationService,
                private changeDetectionRef: ChangeDetectorRef) {
    }


    /* better solution that solves error: Expression has changed after it was checked exception resolution*/
    ngAfterViewInit(): void {

        this.changeDetectionRef.detectChanges();
    }

    ngOnInit() {

        this.form = this.pcs.toFormGroupFromPP(this.propertyPages);

    }

    onSubmit() {

        this.payLoad = JSON.stringify(this.form.value);

        console.debug('Saving Form!');
        this.updatePropertiesEvent.emit(this.payLoad);

        console.debug('Sending configuration to the config service!');
        this.configService.notifyGadgetOnPropertyChange(this.payLoad, this.instanceId);

        if (this.payLoad) {
            this.showMessage = true;

            setTimeout(function() {
                this.showMessage = false;
            }.bind(this), 2000);
        }
    }

    setCurrentTab(tab) {
        this.currentTab = tab.groupId;

    }

    get isPropertyPageValid (){

        return this.form.valid;
    }
}







================================================
FILE: src/app/dynamic-form/property-base.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
export class PropertyBase<T> {
    value: T;
    key: string;
    label: string;
    required: boolean;
    order: number;
    controlType: string;
    options:any;

    constructor(props: {
        value?: T,
        key?: string,
        label?: string,
        required?: boolean,
        order?: number,
        controlType?: string,
        options?:any
    } = {},
   ) {

        this.value = props.value;
        this.key = props.key || '';
        this.label = props.label || '';
        this.required = !props.required;
        this.order = props.order === undefined ? 1 : props.order;
        this.controlType = props.controlType || '';
        this.options = props.options;

    }
}

================================================
FILE: src/app/dynamic-form/property-checkbox.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {PropertyBase} from './property-base';


export class CheckboxProperty extends PropertyBase<boolean> {

    controlType = 'checkbox';
    type: string;

    constructor(options: {} = {}) {

        super(options);
        this.type = 'checkbox'; // options['type'] || '';
    }

}

================================================
FILE: src/app/dynamic-form/property-control.service.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {Injectable} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';

@Injectable()
export class PropertyControlService {

    constructor() {
    }


    toFormGroupFromPP(propertyPages: any[]) {

        const group: any = {};

        propertyPages.forEach(propertyPage => {

            propertyPage.properties.forEach(property => {
                group[property.key] = property.required ? new FormControl(property.value
                    || '', Validators.required) : new FormControl(property.value
                    || '');
            });

        });

        return new FormGroup(group);
    }
}


================================================
FILE: src/app/dynamic-form/property-dropdown.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {PropertyBase} from './property-base';

export class DropdownProperty extends PropertyBase<string> {

    controlType = 'dropdown';
    options: {key: string, value: string}[] = [];

    constructor(options: {} = {}) {
        super(options);
        this.options = options['options'] || [];

    }

}


================================================
FILE: src/app/dynamic-form/property-dynamicdropdown.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {PropertyBase} from './property-base';

export class DynamicDropdownProperty extends PropertyBase<string> {

    controlType = 'dynamicdropdown';
    options: {key: string, value: string}[] = [];

    constructor(options: {} = {}) {
        super(options);
        this.options = options['options'] || [];
    }
}


================================================
FILE: src/app/dynamic-form/property-hidden.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {PropertyBase} from './property-base';


export class HiddenProperty extends PropertyBase<string> {

    controlType = 'hidden';
    type: string;

    constructor(options: {} = {}) {
        super(options);
        this.type = 'hidden';
    }

}


================================================
FILE: src/app/dynamic-form/property-number.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {PropertyBase} from './property-base';


export class NumberProperty extends PropertyBase<number> {

    controlType = 'number';
    type: string;

    constructor(options: {} = {}) {
        super(options);
        this.type = 'number'; // options['type']|| '';
    }

}


================================================
FILE: src/app/dynamic-form/property-textbox.ts
================================================
/**
 * Created by jayhamilton on 2/3/17.
 */
import {PropertyBase} from './property-base';

export class TextboxProperty extends PropertyBase<string> {

    controlType = 'textbox';
    type: string;

    constructor(options: {} = {}) {
        super(options);
        this.type = options['type'] || '';
    }

}


================================================
FILE: src/app/dynamic-form/styles-props.css
================================================
.field > label {
    font-size: 1.1em !important;
    color: #767676 !important;
    font-weight: 300
}

.ui.tabular.menu .active.item {
    border-top-width: 3px !important;
    border-top-color: #2185D0 !important;
}

.ui.segment{
    border:none;
}

select{
    color: rgba(97, 97, 97, 0.68) !important;
    height: 3em !important;
}

input{

    line-height: 2em;
    padding: 5px;
    border-radius: 5px;
    border-style: solid;
    border-width: thin;
    border-color: lightgray;
    width:100%;


}

================================================
FILE: src/app/error/error-handler.component.ts
================================================
import {
    Component, Input
} from '@angular/core';

import {
    style, trigger, animate, transition
} from '@angular/animations';

import {ErrorObject} from './error-model';



@Component({
    moduleId: module.id,
    selector: 'app-error-handler',
    templateUrl: './view.html',
    styleUrls: ['./styles-error.css'],
    animations: [

        trigger('error', [
            transition(':enter', [
                style({opacity: 0}),
                animate('1000ms', style({opacity: 1}))
            ]),
            transition(':leave', [
                style({opacity: 1}),
                animate('1000ms', style({opacity: 0}))
            ])
        ])
    ]
})
export class ErrorHandlerComponent {
    @Input() errorObject: ErrorObject;
    @Input() errorExists: boolean;

    constructor() {

    }
    public closeMessage() {

        this.errorExists = false;
    }

}



================================================
FILE: src/app/error/error-handler.ts
================================================
import {ErrorObject, SolutionObject} from './error-model';

/**
 * Created by jayhamilton on 7/5/17.
 */
export class ErrorHandler {

    static getErrorObject(errMsg: any) {
        return new ErrorObject(
            errMsg.statusText,
            'Some description',
            ErrorHandler.getSolutionList(
                errMsg.status
                + ' '
                + errMsg.statusText),
            errMsg.resource);
    }

    /**
     * todo - fix this error handling logic. Move it to its own class.
     * @param errMsg
     * @returns {SolutionObject[]}
     */
    static getSolutionList(errMsg: string) {

        console.log("ERROR CONDITION:  " + errMsg )

        const solutionList: SolutionObject[] = [];

        switch (ErrorHandler.getErrorType(errMsg.toLowerCase())) {

            case 'ERR_CERTIFICATE':
                solutionList.push(new SolutionObject('Check to see if your browser has accepted the certificate', 0, 'http://link1'));
                break;
            case 'ERR_CROSS_ORIGIN_RESOURCE_SHARING':
                solutionList.push(new SolutionObject('Check to see if your browser has accepted the certificate', 0, 'http://link1'));
                break;
            case 'ERR_CONNECTION_REFUSED':
                solutionList.push(new SolutionObject(
                    'Check to see if the host/service you are attempting to connect to is up.', 0, 'http://link1'));
                break;
            case 'ERR_NOT_FOUND':
                solutionList.push(new SolutionObject(
                    'Resource not found.', 0, 'http://link1'));
                break;
            case 'ERR_CONNECTION_TIMEOUT':
                solutionList.push(new SolutionObject(
                    'A timeout occurred. The default timeout on a connection is 60 seconds. ' +
                    'Check the endpoint to see if you are able to access the ip and port using ping. ' +
                    'If 60 seconds is to short of a timeout go into configuration and increase it.', 0, 'http://link1'));
                break;
            default: {
                solutionList.push(new SolutionObject(errMsg, 0, 'http://link1'));
            }
        }

        return solutionList;
    }

    static getErrorType(errMsg: string): string {

        if (errMsg.indexOf('trust') > -1) {
            return 'ERR_CERTIFICATE';
        }
        if (errMsg.indexOf('cors') > -1) {
            return 'ERR_CROSS_ORIGIN_RESOURCE_SHARING';
        }
        if (errMsg.indexOf('refuse') > -1) {
            return 'ERR_CONNECTION_REFUSED';
        }
        if (errMsg.indexOf('timeout') > -1) {
            return 'ERR_CONNECTION_TIMEOUT';
        }
        if (errMsg.indexOf('404') > -1) {
            return 'ERR_NOT_FOUND';
        }
        return errMsg;
    }

    static getWebSocketErrorReason(error: any) {

        let reason = 'There was probably a problem with an attempt to connect to the endpoint!';
        switch (error.code) {
            case 1000:
                reason = 'Normal closure';
                break;
            case 1001:
                reason = 'An endpoint is going away';
                break;
            case 1002:
                reason = 'An endpoint is terminating the connection due to a protocol error.';
                break;
            case 1003:
                reason = 'An endpoint is terminating the connection because it has received a type of data it cannot accept';
                break;
            case 1004:
                reason = 'Reserved. The specific meaning might be defined in the future.';
                break;
            case 1005:
                reason = 'No status code was actually present';
                break;
            case 1006:
                reason = 'The connection was closed abnormally';
                break;
            case 1007:
                reason = 'The endpoint is terminating the connection because a message was received that contained inconsistent data';
                break;
            case 1008:
                reason = 'The endpoint is terminating the connection because it received a message that violates its policy';
                break;
            case 1009:
                reason = 'The endpoint is terminating the connection because a data frame was received that is too large';
                break;
            case 1010:
                reason = 'The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn\'t.';
                break;
            case 1011:
                reason = 'The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.';
                break;
            case 1012:
                reason = 'The server is terminating the connection because it is restarting';
                break;
            case 1013:
                reason = 'The server is terminating the connection due to a temporary condition';
                break;
            case 1015:
                reason = 'The connection was closed due to a failure to perform a TLS handshake';
                break;
        }
        return reason;
    }
}


================================================
FILE: src/app/error/error-model.ts
================================================
/**
 * Created by jayhamilton on 6/22/17.
 */
export class ErrorObject {
    detail: string;
    summary: string;
    solutions: SolutionObject[];
    resource: string;
    constructor(detail: string, summary: string, solutions: SolutionObject[], resource: string) {
        this.detail = detail;
        this.summary = summary;
        this.solutions = solutions;
        this.resource = resource;
    }
};

export class SolutionObject {
    summary: string;
    articleId: number;
    link: string;
    constructor(summary, articleId, link) {
        this.summary = summary;
        this.articleId = articleId;
        this.link = link;
    }
}


================================================
FILE: src/app/error/error.module.ts
================================================
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ErrorHandlerComponent} from './error-handler.component';

@NgModule({
    imports: [
        CommonModule
    ],
    declarations: [ErrorHandlerComponent],
    exports: [ErrorHandlerComponent]
})
export class ErrorHandlerModule {
}


================================================
FILE: src/app/error/styles-error.css
================================================
.error-heading{
    color:grey !important;
    text-align: left;
}


================================================
FILE: src/app/error/view.html
================================================
<div [@error]="errorExists" *ngIf="errorExists" class="ui bottom attached negative message">
    <i class="close icon" (click)="closeMessage()"></i>
    <div class="header">
        {{errorObject.summary}}
    </div>
    <p>
        {{errorObject.detail}}
    </p>

    <p>
        resource: {{errorObject.resource}}
    </p>

    <span class="error-heading"> Potential solutions</span>
    <hr style="color:rgba(194,197,200,0.37)">
    <div style="text-align: left !important" *ngFor="let solution of errorObject.solutions">
        <br><span class="error-heading">article:&nbsp;</span> {{solution.link}}
        <br><span class="error-heading">summary:&nbsp;</span> {{solution.summary}}
    </div>
</div>

================================================
FILE: src/app/facet/capitalize-first-character-pipe.ts
================================================
import { Pipe, PipeTransform } from '@angular/core';
/*
 * Capitalize the first letter of the string
 * Takes a string as a value.
 * Usage:
 *  value | capitalizefirst
 * Example:
 *  // value.name = daniel
 *  {{ value.name | capitalizefirst  }}
 *  fromats to: Daniel
 */
@Pipe({
    name: 'capitalizeFirst'
})
export class CapitalizeFirstPipe implements PipeTransform {
    transform(value: string, args: any[]): string {
        if (value === null) {

            return 'Not assigned';
        }
        return value.charAt(0).toUpperCase() + value.slice(1);
    }
}


================================================
FILE: src/app/facet/facet-component.ts
================================================
import {Facet} from './facet-model';
import {
    Component, EventEmitter, Input, OnInit, Output
} from '@angular/core';

import {
    style, state, trigger, animate, transition
} from '@angular/animations';

/**
 * Created by jayhamilton on 7/11/17.
 */
@Component({
    moduleId: module.id,
    selector: 'app-facet',
    template: `

        <hr style='max-width: 100%; margin-left:0;'>
        <br>
        <div class='ui container grid'>
            <div class='eight wide column' style="margin-left: 0 !important;padding-left: 0 !important;">
                <h4>{{facet.name}}</h4>
            </div>
            <div class='eight wide column'>
                <div class='ui top right attached label' style='background-color: whitesmoke'>
                    <i
                        class='chevron icon' [ngClass]= "{'up': facetOpen == 'in', 'down': facetOpen=='out'}"
                        (click)='toggleAccordion()'
                        style='color:grey'>
                    </i>
                </div>
            </div>
        </div>
        <div [@accordion]='facetOpen'>
            <table class='ui very basic table' [@accordion2]='facetOpen'>
                <tbody>
                <tr *ngFor='let tag of facet.tags'>
                    <td style="width: 35px !important">
                        <mat-checkbox (click)='tagSelect(tag.name)'></mat-checkbox>
                        <!--<input type='checkbox' (click)='tagSelect(tag.name)'>-->
                    </td>
                    <td style='color:grey'>{{tag.name}} &nbsp;( {{tag.count}} )</td>
                </tr>
                </tbody>
            </table>
        </div>
        <br>

    `,
    styleUrls: ['./styles.css'],
    animations: [

        trigger('accordion', [
            state('in', style({
                height: '*'
            })),
            state('out', style({
                opacity: '0',
                height: '0px'
            })),
            transition('in => out', animate('700ms ease-in-out')),
            transition('out => in', animate('300ms ease-in-out'))
        ]),
        trigger('accordion2', [
            state('in', style({
                height: '*'
            })),
            state('out', style({
                opacity: '0',
                height: '0px'
            })),
            transition('in => out', animate('300ms ease-in-out')),
            transition('out => in', animate('800ms ease-in-out'))
        ])
    ]
})
export class FacetComponent implements OnInit {
    @Output() tagSelectEvent: EventEmitter<any> = new EventEmitter();
    @Input() facet: Facet;
    @Input() openFacet: boolean;

    facetOpen: string;

    constructor() {
    }

    ngOnInit() {
        if (this.openFacet) {
            this.facetOpen = 'in';
        }else {
            this.facetOpen = 'out';
        }
    }

    toggleAccordion() {
        this.facetOpen = this.facetOpen === 'out' ? 'in' : 'out';

    }

    tagSelect(tagName) {
        this.tagSelectEvent.emit(tagName);
    }

}


================================================
FILE: src/app/facet/facet-model.ts
================================================
export class Facet {
    name: string;
    tags: Array<Tag>;

    constructor(name: string, tags: Array<Tag>) {

        this.name = name;
        this.tags = tags;
    }
}

export class Tag {
    name: string;
    count: number;

    constructor(name: string) {
        this.name = name;
        this.count = 1;
    }
}


================================================
FILE: src/app/facet/facet-tag-processor.ts
================================================
import {Facet, Tag} from './facet-model';

export class FacetTagProcessor {

    facet_tags: Array<Facet> = [];
    objectList: any[];

    constructor(objectList: any[]) {
        this.objectList = objectList;
    }

    getFacetTags() {

        const me = this;
        this.objectList.forEach(function (item) {

            me.formatAndUpdateTagList(item.tags);

        });

        return this.facet_tags;
    }

    formatAndUpdateTagList(items: any[]) {

        items.forEach(tag => {

            // add the first facet and tag to the facet_tag array
            if (!this.facet_tags.length) {

                this.createFacetAndAddItToTheFacetTagArray(tag);

            } else {

                let facetExists = false;

                this.facet_tags.forEach(facet => {

                    if (facet.name.toLowerCase() === tag.facet.toLowerCase()) {
                        facetExists = true;
                    }
                });

                if (facetExists) {

                    this.updateFacetWithTag(tag);

                } else {

                    this.createFacetAndAddItToTheFacetTagArray(tag);

                }
            }
        });
    }

    createFacetAndAddItToTheFacetTagArray(tag: any) {

        const _tags: Array<Tag> = [];
        const _tag: Tag = this.createTag(this.capitalize(tag.name));

        _tags.push(_tag);

        const facet: Facet = new Facet(tag.facet, _tags);

        this.facet_tags.push(facet);

    }

    createTag(tag) {

        return new Tag(tag);
    }

    updateFacetWithTag(tag: any) {

        // find the facet and then add the tag or update the count
        this.facet_tags.forEach(facet => {

            if (facet.name.toLowerCase() === tag.facet.toLowerCase()) {


                let tagExists = false;


                facet.tags.forEach(_tag => {

                    if (_tag.name.toLowerCase() === tag.name.toLowerCase()) {

                        tagExists = true;

                        _tag.count = _tag.count + 1;

                    }

                });

                if (!tagExists) {

                    facet.tags.push(this.createTag(this.capitalize(tag.name)));
                }
            }

        });
    }

    capitalize(value: string) {
        return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
    }
}


================================================
FILE: src/app/facet/facet.module.ts
================================================
import {CommonModule} from '@angular/common';
import {NgModule} from '@angular/core';
import {FacetComponent} from './facet-component';
import {FilterListComponent} from './filter-list-component';
import {FilterTagComponent} from './filter-tag-component';
import {CapitalizeFirstPipe} from './capitalize-first-character-pipe';
import {MatCheckboxModule} from '@angular/material';
import {FormsModule} from '@angular/forms';
import {AddGadgetService} from '../add-gadget/service';

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        MatCheckboxModule
    ],
    declarations: [
        FacetComponent,
        FilterListComponent,
        FilterTagComponent,
        CapitalizeFirstPipe
    ],
    providers: [
        AddGadgetService
    ],
    exports: [
        FacetComponent,
        FilterListComponent,
        FilterTagComponent,
        CapitalizeFirstPipe
    ]
})
export class FacetModule {
}


================================================
FILE: src/app/facet/filter-list-component.ts
================================================
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {AddGadgetService} from '../add-gadget/service';
import {Facet, Tag} from './facet-model';

/**
 * Created by jayhamilton on 6/27/17.
 */
@Component({
    moduleId: module.id,
    selector: 'app-filter-list',
    template: `
        <br>
        <div *ngFor='let facet of facet_tags ;let i = index'>

            <app-facet [facet]='facet' (tagSelectEvent)='tagSelect($event)' [openFacet]='i < 2'></app-facet>

        </div>
    `,
    styleUrls: ['./styles.css']
})
export class FilterListComponent {
    @Output() tagSelectEvent: EventEmitter<any> = new EventEmitter();
    @Input() facet_tags: Array<Facet>;

    tagSelect(tagName) {

        this.tagSelectEvent.emit(tagName);

    }
}


================================================
FILE: src/app/facet/filter-tag-component.ts
================================================
import { Component, EventEmitter, Output} from '@angular/core';

import {
    style, trigger, animate, transition
} from '@angular/animations';
/**
 * Created by jayhamilton on 6/27/17.
 */
@Component({
    moduleId: module.id,
    selector: 'app-filter-tag',
    template: `
        <div class='ui basic segment' style='background-color:white; min-height: 4.5em; border-radius:5px'>
            <div class='ui large circular labels'>
               <a class='ui label' [@showHideAnimation] *ngFor='let tag of filterList'>
                    {{tag}}
                </a>
            </div>
        </div>
    `,
    styleUrls: ['../gadgets/_common/styles-gadget.css'],
    animations: [
        trigger(
            'showHideAnimation',
            [
                transition(':enter', [   // :enter is alias to 'void => *'
                    style({opacity: 0}),
                    animate(750, style({opacity: 1}))
                ]),
                transition(':leave', [   // :leave is alias to '* => void'
                    animate(750, style({opacity: 0}))
                ])
            ])
    ]

})
export class FilterTagComponent {

    @Output() updateFilterListEvent = new EventEmitter<any>();

    filterList: Array<string> = [];

    constructor() {
    }

    updateFilterList(filter) {

        filter = filter.toLocaleLowerCase();

        const index: number = this.filterList.indexOf(filter);
        if (index !== -1) {
            this.filterList.splice(index, 1);
        } else {
            this.filterList.push(filter);
        }

        this.updateFilterListEvent.emit(this.filterList);

    }
}


================================================
FILE: src/app/facet/styles.css
================================================
.ui.avatar.image {
    width: 4.4em !important;
    height: 4em !important
}

hr {
    height: 2px !important;
    color: rgba(110, 110, 110, 0.1) !important;
    background: rgba(110, 110, 110, 0.1) !important;
    font-size: 0;
    border: 0;

}

.ui.input input:focus, .ui.input.focus input {
    border-color: #e9e9e9 !important;
}

h3, h4 {
    color: rgba(66, 66, 66, .74) !important;
    font-weight: 400 !important;
    font-size:.85em;
}

.ui.basic.segment {
    border-radius: 5px !important;
}

.segment {
    border-radius: 5px !important;
}

.ui.table tr td {
    border-top: none !important;
}

.ui.table td {
    padding: .3em !important;
    font-size: .8em;
}


================================================
FILE: src/app/gadgets/_common/base-chart-models/bar.model.ts
================================================
import {Series} from './series.model';

export abstract class Bar {

    public name: string;
    public series: Array<Series>;


    constructor(name: string, series: Array<Series>) {
        this.name = name;
        this.series = series;
    }

}

================================================
FILE: src/app/gadgets/_common/base-chart-models/series.model.ts
================================================
export class Series {

    public name: string;
    public value: number;

    constructor(name: string, value: number) {
        this.name = name;
        this.value = value;
    }
}


================================================
FILE: src/app/gadgets/_common/gadget-base.ts
================================================
import {ErrorObject} from '../../error/error-model';
import {EndPoint} from '../../configuration/tab-endpoint/endpoint.model';
import {EndPointService} from '../../configuration/tab-endpoint/endpoint.service';
import {GadgetPropertyService} from './gadget-property.service';
import {RuntimeService} from '../../services/runtime.service';
import {GadgetInstanceService} from '../../grid/grid.service';
import {AfterViewInit, ChangeDetectorRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {DynamicFormComponent} from '../../dynamic-form/dynamic-form.component';
import {OptionsService} from "../../configuration/tab-options/service";

/**
 * Created by jayhamilton on 6/22/17.
 */

export abstract class GadgetBase implements IGadget, OnDestroy, OnInit, AfterViewInit {
    @ViewChild(DynamicFormComponent) propertyPageForm: DynamicFormComponent;
    title: string;
    instanceId: number;
    config: any;
    gadgetTags: Array<any>;

    /**
     * Used to determine when to show the controls that appear in the gadgets
     * heading area. This is set by the mouseover/mouseout events.
     * @type {boolean}
     */
    showControls = false;

    /**
     * determines whether to show the gadgets property page
     * @type {boolean}
     */
    inConfig = false;

    /**
     * Determines if a gadget is runnning or not
     * @type {boolean}
     */
    inRun = false;

    /**
     * When a gadget is manually put into run mode this property will be used to
     * display a spinning icon and will be enabled between intiating an operation (run or stop)
     * to the operation is enabled
     * @type {boolean}
     */
    actionInitiated = false;

    /**
     * Gadgets that are of type realtime have a run/stop set of controls.
     * Those gadgets should set this property to true. This property's visibility
     * will also be controlled by whether the gadget's configuration form is valid.
     * @type {boolean}
     */
    showOperationControls = false;
    /**
     * This property is used to simply allow the gadget to not show any run/stop controls.
     * This is needed because the showOperationControls does something similar but not exactly the same.
     * The showOperationControls property allows the gadgetBase to determine if the run control, if the gadget
     * uses it, to be displayed when the gadget has a valid configuration.
     *
     * Default: true - Gadgets without a need for run/stop control should override this value.
     * @type {boolean}
     */
    gadgetHasOperationControls = true;

    /**
     * Most gadgets need configuration so gadgets that don't can override this property
     * @type {boolean}
     */
    showConfigurationControl = true;

    // internally controls dynamic form properties
    propertyPages: any[] = [];

    endpointObject: EndPoint;

    errorObject: ErrorObject;
    errorExists = false;
    globalOptions:any;

    constructor(protected _runtimeService: RuntimeService,
                protected _gadgetInstanceService: GadgetInstanceService,
                protected _propertyService: GadgetPropertyService,
                protected _endPointService: EndPointService,
                protected changeDetectionRef: ChangeDetectorRef,
                protected _optionsService: OptionsService) {

        this._optionsService.listenForGlobalOptionsChanges().subscribe(options=>{

            /**
             * This is called when there is a change to the options tab within the configuration modal.
             * The following method needs to also be called when the gadget is initially instantiated.
             * When the gadget is instantiated the option values need to come from the persistent store.
             */

            this.updateGadgetWithGlobalOptions(options);
        });

        this.updateGadgetWithGlobalOptions(this._optionsService.getBoardOptions())
    }

    public ngOnInit() {
       this.toggleConfigMode();
       this.changeDetectionRef.detectChanges();
    }

    public ngAfterViewInit() {


        if (this.propertyPageForm) {

            if (this.propertyPageForm.isPropertyPageValid) {
                this.toggleConfigMode();
                this.changeDetectionRef.detectChanges();

                this.showOperationControls = true;
                this.changeDetectionRef.detectChanges();
            } else {
                this.showOperationControls = false;
                this.changeDetectionRef.detectChanges();
            }
        }
        this.preRun();
    }

    public initializeState() {

    }

    public toggleConfigMode() {

        if (!this.inConfig) {

            this.initializeProperties();
        }
        this.inConfig = !this.inConfig;
    }

    public initializeProperties() {

        if (this.propertyPages.length === 0 && this.config.propertyPages) {
            this._propertyService.setPropertyPagesAndProperties(this.config.propertyPages, this.propertyPages);
        }
    }

    public abstract run(): void

    public abstract stop(): void

    public abstract updateProperties(updatedProperties: any): void

    public abstract updateData(data: any[]): void

    public abstract preRun(): void

    public handleError(error: ErrorObject) {


        this.inRun = false;
        this.actionInitiated = false;
        this.errorExists = true;
        this.errorObject = error;

    }

    public initializeRunState(forceRunState: boolean) {

        this.errorExists = false;
        this.actionInitiated = true;
        this.inConfig = false;
        if (forceRunState) {
            this.setInRunState();
        }
    }

    public setInRunState() {

        this.inRun = true;
        this.actionInitiated = false;
    }

    public setStopState(longRunningStopAction: boolean) {
        /**
         *  If the gadget indicates longRunningStopAction then the gadget has to set this value to
         *  false once the operation is complete
         */
        this.actionInitiated = longRunningStopAction;
        this.inRun = false;

    }

    public remove() {
        this._gadgetInstanceService.removeInstance(this.instanceId);
    }

    public showGadgetControls(enable: boolean) {
        this.showControls = enable;
    }

    /**
     * called from cell.component after the gadget is created during runtime
     * intanceId, config, title and endpoint are common to all gadgets. Once the gadgets are configured
     * we give them an opportunity to perform an action during the preRun() method. For example,
     * the statistic gadget uses preRun() to make a single call to the endpoint to update its display.
     * */
    public configureGadget(instanceId: number, config: any, tags: Array<any>) {

        this.instanceId = instanceId;
        this.config = config;
        this.gadgetTags = tags.slice();

        this.setTitle(this.getPropFromPropertyPages('title'));
        this.setEndPoint(this.getPropFromPropertyPages('endpoint'));

        /**
         *  Todo - remove this prerun call and refactor remaining code. Prerun was called twice and had an impact on the barchart api calls.
         *  API calls continued after route changes which is undesirable. See ngAfterViewInit where it is also called from.
         */
        //this.preRun();

    }

    protected setEndPoint(endpoint: string) {

        this._endPointService.getEndPoints().subscribe(data => {

            if (data['endPoint']) {
                data['endPoint'].forEach(item => {
                    if (item.name === endpoint) {
                        this.endpointObject = item;
                    }
                });
            }
        });
    }

    protected getEndPoint() {
        return this.endpointObject;
    }

    protected setTitle(title: string) {
        this.title = title;
    }

    protected getPropFromPropertyPages(prop: string) {

        for (let x = 0; x < this.config.propertyPages.length; x++) {

            for (let i = 0; i < this.config.propertyPages[x].properties.length; i++) {

                if (this.config.propertyPages[x].properties[i].key === prop) {
                    return this.config.propertyPages[x].properties[i].value;
                }
            }

        }
        return 'Unknown';
    }

    public ngOnDestroy() {

    }

    public updateGadgetWithGlobalOptions(options:any){


        this.globalOptions = Object.assign({},options);


    }
}


================================================
FILE: src/app/gadgets/_common/gadget-config-model.ts
================================================
import {PropertyBase} from '../../dynamic-form/property-base';

/**
 * Created by jayhamilton on 6/15/17.
 */

export class GadgetConfigModel {
    propertyPages: PropertyPage[] = [];

    constructor(config: any) {

        config.propertyPages.forEach((page) => {

            const props: PropertyBase<any>[] = [];

            page.properties.forEach((prop) => {

                switch (prop.controlType) {
                    case 'textbox':
                    case 'dropdown':
                    case 'dynamicdropdown':
                        props.push(new PropertyBase<string>(prop));
                        break;
                    case 'checkbox':
                        props.push(new PropertyBase<boolean>(prop));
                        break;
                    case 'hidden':
                        props.push(new PropertyBase<number>(prop));
                        break;
                    default:
                        props.push(new PropertyBase<string>(prop));
                        break;
                }
            });

            this.propertyPages.push(new PropertyPage(page.displayName, page.groupId, page.position, props));
        });
    }
}

class PropertyPage {
    displayName: string;
    groupId: string;
    position: number;
    properties: PropertyBase<any>[];

    constructor(displayName: string, groupId: string, position: number, properties: PropertyBase<any>[]) {
        this.displayName = displayName;
        this.groupId = groupId;
        this.position = position;
        this.properties = properties;
    }
}


================================================
FILE: src/app/gadgets/_common/gadget-header-component.ts
================================================
/**
 * Created by jayhamilton on 2/28/17.
 */
import {Component, Input, Output, EventEmitter} from '@angular/core';
/**
 * Created by jayhamilton on 2/26/17.
 */

@Component({
    moduleId: module.id,
    selector: 'app-gadget-header',
    templateUrl: './gadget-header.html',
    styleUrls: ['./styles-gadget.css']
})
export class GadgetHeaderComponent {
    @Input() title: string;
    @Input() showControls: boolean;
    @Input() inRun: boolean;
    @Input() inConfig: boolean;
    @Input() actionInitiated: boolean;
    @Input() showOperationControls: boolean;
    @Input() showConfigurationControl: boolean;
    @Input() gadgetHasOperationControls: boolean;
    @Input() globalOptions:any;
    @Output() removeEvent: EventEmitter<any> = new EventEmitter();
    @Output() toggleConfigModeEvent: EventEmitter<any> = new EventEmitter();
    @Output() runEvent: EventEmitter<any> = new EventEmitter();
    @Output() stopEvent: EventEmitter<any> = new EventEmitter();
    @Output() helpEvent: EventEmitter<any> = new EventEmitter();


    remove() {
        this.removeEvent.emit();
    }

    toggleConfigMode() {
        this.toggleConfigModeEvent.emit();
    }

    run() {

        this.runEvent.emit();

    }

    stop() {

        this.stopEvent.emit();
    }

    help(){
        this.helpEvent.emit();
    }

}

================================================
FILE: src/app/gadgets/_common/gadget-header.html
================================================
<div class="ui top attached label">

    <button class="compact ui button right floated"
            *ngIf="showControls || globalOptions.enableHover" (click)="remove()">
        <i class="trash icon" style="margin-right:0 !important"></i>
    </button>
    <button class="compact ui button right floated"
            *ngIf="showControls || globalOptions.enableHover && showConfigurationControl" (click)="toggleConfigMode()">
        <i class="setting  icon" style="margin-right:0 !important"></i>
    </button>
    <button class="compact ui button right floated"
            *ngIf="showControls || globalOptions.enableHover" (click)="help()">
        <i class="info icon" style="margin-right:0 !important" ></i>
    </button>

    <app-gadget-operation-control *ngIf="showControls || globalOptions.enableHover"
                              [inRun]="inRun"
                              [inConfig]="inConfig"
                              [actionInitiated]="actionInitiated"
                              [showOperationControls]="showOperationControls"
                              [gadgetHasOperationControls]="gadgetHasOperationControls"
                              (runEvent)="run()"
                              (stopEvent)="stop()">

    </app-gadget-operation-control>

    <div class="ui top left floated label ct-title">{{title}}</div>
</div>
<div class="spacer"></div>
    

================================================
FILE: src/app/gadgets/_common/gadget-operation-control-component.ts
================================================
import {Component, EventEmitter, Input, Output} from '@angular/core';

/**
 * Created by jayhamilton on 6/29/17.
 */

@Component({
    moduleId: module.id,
    selector: 'app-gadget-operation-control',
    template: `

        <button class="compact ui button right floated"
                *ngIf="!inRun && !actionInitiated && showOperationControls && gadgetHasOperationControls"
                (click)="run()"><i class="green play icon" style="margin-right:0 !important"></i>
        </button>

        <button class="compact ui button right floated"
                *ngIf="!inRun && 
        actionInitiated && 
        showOperationControls && 
        gadgetHasOperationControls">
            <i class="black spinner loading icon" style="margin-right:0 !important"></i>
        </button>

        <button class="compact ui button right floated"
                *ngIf="inRun && !actionInitiated && showOperationControls && gadgetHasOperationControls"
                (click)="stop()"><i class="red stop icon" style="margin-right:0 !important"></i>
        </button>
    `,
})
export class GadgetOperationComponent {
    @Output() runEvent: EventEmitter<any> = new EventEmitter();
    @Output() stopEvent: EventEmitter<any> = new EventEmitter();

    @Input() inRun: boolean;
    @Input() actionInitiated: boolean;
    @Input() inConfig: boolean;
    @Input() showOperationControls: boolean;
    @Input() gadgetHasOperationControls: boolean;


    run() {
        this.runEvent.emit();
    }

    stop() {
        this.stopEvent.emit();
    }

}


================================================
FILE: src/app/gadgets/_common/gadget-property.service.ts
================================================
import {Injectable} from '@angular/core';
import {DropdownProperty} from '../../dynamic-form/property-dropdown';
import {PropertyBase} from '../../dynamic-form/property-base';
import {TextboxProperty} from '../../dynamic-form/property-textbox';
import {HiddenProperty} from '../../dynamic-form/property-hidden';
import {CheckboxProperty} from '../../dynamic-form/property-checkbox';
import {DynamicDropdownProperty} from '../../dynamic-form/property-dynamicdropdown';
import {NumberProperty} from '../../dynamic-form/property-number';

@Injectable()
export class GadgetPropertyService {

    constructor() {
    }

    setPropertiesAndValues(defaultProperties: any[], properties: PropertyBase<any>[]) {
        let ctrl: PropertyBase<any>;

        properties.length = 0;

        defaultProperties.forEach(function (property) {

            if (property.controlType === 'dropdown') {
                ctrl = new DropdownProperty(property);
                properties.push(ctrl);
            } else if (property.controlType === 'textbox') {
                ctrl = new TextboxProperty(property);
                properties.push(ctrl);
            } else if (property.controlType === 'checkbox') {
                ctrl = new CheckboxProperty(property);
                properties.push(ctrl);
            } else if (property.controlType === 'hidden') {
                ctrl = new HiddenProperty(property);
                properties.push(ctrl);
            } else if (property.controlType === 'number') {
                ctrl = new NumberProperty(property);
                properties.push(ctrl);
            } else if (property.controlType === 'dynamicdropdown') {
                ctrl = new DynamicDropdownProperty(property);
                properties.push(ctrl);

            }
        });

        properties.sort((a, b) => a.order - b.order);
    }

    setPropertyPagesAndProperties(defaultPropertyPages: any[], propertyPages: any[]) {

        const me = this;

        // for each defaultPropertyPage object, get the properties
        defaultPropertyPages.forEach(function (propertyPage) {

            const newPropertyPage: any = {};

            for (const property in propertyPage) {

                if (propertyPage.hasOwnProperty(property)) {

                    if (property !== 'properties') {

                        newPropertyPage[property] = propertyPage[property];

                    } else {

                        const properties: PropertyBase<any>[] = [];
                        me.setPropertiesAndValues(propertyPage.properties, properties);
                        newPropertyPage['properties'] = properties;
                    }
                }
            }

            propertyPages.push(newPropertyPage);

        });
    }
}


================================================
FILE: src/app/gadgets/_common/gadget-shared.module.ts
================================================
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {GadgetHeaderComponent} from './gadget-header-component';
import {GadgetOperationComponent} from './gadget-operation-control-component';
import {HelpModalComponent} from './help-modal-component';
import {VisDrillDownComponent} from './vis-drill-down-component';
import {DndModule} from 'ng2-dnd';
import {MatProgressBarModule} from '@angular/material';

@NgModule({
    imports: [
        CommonModule,
        DndModule.forRoot(),
        MatProgressBarModule,
    ],
    declarations: [

        GadgetHeaderComponent,
        GadgetOperationComponent,
        HelpModalComponent,
        VisDrillDownComponent

    ],
    exports: [
        GadgetHeaderComponent,
        GadgetOperationComponent,
        HelpModalComponent,
        VisDrillDownComponent
    ]
})
export class GadgetSharedModule {
}


================================================
FILE: src/app/gadgets/_common/help-modal-component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    ViewChild, ElementRef, AfterViewInit, Component, Input
} from '@angular/core';

declare var jQuery: any;

/**
 * Message Modal - clasable modal with message
 *
 * Selector message-modal
 *
 * Methods
 *      popMessageModal - display a message modal for a sepcified duration
 *      showMessageModal - show the message modal
 *      hideMessageModal - hide the message modal
 */
@Component({
    selector: 'app-help-modal',
    moduleId: module.id,
    templateUrl: './help-modal.html',

})
export class HelpModalComponent implements AfterViewInit {

    @Input() topic: any;

    modalicon: string;
    modalheader: string;
    modalconfig: string;

    @ViewChild('helpmodal_tag') helpmodalaRef: ElementRef;
    configModal: any;


    constructor() {
    }


    showMessageModal(icon: string, header: string, message: string) {
        this.modalicon = icon;
        this.modalheader = header;
        this.modalconfig = message;
        this.configModal.modal('show');

    }


    hideMessageModal() {
        this.modalicon = '';
        this.modalheader = '';
        this.modalconfig = '';
        this.configModal.modal('hide');
    }


    ngAfterViewInit() {
        this.configModal = jQuery(this.helpmodalaRef.nativeElement);
        this.configModal.modal('hide');
    }

    showHelp() {

        this.showMessageModal(null, 'Help', 'Get me out of here!');

    }

}


================================================
FILE: src/app/gadgets/_common/help-modal.html
================================================
<div class="ui long modal" #helpmodal_tag>
    <div class="header">
        Help
    </div>

    <div class="ui basic segment">
        <br>
        <br>
        <p></p>

        <!--
            <h3 style="font-weight:600 !important">{{topic.heading}}</h3>
            <div *ngFor="let detail of topic.details" class="ui segment">
                <h4 style="font-weight:500 !important">{{detail.category}}</h4>

                <div class="ui divided items">
                    <div class="item" *ngFor="let article of detail.articles">
                        <div class="content">
                            <h5>{{article.headline}}</h5>
                            <div class="description">
                                <p>{{article.description}}</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
-->
        <br><br>
    </div>
    <div class="actions">
        <div class="ui approve button">Close</div>
    </div>
</div>

================================================
FILE: src/app/gadgets/_common/igadget.ts
================================================
/**
 * Created by jayhamilton on 2/25/17.
 */
interface IGadget {

    run();

    stop();

    toggleConfigMode();

    initializeProperties();

    updateProperties(updatedProperties: any);

    updateData(data: any[]);

    handleError(error: any);

    remove();

    showGadgetControls(enable: boolean);

    configureGadget(instanceId: number, config: any, tags: Array<any>);

    updateGadgetWithGlobalOptions(options:any);


}


================================================
FILE: src/app/gadgets/_common/styles-gadget.css
================================================
.gadget {
    margin-bottom: 15px !important;
    min-height: inherit !important;
    font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, 'Lucida Grande', sans-serif;
    color: grey;
}

:host /deep/ div:not(.proppages) {
    margin-left: auto;
    margin-right: auto;
    display: block !important
}

.ui.form .field > label {
    font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, 'Lucida Grande', sans-serif;
    font-size: 1.3em !important;
    font-weight: 300;
    color: grey;
}

#bt {
    text-align: center !important
}

input {
    padding: 5px;
    border: none !important;
    width: 75% !important;
    font-weight: 300 !important;
    font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, 'Lucida Grande', sans-serif;
    font-size: 1.3em !important;
    outline: none !important;
}

.ct-title {
    color: #585858 !important;
    font-size: 1.5em !important;
    font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, 'Lucida Grande', sans-serif;
    text-align: left !important;
    font-weight: 500 !important;
}

.ui.top.left.floated.label, .ui.top.attached.label {
    background-color: white;
}

hr {
    font-weight: 300 !important;
    height: 1px;
    border-style: solid;
    color: black;

}

.ui[class*="top attached"].label:before {
    content: "";
    position: absolute;
    left: 2%;
    bottom: 5px;
    height: 1px;
    width: 95%; /* or 100px */
    border-bottom: 0px solid #d0d3d6;
}

.spacer {
    height: 2em;
}

.ui.items > .item > .content > .description {
    color: darkgray !important;
}

.suggestions > li {

    background-color: white !important;

}

td {
    font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, 'Lucida Grande', sans-serif;
    color: grey;
}

th {
    font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, 'Lucida Grande', sans-serif;
    color: #336699;
}

.example-full-width {
    width: 100%;
}

h4 {
    font-weight: 400;
}

.ui.segment {

    border: none;
}


================================================
FILE: src/app/gadgets/_common/vis-drill-down-component.ts
================================================
/**
 * Created by jayhamilton on 1/24/17.
 */
import {
    ViewChild, ElementRef, AfterViewInit, Component
} from '@angular/core';

import {
    style, state, trigger, animate, transition
} from '@angular/animations';

import {Facet} from '../../facet/facet-model';


declare var jQuery: any;

/**
 * Message Modal - clasable modal with message
 *
 * Selector message-modal
 *
 * Methods
 *      popMessageModal - display a message modal for a sepcified duration
 *      showMessageModal - show the message modal
 *      hideMessageModal - hide the message modal
 */
@Component({
    selector: 'app-vis-drill-down-modal',
    moduleId: module.id,
    templateUrl: './vis-drill-down.html',
    animations: [

        trigger('contentSwitch', [
            state('inactive', style({
                opacity: 0
            })),
            state('active', style({
                opacity: 1
            })),
            transition('inactive => active', animate('750ms ease-in')),
            transition('active => inactive', animate('750ms ease-out'))
        ]),
        trigger('tabSwitch', [
            state('inactive', style({
                opacity: .75
            })),
            state('active', style({
                opacity: 1
            })),
            transition('inactive => active', animate('750ms ease-in')),
            transition('active => inactive', animate('750ms ease-out'))
        ])
    ]


})
export class VisDrillDownComponent implements AfterViewInit {

    modalicon: string;
    modalheader: string;
    modalconfig: string;
    vms: any[];
    objectList: any[] = [];
    objectTitleList: string[] = [];
    placeHolderText = 'Begin typing vm name';
    layoutColumnOneWidth = 'six';
    layoutColumnTwoWidth = 'ten';
    facetTags: Array<Facet> = [];

    @ViewChild('vismodal_tag') vismodalaRef: ElementRef;
    configModal: any;


    constructor() {

    }

    showMessageModal(icon: string, header: string, message: string) {
        this.modalicon = icon;
        this.modalheader = header;
        this.modalconfig = message;
        this.configModal.modal('show');

    }


    hideMessageModal() {
        this.modalicon = '';
        this.modalheader = '';
        this.modalconfig = '';
        this.configModal.modal('hide');
    }


    ngAfterViewInit() {
        this.configModal = jQuery(this.vismodalaRef.nativeElement);
        this.configModal.modal('hide');
    }

    showDrillDownDetail($event) {

        const data: string = JSON.stringify($event, null, 4);
        this.showMessageModal(null, 'Detail', data);


    }

    showDetail($event) {

        const data: string = JSON.stringify($event, null, 4);
        this.showMessageModal(null, 'Detail', data);


    }

}


================================================
FILE: src/app/gadgets/_common/vis-drill-down.html
================================================
<div class="ui long modal" #vismodal_tag>
    <div class="header">
        <h2>{{modalheader}}</h2>
    </div>


    <div class="content">

        {{modalconfig}}

    </div>


    <div class="actions">
        <div class="ui approve button">Close</div>
    </div>
</div>

================================================
FILE: src/app/gadgets/barchart/barchart-gadget.component.ts
================================================
import {ChangeDetectorRef, Component, ElementRef, ViewChild} from '@angular/core';
import {GadgetInstanceService} from '../../grid/grid.service';
import {RuntimeService} from '../../services/runtime.service';
import {GadgetPropertyService} from '../_common/gadget-property.service';
import {EndPointService} from '../../configuration/tab-endpoint/endpoint.service';
import {GadgetBase} from '../_common/gadget-base';
import {BarChartService} from './service';
import {Router} from '@angular/router';
import {OptionsService} from "../../configuration/tab-options/service";
import {startWith, switchMap} from "rxjs/operators";
import {interval} from "rxjs";
import {ConfigurationService} from "../../services/configuration.service";

declare var jQuery: any;

@Component({
    selector: 'app-dynamic-component',
    moduleId: module.id,
    templateUrl: './view.html',
    styleUrls: ['../_common/styles-gadget.css']
})

export class BarChartGadgetComponent extends GadgetBase {

    @ViewChild('chartOptionsSideBar_tag') chartOptionsSideBarRef: ElementRef;
    chartOptionsSideBar: any;

    // chart options
    showXAxis: boolean;
    showYAxis: boolean;
    gradient: boolean;
    showLegend: boolean;
    showXAxisLabel: boolean;
    showYAxisLabel: boolean;
    barChartType: string;
    showDataLabel: boolean;
    yAxisLabel: string;
    xAxisLabel: string;
    view: any[];
    colorScheme: any = {
        domain: ['#0AFF16', '#B2303B'] //todo - control color from property page
    };
    //////////////////

    data: any[] = [];
    subscription: any;
    state: string;

    RUN_STATE = 'run';
    STOP_STATE = 'stop';
    POLL_INTERVAL = 15000;


    constructor(protected _runtimeService: RuntimeService,
                protected _gadgetInstanceService: GadgetInstanceService,
                protected _propertyService: GadgetPropertyService,
                protected _endPointService: EndPointService,
                protected _barChartService: BarChartService,
                private _changeDetectionRef: ChangeDetectorRef,
                protected _optionsService: OptionsService,
                private _configService: ConfigurationService,
                private _route: Router
    ) {
        super(_runtimeService,
            _gadgetInstanceService,
            _propertyService,
            _endPointService,
            _changeDetectionRef,
            _optionsService);

    }

    public preRun() {

        /**
         * the base class initializes the common property gadgets. Prerun gives
         * us a chance to initialize any of the gadgets unique properties.
         */
        this.initializeTheRemainderOfTheProperties();

        if (this.getPropFromPropertyPages('state') == this.RUN_STATE) {
            this.run();
        }
    }

    initializeTheRemainderOfTheProperties() {

        this.gradient = this.getPropFromPropertyPages('gradient');
        this.showXAxis = this.getPropFromPropertyPages('showXAxis');
        this.showYAxis = this.getPropFromPropertyPages('showYAxis');
        this.showLegend = this.getPropFromPropertyPages('showLegend');
        this.showXAxisLabel = this.getPropFromPropertyPages('showXAxisLabel');
        this.showYAxisLabel = this.getPropFromPropertyPages('showYAxisLabel');
        this.barChartType = this.getPropFromPropertyPages('barChartType');
        this.showDataLabel = this.getPropFromPropertyPages('showDataLabel');
        this.yAxisLabel = this.getPropFromPropertyPages('yAxisLabel');
        this.xAxisLabel = this.getPropFromPropertyPages('xAxisLabel');

    }


    public run() {

        this.clearChartData();
        this.initializeRunState(true);
        this.updateData(null);
        this.saveState(this.RUN_STATE);

    }

    clearChartData() {
        this.data = [];
    }


    public stop() {

        this.stopWithoutStateSave();
        this.saveState(this.STOP_STATE);
    }

    /**
     * The state is being saved to allow the board to load with the last state. Also, when the gadget is moved
     * within the board we need to carry the gadget's state along.
     * @param state
     */
    public saveState(state: string) {

        this.updateProperties('{\"state\":\"' + state + '\"}');
        this.persistTheChangeInInternalState();

    }

    /**
     * When the gadget is destroyed (see ngOnDestroy) there is no need to
     * save the state. We just want to stop any API calls.
     */
    public stopWithoutStateSave() {
        if (this.subscription) {
            this.subscription.unsubscribe();
        }
        const data = [];
        Object.assign(this, {data});
        this.setStopState(false);

    }

    public updateData(someData: any[]) {
        this.data.length = 0;

        /**
         * poll every 15 seconds
         * todo - change this to a websocket
         */
        this.subscription = interval(this.POLL_INTERVAL).pipe(
            startWith(0), switchMap(() => this._barChartService.getData(this.endpointObject.address)))
            .subscribe(data => {

                    Object.assign(this, {data});
                },
                error => this.handleError(error));
    }

    public drillDown(data) {

        this.stopWithoutStateSave();

        this._route.navigate(['/detail'], {
            queryParams:
                {
                    chartType:"bar",
                    chartSeries: data.series,
                    chartMetric: data.name,
                    endPointName: this.endpointObject.name
                }
        });
    }


    private setInternalProperties(updatedPropsObject: any) {

        this.state = updatedPropsObject.state;

        if (updatedPropsObject.title != undefined) {

            this.title = updatedPropsObject.title;
            this.showXAxis = updatedPropsObject.showXAxis;
            this.showYAxis = updatedPropsObject.showYAxis;
            this.gradient = updatedPropsObject.gradient;
            this.showLegend = updatedPropsObject.showLegend;
            this.showXAxisLabel = updatedPropsObject.showXAxisLabel;
            this.showYAxisLabel = updatedPropsObject.showYAxisLabel;
            this.barChartType = updatedPropsObject.barChartType;
            this.showDataLabel = updatedPropsObject.showDataLabel;
            this.xAxisLabel = updatedPropsObject.xAxisLabel;
            this.yAxisLabel = updatedPropsObject.yAxisLabel;
            this.setEndPoint(updatedPropsObject.endpoint);
            this.showOperationControls = true;
        }
    }

    /**
     * todo
     *  This is called from the dynamic property page form or when the internal running state changes
     *  A similar operation exists on the procmman-config-service
     *  whenever the property page form is saved, the in memory board model
     *  is updated as well as the gadget instance properties
     *  which is what the code below does. This can be eliminated with code added to the
     *  config service or the property page service.
     *
     * **/
    public updateProperties(updatedProperties: any) {

        const updatedPropsObject = JSON.parse(updatedProperties);


        /**
         * update this tools property pages
         */
        this.propertyPages.forEach(function (propertyPage) {


            for (let x = 0; x < propertyPage.properties.length; x++) {

                for (const prop in updatedPropsObject) {
                    if (updatedPropsObject.hasOwnProperty(prop)) {
                        if (prop === propertyPage.properties[x].key) {
                            propertyPage.properties[x].value = updatedPropsObject[prop];
                        }

                    }
                }
            }
        });

        /**
         * update the tools internal state
         */
        this.setInternalProperties(updatedPropsObject);

    }

    public ngOnDestroy() {

        this.stopWithoutStateSave();
    }


    /**
     * todo - need to improve how internal state is saved to persistant store
     */
    private persistTheChangeInInternalState() {
        let payLoad =
            "{\"instanceId\":" + this.instanceId
            + ",\"title\":\"" + this.title
            + "\",\"state\":\"" + this.state
            + "\",\"endpoint\":\"" + this.endpointObject.name
            + "\",\"gradient\":" + this.gradient
            + ",\"showXAxis\":" + this.showXAxis
            + ",\"showYAxis\":" + this.showYAxis
            + ",\"showLegend\":" + this.showLegend
            + ",\"showXAxisLabel\":" + this.showXAxisLabel
            + ",\"showYAxisLabel\":" + this.showYAxisLabel
            + ",\"showDataLabel\":" + this.showDataLabel
            + ",\"barChartType\":\"" + this.barChartType
            + "\",\"yAxisLabel\":\"" + this.yAxisLabel
            + "\",\"xAxisLabel\":\"" + this.xAxisLabel
            + "\"}";


        this._configService.notifyGadgetOnPropertyChange(payLoad, this.instanceId);

    }

    toggleChartProperties() {

        if (this.globalOptions.displayGadgetOptionsInSideBar == false) {
            this.toggleConfigMode();
            return;
        }
        this.chartOptionsSideBar = jQuery(this.chartOptionsSideBarRef.nativeElement);
        this.chartOptionsSideBar.sidebar('setting', 'transition', 'overlay');
        this.chartOptionsSideBar.sidebar('toggle');

    }

}


================================================
FILE: src/app/gadgets/barchart/service.ts
================================================
/**
 * Created by jayhamilton on 6/24/17.
 */

import {Injectable} from '@angular/core';
import {RuntimeService} from '../../services/runtime.service';
import {HttpClient} from '@angular/common/http';
import {catchError} from "rxjs/operators";

@Injectable()
export class BarChartService {

    constructor(private _http: HttpClient) {
    }

    getData(endpoint: string) {
        return this._http.get(endpoint)
            .pipe(
                catchError(RuntimeService.handleError)
            );
    }
}


================================================
FILE: src/app/gadgets/barchart/view.html
================================================
<div class="ui  center aligned segment gadget" dnd-draggable
     [dragEnabled]="true" [dragData]="instanceId" [dropZones]="['c0','c1','c2','c3','r0','r1']">

    <a class="ui left corner label">
        <i class="circle icon" [ngClass]="{'green':inRun, 'yellow':!inRun}"></i>
    </a>

    <app-gadget-header
            (mouseover)="showGadgetControls(true)"
            (mouseleave)="showGadgetControls(false)"
            [globalOptions]="globalOptions"
            [title]="title"
            [inRun]="inRun"
            [inConfig]="inConfig"
            [actionInitiated]="actionInitiated"
            [showOperationControls]="showOperationControls"
            [gadgetHasOperationControls]="gadgetHasOperationControls"
            [showConfigurationControl]="showConfigurationControl"
            [showControls]="showControls"
            (toggleConfigModeEvent)="toggleChartProperties()"
            (removeEvent)="
Download .txt
gitextract_fareezle/

├── .gitignore
├── LICENSE
├── README.md
├── angular.json
├── build.sh
├── e2e/
│   ├── app.e2e-spec.ts
│   ├── app.po.ts
│   └── tsconfig.e2e.json
├── karma.conf.js
├── ngx-dynamic-dashboard-framework.iml
├── package.json
├── protractor.conf.js
├── semantic.json
├── src/
│   ├── app/
│   │   ├── about/
│   │   │   ├── about-component.ts
│   │   │   ├── about.module.ts
│   │   │   ├── model.ts
│   │   │   ├── service.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── add-gadget/
│   │   │   ├── add-gadget-component.ts
│   │   │   ├── add-gadget.module.ts
│   │   │   ├── gadget-factory.ts
│   │   │   ├── gadgetLibraryResponse.ts
│   │   │   ├── service.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── api-token/
│   │   │   └── api-token.service.ts
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   ├── app.module.ts
│   │   ├── board/
│   │   │   ├── board.component.ts
│   │   │   ├── board.module.ts
│   │   │   └── view.html
│   │   ├── configuration/
│   │   │   ├── configuration-component.ts
│   │   │   ├── configuration.module.ts
│   │   │   ├── styles.css
│   │   │   ├── tab-artificial-intelligence/
│   │   │   │   ├── ai-configuration-tab.component.ts
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tab-boards/
│   │   │   │   ├── boards-configuration-tab.component.ts
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tab-endpoint/
│   │   │   │   ├── endpoint-configuration-tab.component.ts
│   │   │   │   ├── endpoint.help.ts
│   │   │   │   ├── endpoint.model.ts
│   │   │   │   ├── endpoint.service.ts
│   │   │   │   ├── endpointDetail.component.ts
│   │   │   │   ├── endpointDetail.html
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tab-options/
│   │   │   │   ├── options-configuration-tab.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   ├── styles.css
│   │   │   │   └── view.html
│   │   │   ├── tabs.model.ts
│   │   │   └── view.html
│   │   ├── datalist/
│   │   │   ├── action-model.ts
│   │   │   ├── data-list.component.ts
│   │   │   ├── data-list.module.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── detail/
│   │   │   ├── detail.component.ts
│   │   │   ├── detail.model.ts
│   │   │   ├── detail.module.ts
│   │   │   ├── detail.resolver.ts
│   │   │   ├── filter.pipe.ts
│   │   │   ├── service.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── dynamic-form/
│   │   │   ├── dynamic-form-module.ts
│   │   │   ├── dynamic-form-property.component.html
│   │   │   ├── dynamic-form-property.component.ts
│   │   │   ├── dynamic-form.component.html
│   │   │   ├── dynamic-form.component.ts
│   │   │   ├── property-base.ts
│   │   │   ├── property-checkbox.ts
│   │   │   ├── property-control.service.ts
│   │   │   ├── property-dropdown.ts
│   │   │   ├── property-dynamicdropdown.ts
│   │   │   ├── property-hidden.ts
│   │   │   ├── property-number.ts
│   │   │   ├── property-textbox.ts
│   │   │   └── styles-props.css
│   │   ├── error/
│   │   │   ├── error-handler.component.ts
│   │   │   ├── error-handler.ts
│   │   │   ├── error-model.ts
│   │   │   ├── error.module.ts
│   │   │   ├── styles-error.css
│   │   │   └── view.html
│   │   ├── facet/
│   │   │   ├── capitalize-first-character-pipe.ts
│   │   │   ├── facet-component.ts
│   │   │   ├── facet-model.ts
│   │   │   ├── facet-tag-processor.ts
│   │   │   ├── facet.module.ts
│   │   │   ├── filter-list-component.ts
│   │   │   ├── filter-tag-component.ts
│   │   │   └── styles.css
│   │   ├── gadgets/
│   │   │   ├── _common/
│   │   │   │   ├── base-chart-models/
│   │   │   │   │   ├── bar.model.ts
│   │   │   │   │   └── series.model.ts
│   │   │   │   ├── gadget-base.ts
│   │   │   │   ├── gadget-config-model.ts
│   │   │   │   ├── gadget-header-component.ts
│   │   │   │   ├── gadget-header.html
│   │   │   │   ├── gadget-operation-control-component.ts
│   │   │   │   ├── gadget-property.service.ts
│   │   │   │   ├── gadget-shared.module.ts
│   │   │   │   ├── help-modal-component.ts
│   │   │   │   ├── help-modal.html
│   │   │   │   ├── igadget.ts
│   │   │   │   ├── styles-gadget.css
│   │   │   │   ├── vis-drill-down-component.ts
│   │   │   │   └── vis-drill-down.html
│   │   │   ├── barchart/
│   │   │   │   ├── barchart-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── bubble/
│   │   │   │   ├── bubble-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── cpu/
│   │   │   │   ├── cpu-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── cpum/
│   │   │   │   ├── cpu.model.ts
│   │   │   │   ├── cpum-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── disk/
│   │   │   │   ├── disk-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── donut/
│   │   │   │   ├── donut-gadget.component.ts
│   │   │   │   ├── drill-down-component.ts
│   │   │   │   ├── drill-down-style.css
│   │   │   │   ├── drill-down.html
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── edge-service-list/
│   │   │   │   ├── edge-service-list-gadget.component.ts
│   │   │   │   ├── service-list.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── gadget.module.ts
│   │   │   ├── job-analysis/
│   │   │   │   ├── ja.css
│   │   │   │   ├── job-analysis-gadget.component.ts
│   │   │   │   ├── model.json
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── memory/
│   │   │   │   ├── memory-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── news/
│   │   │   │   ├── news-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── piechart/
│   │   │   │   ├── piechart-gadget.component.ts
│   │   │   │   ├── service.ts
│   │   │   │   └── view.html
│   │   │   ├── port-connection/
│   │   │   │   ├── port-connection-gadget.component.ts
│   │   │   │   ├── port-connection.css
│   │   │   │   ├── result-view.component.ts
│   │   │   │   ├── result-view.html
│   │   │   │   ├── service.model.ts
│   │   │   │   ├── service.ts
│   │   │   │   ├── solution-view.component.ts
│   │   │   │   ├── solution-view.html
│   │   │   │   └── view.html
│   │   │   ├── property-list/
│   │   │   │   ├── property-list-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── service-list/
│   │   │   │   ├── service-list-gadget.component.ts
│   │   │   │   ├── service-list.ts
│   │   │   │   └── view.html
│   │   │   ├── statistic/
│   │   │   │   ├── service.ts
│   │   │   │   ├── statistic-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── storage-object-list/
│   │   │   │   ├── service.ts
│   │   │   │   ├── storage-object-list.component.ts
│   │   │   │   ├── style.css
│   │   │   │   └── view.html
│   │   │   ├── todo/
│   │   │   │   ├── service.ts
│   │   │   │   ├── todo-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   ├── trend/
│   │   │   │   ├── service.ts
│   │   │   │   ├── trend-gadget.component.ts
│   │   │   │   └── view.html
│   │   │   └── trend-line/
│   │   │       ├── service.ts
│   │   │       ├── trend-line-gadget.component.ts
│   │   │       └── view.html
│   │   ├── grid/
│   │   │   ├── cell.component.ts
│   │   │   ├── grid.component.ts
│   │   │   ├── grid.html
│   │   │   ├── grid.module.ts
│   │   │   ├── grid.service.ts
│   │   │   └── styles-grid.css
│   │   ├── layout/
│   │   │   ├── layout-component.ts
│   │   │   ├── layout.module.ts
│   │   │   ├── model.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── menu/
│   │   │   ├── IEvent.ts
│   │   │   ├── menu-service.ts
│   │   │   ├── menu.component.ts
│   │   │   ├── menu.module.ts
│   │   │   ├── styles.css
│   │   │   └── view.html
│   │   ├── notification/
│   │   │   ├── notification-component.css
│   │   │   ├── notification-component.html
│   │   │   ├── notification-component.spec.ts
│   │   │   ├── notification-component.ts
│   │   │   ├── notification-service.spec.ts
│   │   │   ├── notification-service.ts
│   │   │   ├── notification.model.ts
│   │   │   ├── notification.module.ts
│   │   │   ├── notificationDetail.component.ts
│   │   │   └── notificationDetail.html
│   │   ├── routing.module.ts
│   │   ├── services/
│   │   │   ├── configuration-sample-boards-prod.model.ts
│   │   │   ├── configuration-sample-boards.model.ts
│   │   │   ├── configuration-sample-default-board.ts
│   │   │   ├── configuration.service.ts
│   │   │   ├── runtime.service.ts
│   │   │   └── websocket-service.ts
│   │   ├── toast/
│   │   │   ├── message.ts
│   │   │   ├── reverse.pipe.spec.ts
│   │   │   ├── reverse.pipe.ts
│   │   │   ├── toast.component.css
│   │   │   ├── toast.component.html
│   │   │   ├── toast.component.spec.ts
│   │   │   ├── toast.component.ts
│   │   │   ├── toast.module.ts
│   │   │   ├── toast.service.spec.ts
│   │   │   └── toast.service.ts
│   │   └── typeahead-input/
│   │       ├── styles.css
│   │       ├── typeahead-input.component.ts
│   │       ├── typeahead-input.module.ts
│   │       └── view.html
│   ├── assets/
│   │   ├── .gitkeep
│   │   └── api/
│   │       ├── chart-mock-bar-model.json
│   │       ├── chart-mock-bubble-model.json
│   │       ├── chart-mock-pie-model.json
│   │       ├── connection-model.json
│   │       ├── cpu-model.json
│   │       ├── disk-help-model.json
│   │       ├── disk-model.json
│   │       ├── donut-model.json
│   │       ├── gadget-library-model-prod.json
│   │       ├── gadget-library-model.json
│   │       ├── http-codes.json
│   │       ├── news-model.json
│   │       ├── port-model.json
│   │       ├── stat-database-model.json
│   │       ├── stat-job-model.json
│   │       ├── stat-undefined-model.json
│   │       ├── stat-vm-model.json
│   │       ├── stat-volume-model.json
│   │       ├── storage-model.json
│   │       ├── todo-model.json
│   │       ├── trend-model.json
│   │       ├── trendline-help-model.json
│   │       └── version-model.json
│   ├── environments/
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.css
│   ├── test.ts
│   ├── tsconfig.app.json
│   ├── tsconfig.spec.json
│   └── typings.d.ts
├── tsconfig.json
└── tslint.json
Download .txt
SYMBOL INDEX (655 symbols across 134 files)

FILE: e2e/app.po.ts
  class NgADFPage (line 3) | class NgADFPage {
    method navigateTo (line 4) | navigateTo() {
    method getParagraphText (line 8) | getParagraphText() {

FILE: protractor.conf.js
  method onPrepare (line 27) | onPrepare() {

FILE: src/app/about/about-component.ts
  class AboutComponent (line 29) | class AboutComponent implements AfterViewInit {
    method constructor (line 37) | constructor(private _aboutService: AboutService) {
    method ngAfterViewInit (line 43) | ngAfterViewInit() {
    method getVersion (line 49) | getVersion() {

FILE: src/app/about/about.module.ts
  class AboutModule (line 14) | class AboutModule {

FILE: src/app/about/service.ts
  class AboutService (line 8) | class AboutService {
    method constructor (line 12) | constructor(private _http: HttpClient) {
    method getAPIVersion (line 17) | getAPIVersion() {

FILE: src/app/add-gadget/add-gadget-component.ts
  class AddGadgetComponent (line 48) | class AddGadgetComponent implements AfterViewInit {
    method constructor (line 72) | constructor(private _addGadgetService: AddGadgetService) {
    method actionHandler (line 77) | actionHandler(actionItem, actionName) {
    method showMessageModal (line 84) | showMessageModal(icon: string, header: string, message: string) {
    method showComponentLibraryModal (line 92) | showComponentLibraryModal(header: string) {
    method hideMessageModal (line 98) | hideMessageModal() {
    method ngAfterViewInit (line 105) | ngAfterViewInit() {
    method getObjectList (line 109) | getObjectList() {

FILE: src/app/add-gadget/add-gadget.module.ts
  class AddGadgetModule (line 26) | class AddGadgetModule {

FILE: src/app/add-gadget/gadget-factory.ts
  class GadgetFactory (line 25) | class GadgetFactory {
    method getComponentType (line 34) | static getComponentType(gadgetType): any {

FILE: src/app/add-gadget/gadgetLibraryResponse.ts
  type GadgetLibraryResponse (line 1) | interface GadgetLibraryResponse {

FILE: src/app/add-gadget/service.ts
  class AddGadgetService (line 9) | class AddGadgetService {
    method constructor (line 13) | constructor(private _http: HttpClient) {
    method getGadgetLibrary (line 17) | getGadgetLibrary() {

FILE: src/app/api-token/api-token.service.ts
  class APITokenService (line 5) | class APITokenService {
    method constructor (line 10) | constructor(private _http: HttpClient) {
    method getAPITokenForCredentials (line 13) | public getAPITokenForCredentials(_credentials: any) {
    method setAPIToken (line 25) | public setAPIToken(apiToken: string) {
    method getAPIToken (line 29) | public getAPIToken() {
  function B64encode (line 34) | function B64encode(data: string) {

FILE: src/app/app.component.ts
  class AppComponent (line 8) | class AppComponent {

FILE: src/app/app.module.ts
  class AppModule (line 30) | class AppModule {

FILE: src/app/board/board.component.ts
  class BoardComponent (line 11) | class BoardComponent {

FILE: src/app/board/board.module.ts
  class BoardModule (line 56) | class BoardModule {

FILE: src/app/configuration/configuration-component.ts
  class ConfigurationComponent (line 48) | class ConfigurationComponent implements AfterViewInit {
    method constructor (line 69) | constructor() {
    method showConfigurationModal (line 78) | showConfigurationModal(header: string) {
    method hideMessageModal (line 83) | hideMessageModal() {
    method createBoard (line 90) | createBoard(name: string) {
    method editBoard (line 98) | editBoard(name: string) {
    method deleteBoard (line 102) | deleteBoard(name: string) {
    method ngAfterViewInit (line 107) | ngAfterViewInit() {
    method setCurrentTab (line 112) | setCurrentTab(tab_index) {

FILE: src/app/configuration/configuration.module.ts
  class ConfigurationModule (line 60) | class ConfigurationModule {

FILE: src/app/configuration/tab-artificial-intelligence/ai-configuration-tab.component.ts
  class AIConfigurationTabComponent (line 17) | class AIConfigurationTabComponent {
    method constructor (line 32) | constructor() {
    method selectChange (line 49) | selectChange(selectControl) {
    method save (line 57) | save() {

FILE: src/app/configuration/tab-boards/boards-configuration-tab.component.ts
  class BoardsConfigurationTabComponent (line 28) | class BoardsConfigurationTabComponent {
    method constructor (line 39) | constructor(private _configurationService: ConfigurationService) {
    method createBoard (line 46) | createBoard(name: string) {
    method editBoard (line 53) | editBoard(name: string) {
    method deleteBoard (line 57) | deleteBoard(name: string) {

FILE: src/app/configuration/tab-endpoint/endpoint-configuration-tab.component.ts
  class EndpointConfigurationTabComponent (line 17) | class EndpointConfigurationTabComponent {
    method constructor (line 26) | constructor(private _endPointService: EndPointService) {
    method setSelectedEndPoint (line 40) | setSelectedEndPoint(endPoint: EndPoint) {
    method createEndPoint (line 44) | createEndPoint(endPoint: EndPoint) {
    method updateEndPoint (line 57) | updateEndPoint(endPoint: EndPoint) {
    method deleteEndPoint (line 64) | deleteEndPoint(endPoint: EndPoint) {
    method persistInMemoryDataToStore (line 94) | persistInMemoryDataToStore() {

FILE: src/app/configuration/tab-endpoint/endpoint.model.ts
  type TAG (line 1) | interface TAG {
  class EndPoint (line 5) | class EndPoint {
    method constructor (line 18) | constructor(name: string,

FILE: src/app/configuration/tab-endpoint/endpoint.service.ts
  class EndPointService (line 12) | class EndPointService {
    method constructor (line 15) | constructor(private _http: HttpClient) {
    method getEndPoints (line 18) | getEndPoints() {
    method saveEndPoint (line 80) | saveEndPoint(endpoint: any) {

FILE: src/app/configuration/tab-endpoint/endpointDetail.component.ts
  class EndPointDetailComponent (line 23) | class EndPointDetailComponent implements OnChanges, AfterViewInit {
    method addTag (line 50) | addTag(event: MatChipInputEvent): void {
    method removeTag (line 69) | removeTag(tag: TAG): void {
    method checkPredefinition (line 80) | checkPredefinition() {
    method ngAfterViewInit (line 92) | ngAfterViewInit() {
    method ngOnChanges (line 97) | ngOnChanges() {
    method populateFormWithCurrentEndpointValues (line 105) | populateFormWithCurrentEndpointValues() {
    method constructor (line 121) | constructor(private fb: FormBuilder) {
    method disableControls (line 136) | disableControls() {
    method enableControls (line 147) | enableControls() {
    method setFormState (line 159) | setFormState() {
    method createForm (line 182) | createForm() {
    method createEndPoint (line 198) | createEndPoint() {
    method updateEndPoint (line 219) | updateEndPoint() {
    method newEndPoint (line 236) | newEndPoint() {
    method resetEndPoint (line 251) | resetEndPoint() {
    method deleteEndPoint (line 256) | deleteEndPoint() {
    method resetForm (line 262) | resetForm() {

FILE: src/app/configuration/tab-options/options-configuration-tab.component.ts
  class OptionsConfigurationTabComponent (line 16) | class OptionsConfigurationTabComponent {
    method constructor (line 21) | constructor(private _optionsService: OptionsService, private _toastSer...
    method onHooverOptionChange (line 27) | onHooverOptionChange(value) {
    method onDisplayGadgetOptionsInSideBarChange (line 38) | onDisplayGadgetOptionsInSideBarChange(value) {

FILE: src/app/configuration/tab-options/service.ts
  class OptionsService (line 6) | class OptionsService {
    method constructor (line 16) | constructor() {
    method getBoardOptions (line 19) | public getBoardOptions() {
    method persistDefautBoardOptions (line 31) | private persistDefautBoardOptions(){
    method setBoardOptions (line 36) | public setBoardOptions(options: any) {
    method listenForGlobalOptionsChanges (line 60) | listenForGlobalOptionsChanges(): Observable<string> {

FILE: src/app/datalist/action-model.ts
  type ActionInterface (line 1) | interface ActionInterface {

FILE: src/app/datalist/data-list.component.ts
  class DataListComponent (line 10) | class DataListComponent {
    method filterListByTags (line 27) | filterListByTags(filterList: string[]) {
    method filterListBySearchString (line 53) | filterListBySearchString(searchString: string) {
    method copyObjectList (line 74) | copyObjectList() {

FILE: src/app/datalist/data-list.module.ts
  class DataListModule (line 25) | class DataListModule {

FILE: src/app/detail/detail.component.ts
  class DetailComponent (line 17) | class DetailComponent implements OnInit {
    method constructor (line 30) | constructor(private _router: Router,
    method ngOnInit (line 43) | ngOnInit() {
    method getObject (line 52) | getObject(record: any) {
    method getObjectsByHateoasLink (line 63) | getObjectsByHateoasLink(detail: any) {
    method getObjectsByMetric (line 88) | getObjectsByMetric(isReload: boolean) {
    method goHome (line 108) | goHome() {
    method gotToRoute (line 112) | gotToRoute(nav: string, disabled: boolean) {
    method clearDetailDisplay (line 129) | clearDetailDisplay() {

FILE: src/app/detail/detail.model.ts
  type DetailModel (line 1) | interface DetailModel {

FILE: src/app/detail/detail.module.ts
  class DetailModule (line 27) | class DetailModule {

FILE: src/app/detail/detail.resolver.ts
  class DetailResolver (line 5) | class DetailResolver implements Resolve <DetailModel> {
    method constructor (line 9) | constructor(detailData: DetailModel) {
    method resolve (line 13) | resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Ob...

FILE: src/app/detail/filter.pipe.ts
  class FilterPipe (line 5) | class FilterPipe implements PipeTransform {
    method transform (line 6) | transform(items: any[], searchText: string): any[] {

FILE: src/app/detail/service.ts
  class DetailService (line 8) | class DetailService {
    method constructor (line 10) | constructor(private _http: HttpClient) {
    method configure (line 16) | configure() {
    method getDetailByChartSeriesSelected (line 23) | getDetailByChartSeriesSelected(chartType: string, chartSeries: string,...
    method getDetail (line 39) | getDetail(url: string) {
    method getRecord (line 48) | getRecord(url: string) {

FILE: src/app/dynamic-form/dynamic-form-module.ts
  class DynamicFormModule (line 25) | class DynamicFormModule {

FILE: src/app/dynamic-form/dynamic-form-property.component.ts
  class DynamicFormPropertyComponent (line 33) | class DynamicFormPropertyComponent implements AfterViewInit {
    method isValid (line 39) | get isValid() {
    method constructor (line 44) | constructor(private endPointService: EndPointService) {
    method updateEndPointList (line 49) | updateEndPointList() {
    method ngAfterViewInit (line 58) | ngAfterViewInit() {

FILE: src/app/dynamic-form/dynamic-form.component.ts
  class DynamicFormComponent (line 54) | class DynamicFormComponent implements OnInit, AfterViewInit {
    method constructor (line 69) | constructor(private pcs: PropertyControlService,
    method ngAfterViewInit (line 76) | ngAfterViewInit(): void {
    method ngOnInit (line 81) | ngOnInit() {
    method onSubmit (line 87) | onSubmit() {
    method setCurrentTab (line 106) | setCurrentTab(tab) {
    method isPropertyPageValid (line 111) | get isPropertyPageValid (){

FILE: src/app/dynamic-form/property-base.ts
  class PropertyBase (line 4) | class PropertyBase<T> {
    method constructor (line 13) | constructor(props: {

FILE: src/app/dynamic-form/property-checkbox.ts
  class CheckboxProperty (line 7) | class CheckboxProperty extends PropertyBase<boolean> {
    method constructor (line 12) | constructor(options: {} = {}) {

FILE: src/app/dynamic-form/property-control.service.ts
  class PropertyControlService (line 8) | class PropertyControlService {
    method constructor (line 10) | constructor() {
    method toFormGroupFromPP (line 14) | toFormGroupFromPP(propertyPages: any[]) {

FILE: src/app/dynamic-form/property-dropdown.ts
  class DropdownProperty (line 6) | class DropdownProperty extends PropertyBase<string> {
    method constructor (line 11) | constructor(options: {} = {}) {

FILE: src/app/dynamic-form/property-dynamicdropdown.ts
  class DynamicDropdownProperty (line 6) | class DynamicDropdownProperty extends PropertyBase<string> {
    method constructor (line 11) | constructor(options: {} = {}) {

FILE: src/app/dynamic-form/property-hidden.ts
  class HiddenProperty (line 7) | class HiddenProperty extends PropertyBase<string> {
    method constructor (line 12) | constructor(options: {} = {}) {

FILE: src/app/dynamic-form/property-number.ts
  class NumberProperty (line 7) | class NumberProperty extends PropertyBase<number> {
    method constructor (line 12) | constructor(options: {} = {}) {

FILE: src/app/dynamic-form/property-textbox.ts
  class TextboxProperty (line 6) | class TextboxProperty extends PropertyBase<string> {
    method constructor (line 11) | constructor(options: {} = {}) {

FILE: src/app/error/error-handler.component.ts
  class ErrorHandlerComponent (line 32) | class ErrorHandlerComponent {
    method constructor (line 36) | constructor() {
    method closeMessage (line 39) | public closeMessage() {

FILE: src/app/error/error-handler.ts
  class ErrorHandler (line 6) | class ErrorHandler {
    method getErrorObject (line 8) | static getErrorObject(errMsg: any) {
    method getSolutionList (line 24) | static getSolutionList(errMsg: string) {
    method getErrorType (line 60) | static getErrorType(errMsg: string): string {
    method getWebSocketErrorReason (line 80) | static getWebSocketErrorReason(error: any) {

FILE: src/app/error/error-model.ts
  class ErrorObject (line 4) | class ErrorObject {
    method constructor (line 9) | constructor(detail: string, summary: string, solutions: SolutionObject...
  class SolutionObject (line 17) | class SolutionObject {
    method constructor (line 21) | constructor(summary, articleId, link) {

FILE: src/app/error/error.module.ts
  class ErrorHandlerModule (line 12) | class ErrorHandlerModule {

FILE: src/app/facet/capitalize-first-character-pipe.ts
  class CapitalizeFirstPipe (line 15) | class CapitalizeFirstPipe implements PipeTransform {
    method transform (line 16) | transform(value: string, args: any[]): string {

FILE: src/app/facet/facet-component.ts
  class FacetComponent (line 77) | class FacetComponent implements OnInit {
    method constructor (line 84) | constructor() {
    method ngOnInit (line 87) | ngOnInit() {
    method toggleAccordion (line 95) | toggleAccordion() {
    method tagSelect (line 100) | tagSelect(tagName) {

FILE: src/app/facet/facet-model.ts
  class Facet (line 1) | class Facet {
    method constructor (line 5) | constructor(name: string, tags: Array<Tag>) {
  class Tag (line 12) | class Tag {
    method constructor (line 16) | constructor(name: string) {

FILE: src/app/facet/facet-tag-processor.ts
  class FacetTagProcessor (line 3) | class FacetTagProcessor {
    method constructor (line 8) | constructor(objectList: any[]) {
    method getFacetTags (line 12) | getFacetTags() {
    method formatAndUpdateTagList (line 24) | formatAndUpdateTagList(items: any[]) {
    method createFacetAndAddItToTheFacetTagArray (line 57) | createFacetAndAddItToTheFacetTagArray(tag: any) {
    method createTag (line 70) | createTag(tag) {
    method updateFacetWithTag (line 75) | updateFacetWithTag(tag: any) {
    method capitalize (line 107) | capitalize(value: string) {

FILE: src/app/facet/facet.module.ts
  class FacetModule (line 33) | class FacetModule {

FILE: src/app/facet/filter-list-component.ts
  class FilterListComponent (line 21) | class FilterListComponent {
    method tagSelect (line 25) | tagSelect(tagName) {

FILE: src/app/facet/filter-tag-component.ts
  class FilterTagComponent (line 37) | class FilterTagComponent {
    method constructor (line 43) | constructor() {
    method updateFilterList (line 46) | updateFilterList(filter) {

FILE: src/app/gadgets/_common/base-chart-models/bar.model.ts
  method constructor (line 9) | constructor(name: string, series: Array<Series>) {

FILE: src/app/gadgets/_common/base-chart-models/series.model.ts
  class Series (line 1) | class Series {
    method constructor (line 6) | constructor(name: string, value: number) {

FILE: src/app/gadgets/_common/gadget-base.ts
  method constructor (line 82) | constructor(protected _runtimeService: RuntimeService,
  method ngOnInit (line 103) | public ngOnInit() {
  method ngAfterViewInit (line 108) | public ngAfterViewInit() {
  method initializeState (line 127) | public initializeState() {
  method toggleConfigMode (line 131) | public toggleConfigMode() {
  method initializeProperties (line 140) | public initializeProperties() {
  method handleError (line 157) | public handleError(error: ErrorObject) {
  method initializeRunState (line 167) | public initializeRunState(forceRunState: boolean) {
  method setInRunState (line 177) | public setInRunState() {
  method setStopState (line 183) | public setStopState(longRunningStopAction: boolean) {
  method remove (line 193) | public remove() {
  method showGadgetControls (line 197) | public showGadgetControls(enable: boolean) {
  method configureGadget (line 207) | public configureGadget(instanceId: number, config: any, tags: Array<any>) {
  method setEndPoint (line 224) | protected setEndPoint(endpoint: string) {
  method getEndPoint (line 238) | protected getEndPoint() {
  method setTitle (line 242) | protected setTitle(title: string) {
  method getPropFromPropertyPages (line 246) | protected getPropFromPropertyPages(prop: string) {
  method ngOnDestroy (line 261) | public ngOnDestroy() {
  method updateGadgetWithGlobalOptions (line 265) | public updateGadgetWithGlobalOptions(options:any){

FILE: src/app/gadgets/_common/gadget-config-model.ts
  class GadgetConfigModel (line 7) | class GadgetConfigModel {
    method constructor (line 10) | constructor(config: any) {
  class PropertyPage (line 41) | class PropertyPage {
    method constructor (line 47) | constructor(displayName: string, groupId: string, position: number, pr...

FILE: src/app/gadgets/_common/gadget-header-component.ts
  class GadgetHeaderComponent (line 15) | class GadgetHeaderComponent {
    method remove (line 32) | remove() {
    method toggleConfigMode (line 36) | toggleConfigMode() {
    method run (line 40) | run() {
    method stop (line 46) | stop() {
    method help (line 51) | help(){

FILE: src/app/gadgets/_common/gadget-operation-control-component.ts
  class GadgetOperationComponent (line 31) | class GadgetOperationComponent {
    method run (line 42) | run() {
    method stop (line 46) | stop() {

FILE: src/app/gadgets/_common/gadget-property.service.ts
  class GadgetPropertyService (line 11) | class GadgetPropertyService {
    method constructor (line 13) | constructor() {
    method setPropertiesAndValues (line 16) | setPropertiesAndValues(defaultProperties: any[], properties: PropertyB...
    method setPropertyPagesAndProperties (line 48) | setPropertyPagesAndProperties(defaultPropertyPages: any[], propertyPag...

FILE: src/app/gadgets/_common/gadget-shared.module.ts
  class GadgetSharedModule (line 31) | class GadgetSharedModule {

FILE: src/app/gadgets/_common/help-modal-component.ts
  class HelpModalComponent (line 26) | class HelpModalComponent implements AfterViewInit {
    method constructor (line 38) | constructor() {
    method showMessageModal (line 42) | showMessageModal(icon: string, header: string, message: string) {
    method hideMessageModal (line 51) | hideMessageModal() {
    method ngAfterViewInit (line 59) | ngAfterViewInit() {
    method showHelp (line 64) | showHelp() {

FILE: src/app/gadgets/_common/igadget.ts
  type IGadget (line 4) | interface IGadget {

FILE: src/app/gadgets/_common/vis-drill-down-component.ts
  class VisDrillDownComponent (line 57) | class VisDrillDownComponent implements AfterViewInit {
    method constructor (line 74) | constructor() {
    method showMessageModal (line 78) | showMessageModal(icon: string, header: string, message: string) {
    method hideMessageModal (line 87) | hideMessageModal() {
    method ngAfterViewInit (line 95) | ngAfterViewInit() {
    method showDrillDownDetail (line 100) | showDrillDownDetail($event) {
    method showDetail (line 108) | showDetail($event) {

FILE: src/app/gadgets/barchart/barchart-gadget.component.ts
  class BarChartGadgetComponent (line 23) | class BarChartGadgetComponent extends GadgetBase {
    method constructor (line 54) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 73) | public preRun() {
    method initializeTheRemainderOfTheProperties (line 86) | initializeTheRemainderOfTheProperties() {
    method run (line 102) | public run() {
    method clearChartData (line 111) | clearChartData() {
    method stop (line 116) | public stop() {
    method saveState (line 127) | public saveState(state: string) {
    method stopWithoutStateSave (line 138) | public stopWithoutStateSave() {
    method updateData (line 148) | public updateData(someData: any[]) {
    method drillDown (line 164) | public drillDown(data) {
    method setInternalProperties (line 180) | private setInternalProperties(updatedPropsObject: any) {
    method updateProperties (line 212) | public updateProperties(updatedProperties: any) {
    method ngOnDestroy (line 243) | public ngOnDestroy() {
    method persistTheChangeInInternalState (line 252) | private persistTheChangeInInternalState() {
    method toggleChartProperties (line 275) | toggleChartProperties() {

FILE: src/app/gadgets/barchart/service.ts
  class BarChartService (line 11) | class BarChartService {
    method constructor (line 13) | constructor(private _http: HttpClient) {
    method getData (line 16) | getData(endpoint: string) {

FILE: src/app/gadgets/bubble/bubble-gadget.component.ts
  class BubbleGadgetComponent (line 18) | class BubbleGadgetComponent extends GadgetBase {
    method constructor (line 36) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 53) | public preRun(): void {
    method run (line 58) | public run() {
    method stop (line 66) | public stop() {
    method updateData (line 70) | public updateData(_data: any[]) {
    method drillDown (line 82) | public drillDown(data) {
    method updateProperties (line 86) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/bubble/service.ts
  class BubbleService (line 11) | class BubbleService {
    method constructor (line 13) | constructor(private _http: HttpClient) {
    method getMockData (line 16) | getMockData() {

FILE: src/app/gadgets/cpu/cpu-gadget.component.ts
  class CPUGadgetComponent (line 18) | class CPUGadgetComponent extends GadgetBase {
    method constructor (line 36) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 53) | public preRun(): void {
    method run (line 58) | public run() {
    method stop (line 66) | public stop() {
    method updateData (line 70) | public updateData(data: any[]) {
    method drillDown (line 80) | public drillDown(data) {
    method updateProperties (line 86) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/cpu/service.ts
  class CPUService (line 11) | class CPUService {
    method constructor (line 13) | constructor(private _http: HttpClient) {
    method getMockData (line 16) | getMockData() {

FILE: src/app/gadgets/cpum/cpu.model.ts
  class CPUChartMetric (line 5) | class CPUChartMetric extends Bar {
    method constructor (line 9) | constructor(data: any, name: string, series: Array<Series>) {

FILE: src/app/gadgets/cpum/cpum-gadget.component.ts
  class CPUMGadgetComponent (line 21) | class CPUMGadgetComponent extends GadgetBase implements OnDestroy, OnInit {
    method constructor (line 41) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 57) | public preRun(): void {
    method run (line 60) | public run() {
    method stop (line 118) | public stop() {
    method updateGraph (line 137) | public updateGraph(cpus: Array<any>) {
    method updateData (line 171) | public updateData(data: any[]) {
    method updateProperties (line 175) | public updateProperties(updatedProperties: any) {
    method ngOnDestroy (line 221) | public ngOnDestroy() {

FILE: src/app/gadgets/disk/disk-gadget.component.ts
  class DiskGadgetComponent (line 49) | class DiskGadgetComponent extends GadgetBase {
    method constructor (line 72) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 91) | public preRun(): void {
    method run (line 99) | public run() {
    method stop (line 105) | public stop() {
    method updateData (line 109) | public updateData(data: any[]) {
    method updateProperties (line 129) | public updateProperties(updatedProperties: any) {
    method setTopic (line 167) | setTopic() {
    method toggleAcordion (line 174) | toggleAcordion(): void {

FILE: src/app/gadgets/disk/service.ts
  class DiskService (line 13) | class DiskService {
    method constructor (line 15) | constructor(private _http: HttpClient) {
    method get (line 18) | get() {
    method getHelpTopic (line 25) | getHelpTopic() {
    method getMockData (line 32) | getMockData() {

FILE: src/app/gadgets/donut/donut-gadget.component.ts
  class DonutGadgetComponent (line 50) | class DonutGadgetComponent extends GadgetBase implements OnDestroy {
    method constructor (line 64) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 80) | public preRun(): void {
    method run (line 88) | public run() {
    method stop (line 94) | public stop() {
    method updateData (line 103) | public updateData(data: any[]) {
    method updateProperties (line 118) | public updateProperties(updatedProperties: any) {
    method setTopic (line 147) | setTopic() {
    method setProperties (line 153) | public setProperties() {
    method toggleAccordion (line 160) | toggleAccordion(): void {
    method ngOnDestroy (line 166) | public ngOnDestroy() {

FILE: src/app/gadgets/donut/drill-down-component.ts
  class DrillDownComponent (line 57) | class DrillDownComponent implements AfterViewInit {
    method constructor (line 88) | constructor(private _donutService: DonutService) {
    method showMessageModal (line 92) | showMessageModal(icon: string, header: string, message: string) {
    method hideMessageModal (line 101) | hideMessageModal() {
    method ngAfterViewInit (line 109) | ngAfterViewInit() {
    method showDrillDownDetail (line 114) | showDrillDownDetail($event) {
    method showDetail (line 152) | showDetail($event) {
    method processObjects (line 160) | processObjects(objectsToProcess: any) {
    method updateDropZone1 (line 176) | updateDropZone1(object: any) {
    method updateDropZone2 (line 184) | updateDropZone2(object: any) {
    method updateDropZone3 (line 192) | updateDropZone3(object: any) {
    method setFacets (line 200) | setFacets() {

FILE: src/app/gadgets/donut/service.ts
  class DonutService (line 12) | class DonutService {
    method constructor (line 14) | constructor(private _http: HttpClient) {
    method get (line 17) | get() {
    method getHelpTopic (line 24) | getHelpTopic() {
    method poll (line 32) | poll() {
    method complianceJob (line 40) | complianceJob(event: string) {

FILE: src/app/gadgets/edge-service-list/edge-service-list-gadget.component.ts
  class EdgeServiceListGadgetComponent (line 58) | class EdgeServiceListGadgetComponent extends GadgetBase implements OnDes...
    method constructor (line 90) | constructor(protected _procMonRuntimeService: RuntimeService,
    method preRun (line 111) | public preRun(): void {
    method run (line 115) | public run() {
    method checkPoxySelection (line 174) | public checkPoxySelection() {
    method seedProxiesWithWork (line 180) | public seedProxiesWithWork() {
    method runProxyJob (line 189) | public runProxyJob(uri: string) {
    method stop (line 198) | public stop() {
    method updateData (line 209) | public updateData(data: any[]) {
    method updateProperties (line 225) | public updateProperties(updatedProperties: any) {
    method updateGraph (line 263) | updateGraph() {
    method ngOnDestroy (line 287) | public ngOnDestroy() {
    method toggleAcordion (line 293) | toggleAcordion(): void {

FILE: src/app/gadgets/edge-service-list/service.ts
  class EdgeService (line 8) | class EdgeService {
    method constructor (line 10) | constructor(private _http: HttpClient) {
    method getSelectedProxy (line 13) | getSelectedProxy() {
    method getMicroServices (line 21) | getMicroServices(url: string) {
    method getTaskCount (line 33) | getTaskCount(uri: string) {
    method seedProxiesWithWork (line 41) | seedProxiesWithWork() {
    method runJob (line 48) | runJob(uri: string) {
    method getGraphInfo (line 55) | getGraphInfo() {

FILE: src/app/gadgets/gadget.module.ts
  class GadgetModule (line 140) | class GadgetModule {

FILE: src/app/gadgets/job-analysis/job-analysis-gadget.component.ts
  class JobAnalysisGadgetComponent (line 21) | class JobAnalysisGadgetComponent extends GadgetBase {
    method constructor (line 26) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 49) | public preRun(): void {
    method run (line 52) | public run() {
    method stop (line 57) | public stop() {
    method updateData (line 61) | public updateData(data: any[]) {
    method updateProperties (line 66) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/job-analysis/service.ts
  class JobAnalysisService (line 6) | class JobAnalysisService {
    method constructor (line 8) | constructor(private _http: HttpClient) {
    method get (line 11) | get() {

FILE: src/app/gadgets/memory/memory-gadget.component.ts
  class MemoryGadgetComponent (line 18) | class MemoryGadgetComponent extends GadgetBase implements OnDestroy {
    method constructor (line 31) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 47) | public preRun(): void {
    method run (line 50) | public run() {
    method stop (line 88) | public stop() {
    method updateData (line 105) | public updateData(data: any[]) {
    method updateGraph (line 110) | public updateGraph(value: number) {
    method updateProperties (line 121) | public updateProperties(updatedProperties: any) {
    method ngOnDestroy (line 159) | public ngOnDestroy() {

FILE: src/app/gadgets/news/news-gadget.component.ts
  class NewsGadgetComponent (line 16) | class NewsGadgetComponent extends GadgetBase {
    method constructor (line 24) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 40) | public preRun(): void {
    method run (line 45) | public run() {
    method stop (line 51) | public stop() {
    method updateData (line 55) | public updateData(data: any[]) {
    method updateProperties (line 63) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/news/service.ts
  class NewsService (line 9) | class NewsService {
    method constructor (line 11) | constructor(private _http: HttpClient) {
    method get (line 14) | get() {

FILE: src/app/gadgets/piechart/piechart-gadget.component.ts
  class PieChartGadgetComponent (line 21) | class PieChartGadgetComponent extends GadgetBase {
    method constructor (line 49) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 67) | public preRun() {
    method initializeTheRemainderOfTheProperties (line 80) | initializeTheRemainderOfTheProperties() {
    method run (line 91) | public run() {
    method clearChartData (line 99) | clearChartData() {
    method stop (line 104) | public stop() {
    method saveState (line 115) | public saveState(state: string) {
    method stopWithoutStateSave (line 126) | public stopWithoutStateSave() {
    method updateData (line 136) | public updateData(someData: any[]) {
    method drillDown (line 152) | public drillDown(data) {
    method setInternalProperties (line 157) | private setInternalProperties(updatedPropsObject: any) {
    method updateProperties (line 185) | public updateProperties(updatedProperties: any) {
    method ngOnDestroy (line 215) | public ngOnDestroy() {
    method persistTheChangeInInternalState (line 224) | private persistTheChangeInInternalState() {
    method toggleChartProperties (line 241) | toggleChartProperties() {

FILE: src/app/gadgets/piechart/service.ts
  class PieChartService (line 11) | class PieChartService {
    method constructor (line 13) | constructor(private _http: HttpClient) {
    method getData (line 16) | getData(endpoint: string) {

FILE: src/app/gadgets/port-connection/port-connection-gadget.component.ts
  class PortConnectionGadgetComponent (line 20) | class PortConnectionGadgetComponent extends GadgetBase implements OnDest...
    method constructor (line 28) | constructor(protected _procMonRuntimeService: RuntimeService,
    method preRun (line 44) | public preRun(): void {
    method run (line 50) | public run() {
    method stop (line 61) | public stop() {
    method testConnection (line 65) | public testConnection() {
    method clearState (line 94) | private clearState() {
    method updateData (line 99) | public updateData(data: any[]) {
    method updateProperties (line 102) | public updateProperties(updatedProperties: any) {
    method setUpEndPoints (line 138) | public setUpEndPoints() {
    method setTopic (line 156) | public setTopic() {
    method ngOnDestroy (line 186) | ngOnDestroy() {

FILE: src/app/gadgets/port-connection/result-view.component.ts
  class ResultViewComponent (line 26) | class ResultViewComponent{
    method toggleMessageDetail (line 34) | public toggleMessageDetail(): void {

FILE: src/app/gadgets/port-connection/service.model.ts
  class EndPointModel (line 2) | class EndPointModel {
    method constructor (line 7) | constructor(host: string, port: string) {

FILE: src/app/gadgets/port-connection/service.ts
  class ConnectionService (line 12) | class ConnectionService {
    method constructor (line 16) | constructor(private _http: HttpClient) {
    method configure (line 27) | configure() {
    method testConnectivity (line 46) | testConnectivity(endPoints: Array<EndPointModel>) {

FILE: src/app/gadgets/port-connection/solution-view.component.ts
  class SolutionViewComponent (line 12) | class SolutionViewComponent {

FILE: src/app/gadgets/property-list/property-list-gadget.component.ts
  class PropertyListGadgetComponent (line 16) | class PropertyListGadgetComponent extends GadgetBase implements OnDestroy {
    method constructor (line 22) | constructor(protected _procMonRuntimeService: RuntimeService,
    method preRun (line 37) | public preRun(): void {
    method run (line 40) | public run() {
    method stop (line 44) | public stop() {
    method updateData (line 48) | public updateData(data: any[]) {
    method updateProperties (line 51) | public updateProperties(updatedProperties: any) {
    method ngOnDestroy (line 56) | ngOnDestroy() {

FILE: src/app/gadgets/service-list/service-list-gadget.component.ts
  class ServiceListGadgetComponent (line 34) | class ServiceListGadgetComponent extends GadgetBase implements OnDestroy {
    method constructor (line 45) | constructor(protected _procMonRuntimeService: RuntimeService,
    method preRun (line 62) | public preRun(): void {
    method run (line 65) | public run() {
    method stop (line 71) | public stop() {
    method updateData (line 75) | public updateData(data: any[]) {
    method updateProperties (line 79) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/statistic/service.ts
  class StatisticService (line 9) | class StatisticService {
    method constructor (line 11) | constructor(private _http: HttpClient) {
    method get (line 14) | get(resourceType) {

FILE: src/app/gadgets/statistic/statistic-gadget.component.ts
  class StatisticGadgetComponent (line 16) | class StatisticGadgetComponent extends GadgetBase {
    method constructor (line 24) | constructor(protected _statisticService: StatisticService,
    method preRun (line 41) | public preRun(): void {
    method run (line 46) | public run() {
    method stop (line 52) | public stop() {
    method updateData (line 56) | public updateData(data: any[]) {
    method updateProperties (line 64) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/storage-object-list/service.ts
  class StorageService (line 9) | class StorageService {
    method constructor (line 11) | constructor(private _http: HttpClient) {
    method get (line 14) | get() {

FILE: src/app/gadgets/storage-object-list/storage-object-list.component.ts
  class StorageObjectListComponent (line 32) | class StorageObjectListComponent extends GadgetBase {
    method constructor (line 47) | constructor(protected _runtimeService: RuntimeService,
    method preRun (line 62) | public preRun(): void {
    method run (line 68) | public run() {
    method stop (line 74) | public stop() {
    method updateData (line 78) | public updateData(data: any[]) {
    method updateProperties (line 91) | public updateProperties(updatedProperties: any) {
    method actionHandler (line 126) | actionHandler(actionItem, actionName) {

FILE: src/app/gadgets/todo/service.ts
  class TodoService (line 9) | class TodoService {
    method constructor (line 11) | constructor(private _http: HttpClient) {
    method get (line 14) | get() {

FILE: src/app/gadgets/todo/todo-gadget.component.ts
  class TodoGadgetComponent (line 16) | class TodoGadgetComponent extends GadgetBase {
    method constructor (line 25) | constructor(protected _todoService: TodoService,
    method preRun (line 40) | public preRun(): void {
    method run (line 44) | public run() {
    method stop (line 50) | public stop() {
    method updateData (line 54) | public updateData(data: any[]) {
    method addTodo (line 62) | public addTodo(todo: string) {
    method removeTodo (line 66) | public removeTodo(todoIx: number) {
    method updateProperties (line 72) | public updateProperties(updatedProperties: any) {

FILE: src/app/gadgets/trend-line/service.ts
  class TrendLineService (line 8) | class TrendLineService {
    method seedData (line 9) | static seedData() {
    method retrieveData (line 20) | static retrieveData() {
    method getRandomArbitrary (line 36) | static getRandomArbitrary(min, max) {
    method getDay (line 39) | static getDay(dayOfWeek: number) {
    method constructor (line 58) | constructor(private _http: HttpClient) {
    method get (line 61) | public get(collectors: any[]) {
    method stop (line 75) | public stop(subscription: any) {
    method getHelpTopic (line 79) | getHelpTopic() {

FILE: src/app/gadgets/trend-line/trend-line-gadget.component.ts
  class TrendLineGadgetComponent (line 19) | class TrendLineGadgetComponent extends GadgetBase {
    method constructor (line 46) | constructor(protected _trendLineService: TrendLineService,
    method preRun (line 64) | public preRun(): void {
    method run (line 82) | public run() {
    method stop (line 88) | public stop() {
    method updateData (line 93) | public updateData() {
    method updateProperties (line 110) | public updateProperties(updatedProperties: any) {
    method setHelpTopic (line 159) | private setHelpTopic() {

FILE: src/app/gadgets/trend/service.ts
  class TrendService (line 6) | class TrendService {
    method constructor (line 8) | constructor(private _http: HttpClient) {
    method get (line 11) | get() {

FILE: src/app/gadgets/trend/trend-gadget.component.ts
  class TrendGadgetComponent (line 19) | class TrendGadgetComponent extends GadgetBase {
    method constructor (line 38) | constructor(protected _trendService: TrendService,
    method preRun (line 54) | public preRun(): void {
    method run (line 59) | public run() {
    method stop (line 65) | public stop() {
    method updateData (line 69) | public updateData(data: any[]) {
    method updateProperties (line 77) | public updateProperties(updatedProperties: any) {

FILE: src/app/grid/cell.component.ts
  class CellComponent (line 13) | class CellComponent implements OnInit {
    method constructor (line 20) | constructor(private viewContainerRef: ViewContainerRef,
    method ngOnInit (line 24) | ngOnInit() {

FILE: src/app/grid/grid.component.ts
  class GridComponent (line 16) | class GridComponent {
    method constructor (line 45) | constructor(private _gadgetInstanceService: GadgetInstanceService,
    method removeOldListeners (line 69) | removeOldListeners(){
    method setupEventListeners (line 76) | setupEventListeners() {
    method getGadgetLibrary (line 120) | getGadgetLibrary() {
    method getGadgetFromLibrary (line 131) | getGadgetFromLibrary(gadgetType: string) {
    method addGadgetUsingArtificialIntelligence (line 145) | addGadgetUsingArtificialIntelligence(aiObject: any) {
    method updateGadgetPositionInBoard (line 166) | updateGadgetPositionInBoard($event, columnNumber, rowNumber, type) {
    method createBoard (line 201) | public createBoard(name: string) {
    method editBoard (line 205) | public editBoard(name: string) {
    method deleteBoard (line 209) | public deleteBoard(name: string) {
    method addGadget (line 221) | public addGadget(gadget: any) {
    method updateBoardLayout (line 245) | public updateBoardLayout(structure) {
    method updateGridState (line 292) | private updateGridState() {
    method readColumnsFromOriginalModel (line 318) | private readColumnsFromOriginalModel(_model) {
    method fillGridStructure (line 330) | private fillGridStructure(destinationModelStructure, originalColumns: ...
    method copyGadgets (line 350) | private copyGadgets(source, target) {
    method enableConfigMode (line 361) | public enableConfigMode() {
    method initializeBoard (line 366) | private initializeBoard() {
    method loadBoard (line 384) | private loadBoard(boardTitle: string) {
    method loadDefaultBoard (line 402) | private loadDefaultBoard() {
    method loadNewBoard (line 416) | private loadNewBoard(name: string) {
    method updateServicesAndGridWithModel (line 433) | private updateServicesAndGridWithModel() {
    method saveBoard (line 439) | private saveBoard(operation: string, alertBoardListenerThatTheMenuShou...
    method clearGridModelAndGadgetInstanceStructures (line 456) | private clearGridModelAndGadgetInstanceStructures() {
    method setGadgetInsertPosition (line 467) | private setGadgetInsertPosition() {
    method setModel (line 495) | public setModel(model: any) {
    method getModel (line 500) | public getModel() {

FILE: src/app/grid/grid.module.ts
  class GridModule (line 59) | class GridModule {
    method withComponents (line 60) | static withComponents(components: any[]) {

FILE: src/app/grid/grid.service.ts
  class GadgetInstanceService (line 12) | class GadgetInstanceService {
    method constructor (line 19) | constructor() {
    method addInstance (line 22) | addInstance(gadget: any) {
    method enableConfigureMode (line 37) | enableConfigureMode() {
    method removeInstance (line 44) | removeInstance(id: number) {
    method getInstanceCount (line 81) | getInstanceCount() {
    method setCurrentModel (line 88) | setCurrentModel(model: any) {
    method listenForInstanceRemovedEventsFromGadgets (line 96) | listenForInstanceRemovedEventsFromGadgets(): Observable<string> {
    method addSubscriber (line 100) | addSubscriber(subscriber: any) {
    method unSubscribeAll (line 104) | unSubscribeAll() {
    method clearAllInstances (line 114) | clearAllInstances() {

FILE: src/app/layout/layout-component.ts
  class BoardLayoutManagerComponent (line 28) | class BoardLayoutManagerComponent implements AfterViewInit {
    method constructor (line 39) | constructor() {
    method selectBoardLayout (line 43) | selectBoardLayout(layoutId: number) {
    method ngAfterViewInit (line 55) | ngAfterViewInit() {
    method initializeLayouts (line 59) | initializeLayouts() {

FILE: src/app/layout/layout.module.ts
  class LayoutModule (line 12) | class LayoutModule {

FILE: src/app/menu/IEvent.ts
  type IEvent (line 1) | interface IEvent {

FILE: src/app/menu/menu-service.ts
  class MenuEventService (line 16) | class MenuEventService {
    method constructor (line 22) | constructor() {
    method raiseMenuEvent (line 25) | raiseMenuEvent(event: IEvent) {
    method listenForMenuEvents (line 29) | listenForMenuEvents(): Observable<IEvent> {
    method raiseGridEvent (line 34) | raiseGridEvent(event: IEvent) {
    method listenForGridEvents (line 38) | listenForGridEvents(): Observable<IEvent> {
    method addSubscriber (line 42) | addSubscriber(subscriber:any){
    method unSubscribeAll (line 45) | unSubscribeAll(){

FILE: src/app/menu/menu.component.ts
  class MenuComponent (line 21) | class MenuComponent implements OnInit {
    method constructor (line 44) | constructor(private _configurationService: ConfigurationService,
    method setupEventListeners (line 53) | setupEventListeners() {
    method ngOnInit (line 70) | ngOnInit() {
    method emitBoardChangeLayoutEvent (line 76) | emitBoardChangeLayoutEvent(event) {
    method emitBoardSelectEvent (line 80) | emitBoardSelectEvent(event) {
    method emitBoardCreateEvent (line 85) | emitBoardCreateEvent(event) {
    method emitBoardEditEvent (line 90) | emitBoardEditEvent(event) {
    method emitBoardDeleteEvent (line 94) | emitBoardDeleteEvent(event) {
    method emitBoardAddGadgetEvent (line 99) | emitBoardAddGadgetEvent(event) {
    method emitBoardAIAddGadgetEvent (line 103) | emitBoardAIAddGadgetEvent(event) {
    method updateDashboardMenu (line 107) | updateDashboardMenu(selectedBoard: string) {
    method boardSelect (line 137) | boardSelect(selectedBoard: string) {
    method toggleLayoutSideBar (line 141) | toggleLayoutSideBar() {
    method toggleNotificationSideBar (line 148) | toggleNotificationSideBar() {
    method toggleAboutSideBar (line 153) | toggleAboutSideBar() {
    method showDocumentation (line 160) | public showDocumentation() {

FILE: src/app/menu/menu.module.ts
  class MenuModule (line 47) | class MenuModule {

FILE: src/app/notification/notification-component.ts
  class NotificationComponent (line 11) | class NotificationComponent implements OnInit, AfterViewInit {
    method constructor (line 22) | constructor() {
    method ngOnInit (line 32) | ngOnInit() {
    method ngAfterViewInit (line 35) | ngAfterViewInit() {
    method setSelectedNotificationFilter (line 39) | setSelectedNotificationFilter(item) {

FILE: src/app/notification/notification-service.ts
  class NotificationService (line 4) | class NotificationService {
    method constructor (line 6) | constructor() { }

FILE: src/app/notification/notification.model.ts
  class Notification (line 1) | class Notification {
    method constructor (line 9) | constructor(name: string, description: string) {
    method setState (line 13) | setState(state: string) {
    method getState (line 16) | getState() {
    method setIcon (line 20) | setIcon(icon: string) {
    method getIcon (line 23) | getIcon() {
    method setWhen (line 27) | setWhen(when: string) {
    method getWhen (line 30) | getWhen() {

FILE: src/app/notification/notification.module.ts
  class NotificationModule (line 15) | class NotificationModule {

FILE: src/app/notification/notificationDetail.component.ts
  class NotificationDetailComponent (line 13) | class NotificationDetailComponent {
    method constructor (line 18) | constructor() {

FILE: src/app/routing.module.ts
  class RoutingModule (line 34) | class RoutingModule {

FILE: src/app/services/configuration.service.ts
  class ConfigurationService (line 14) | class ConfigurationService {
    method constructor (line 30) | constructor(private _http: HttpClient) {
    method seedLocalStorageWithSampleBoardCollection (line 39) | private seedLocalStorageWithSampleBoardCollection() {
    method getBoardByTitle (line 53) | public getBoardByTitle(title: string) {
    method getBoards (line 77) | public getBoards() {
    method saveBoard (line 99) | public saveBoard(board: any) {
    method delete (line 149) | private delete(board_collection: any) {
    method deleteBoardFromLocalStore (line 156) | private deleteBoardFromLocalStore(boardTitle: string) {
    method deleteBoard (line 171) | public deleteBoard(boardTitle: string) {
    method getDefaultBoard (line 191) | public getDefaultBoard() {
    method notifyGadgetOnPropertyChange (line 207) | notifyGadgetOnPropertyChange(gadgetConfig: string, instanceId: number) {
    method setCurrentModel (line 213) | setCurrentModel(_currentModel: any) {
    method savePropertyPageConfigurationToStore (line 217) | savePropertyPageConfigurationToStore(gadgetConfig: string, instanceId:...
    method updateProperties (line 246) | updateProperties(updatedProperties: any, gadget: any, instanceId: numb...

FILE: src/app/services/runtime.service.ts
  class RuntimeService (line 13) | class RuntimeService {
    method handleError (line 20) | static handleError(err: HttpErrorResponse | any) {
    method constructor (line 44) | constructor(private _http: HttpClient) {
    method configure (line 48) | configure() {
    method testURLResponse (line 62) | testURLResponse(url: string) {
    method testConnectivity (line 70) | testConnectivity(host: string, port: string) {
    method callWitAI (line 88) | callWitAI(aiStatement: string) {
    method callback (line 110) | callback(data) {
    method callWatsonAI (line 143) | callWatsonAI(aiStatement: string) {

FILE: src/app/services/websocket-service.ts
  class ObservableWebSocketService (line 6) | class ObservableWebSocketService {
    method createObservableWebSocket (line 10) | createObservableWebSocket(url: string): Observable<any> {
    method sendMessage (line 23) | sendMessage(message: string) {

FILE: src/app/toast/message.ts
  class Message (line 1) | class Message {
    method constructor (line 8) | constructor(content, id, style?) {

FILE: src/app/toast/reverse.pipe.ts
  class ReversePipe (line 7) | class ReversePipe implements PipeTransform {
    method transform (line 9) | transform(value: any, args?: any): any {

FILE: src/app/toast/toast.component.ts
  class ToastComponent (line 25) | class ToastComponent implements OnInit {
    method constructor (line 29) | constructor(private _toastService: ToastService) {
    method ngOnInit (line 33) | ngOnInit() {
    method dismiss (line 49) | dismiss(id) {

FILE: src/app/toast/toast.module.ts
  class ToastModule (line 15) | class ToastModule {

FILE: src/app/toast/toast.service.ts
  class ToastService (line 5) | class ToastService {
    method constructor (line 9) | constructor() {
    method getMessages (line 12) | getMessages() {
    method sendMessage (line 16) | sendMessage(content, style) {
    method dismissMessage (line 23) | dismissMessage(messageKey) {
    method purgeDismissedMessages (line 34) | purgeDismissedMessages  () {

FILE: src/app/typeahead-input/typeahead-input.component.ts
  class TypeAheadInputComponent (line 14) | class TypeAheadInputComponent {
    method constructor (line 29) | constructor(myElement: ElementRef, private _runtimeService: RuntimeSer...
    method filter (line 34) | filter() {
    method select (line 52) | select(item) {
    method processAIString (line 58) | processAIString(aiStatement: string) {
    method getAIIntentFromWitAI (line 76) | getAIIntentFromWitAI(aiObject: any) {
    method getAIIntentFromWatson (line 94) | getAIIntentFromWatson(aiObject: any) {

FILE: src/app/typeahead-input/typeahead-input.module.ts
  class TypeAheadInputModule (line 23) | class TypeAheadInputModule {

FILE: src/typings.d.ts
  type NodeModule (line 3) | interface NodeModule {
Condensed preview — 267 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (671K chars).
[
  {
    "path": ".gitignore",
    "chars": 1078,
    "preview": "# Created by .ignore support plugin (hsz.mobi)\n### JetBrains template\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpSt"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) [year] [fullname]\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 15767,
    "preview": "\n# NGX Dynamic Dashboard Framework\n\n## Natural Language Processing (NLP) integration\n![Image of Main Screen](https://git"
  },
  {
    "path": "angular.json",
    "chars": 4263,
    "preview": "{\n  \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n  \"version\": 1,\n  \"newProjectRoot\": \"projects\",\n  \""
  },
  {
    "path": "build.sh",
    "chars": 99,
    "preview": "#!/bin/bash\n\n#ng config -g cli.warnings.versionMismatch false\n\nnpm install\n\nng build --prod --aot\n\n"
  },
  {
    "path": "e2e/app.e2e-spec.ts",
    "chars": 298,
    "preview": "import { NgADFPage } from './app.po';\n\ndescribe('ng-adf App', () => {\n  let page: NgADFPage;\n\n  beforeEach(() => {\n    p"
  },
  {
    "path": "e2e/app.po.ts",
    "chars": 210,
    "preview": "import { browser, element, by } from 'protractor';\n\nexport class NgADFPage {\n  navigateTo() {\n    return browser.get('/'"
  },
  {
    "path": "e2e/tsconfig.e2e.json",
    "chars": 193,
    "preview": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../out-tsc/e2e\",\n    \"module\": \"commonjs\",\n    "
  },
  {
    "path": "karma.conf.js",
    "chars": 1202,
    "preview": "// Karma configuration file, see link for more information\n// https://karma-runner.github.io/0.13/config/configuration-f"
  },
  {
    "path": "ngx-dynamic-dashboard-framework.iml",
    "chars": 457,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\" i"
  },
  {
    "path": "package.json",
    "chars": 1815,
    "preview": "{\n  \"name\": \"ng-dadf\",\n  \"version\": \"0.0.0\",\n  \"license\": \"MIT\",\n  \"ngPackage\": {\n    \"lib\": {\n      \"entryFile\": \"publi"
  },
  {
    "path": "protractor.conf.js",
    "chars": 756,
    "preview": "// Protractor configuration file, see link for more information\n// https://github.com/angular/protractor/blob/master/lib"
  },
  {
    "path": "semantic.json",
    "chars": 468,
    "preview": "{\n  \"base\": \"semantic/\",\n  \"paths\": {\n    \"source\": {\n      \"config\": \"src/theme.config\",\n      \"definitions\": \"src/defi"
  },
  {
    "path": "src/app/about/about-component.ts",
    "chars": 1109,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    AfterViewInit, Component, Output, EventEmitter, Input\n} from "
  },
  {
    "path": "src/app/about/about.module.ts",
    "chars": 361,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {AboutComponent} from './ab"
  },
  {
    "path": "src/app/about/model.ts",
    "chars": 4627,
    "preview": "/**\n * Created by jayhamilton on 1/31/17.\n */\nexport const boardLayouts = [\n\n    {\n        id: 0,\n        boardInstanceI"
  },
  {
    "path": "src/app/about/service.ts",
    "chars": 736,
    "preview": "import {Injectable} from \"@angular/core\";\nimport {environment} from \"../../environments/environment\";\nimport {HttpClient"
  },
  {
    "path": "src/app/about/styles.css",
    "chars": 109,
    "preview": "\nul{\n    text-align: center;\n}\nh2, h3, h4{\n    color:white !important;\n    font-weight: normal !important;\n}\n"
  },
  {
    "path": "src/app/about/view.html",
    "chars": 409,
    "preview": "<br>\n\n<div style=\"text-align: center\">\n    <h2>{{modalHeader}}</h2>\n</div>\n\n<hr>\n\n<br>\n<br>\n\n<div style=\"text-align: cen"
  },
  {
    "path": "src/app/add-gadget/add-gadget-component.ts",
    "chars": 3241,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    ViewChild, ElementRef, AfterViewInit, Component, Output, Even"
  },
  {
    "path": "src/app/add-gadget/add-gadget.module.ts",
    "chars": 676,
    "preview": "import {CommonModule} from '@angular/common';\nimport {NgModule} from '@angular/core';\nimport {AddGadgetComponent} from '"
  },
  {
    "path": "src/app/add-gadget/gadget-factory.ts",
    "chars": 3973,
    "preview": "import {CPUGadgetComponent} from '../gadgets/cpu/cpu-gadget.component';\nimport {MemoryGadgetComponent} from '../gadgets/"
  },
  {
    "path": "src/app/add-gadget/gadgetLibraryResponse.ts",
    "chars": 56,
    "preview": "interface GadgetLibraryResponse {\n    library: any[];\n}\n"
  },
  {
    "path": "src/app/add-gadget/service.ts",
    "chars": 701,
    "preview": "/**\n * Created by jayhamilton on 2/7/17.\n */\nimport {Injectable} from '@angular/core';\nimport {HttpClient} from '@angula"
  },
  {
    "path": "src/app/add-gadget/styles.css",
    "chars": 41,
    "preview": ".modal{\n    background-color:#f7f7f7;\n\n}\n"
  },
  {
    "path": "src/app/add-gadget/view.html",
    "chars": 2233,
    "preview": "<div class=\"ui long modal\" #messagemodal_tag>\n    <div class=\"header\">\n        <h2>{{modalheader}}</h2>\n    </div>\n\n    "
  },
  {
    "path": "src/app/api-token/api-token.service.ts",
    "chars": 4215,
    "preview": "import {Injectable} from '@angular/core';\nimport {HttpClient, HttpHeaders} from '@angular/common/http';\n\n@Injectable()\ne"
  },
  {
    "path": "src/app/app.component.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/app/app.component.html",
    "chars": 714,
    "preview": "<!--\nThe grid is primarily controlled by MenuService Events. You can change the behavior by\nchanging the MenuComponent a"
  },
  {
    "path": "src/app/app.component.spec.ts",
    "chars": 1133,
    "preview": "import { TestBed, async } from '@angular/core/testing';\nimport 'rxjs/Rx';\n\nimport { AppComponent } from './app.component"
  },
  {
    "path": "src/app/app.component.ts",
    "chars": 214,
    "preview": "import { Component } from '@angular/core';\n\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n"
  },
  {
    "path": "src/app/app.module.ts",
    "chars": 905,
    "preview": "import {BrowserModule} from '@angular/platform-browser';\nimport {NgModule} from '@angular/core';\nimport {FormsModule} fr"
  },
  {
    "path": "src/app/board/board.component.ts",
    "chars": 179,
    "preview": "import { Component} from '@angular/core';\n/**a\n * Board component\n *\n */\n@Component({\n    moduleId: module.id,\n    templ"
  },
  {
    "path": "src/app/board/board.module.ts",
    "chars": 2789,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {GridModule} from '../grid/"
  },
  {
    "path": "src/app/board/view.html",
    "chars": 685,
    "preview": "<!--\n\nThe grid is primarily controlled by MenuService Events. You can change the behavior by\nchanging the MenuComponent "
  },
  {
    "path": "src/app/configuration/configuration-component.ts",
    "chars": 2858,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    ViewChild, ElementRef, AfterViewInit, Component, Output, Even"
  },
  {
    "path": "src/app/configuration/configuration.module.ts",
    "chars": 1981,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {EndpointConfigurationTabCo"
  },
  {
    "path": "src/app/configuration/styles.css",
    "chars": 138,
    "preview": "\n.ui.tabular.menu .active.item {\n    border-top: 3px solid #3f51b5 !important;\n}\n\n.ui.attached.segment {\n    margin: 0;\n"
  },
  {
    "path": "src/app/configuration/tab-artificial-intelligence/ai-configuration-tab.component.ts",
    "chars": 1794,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    Component\n} from '@angular/core';\n\nimport {environment} from "
  },
  {
    "path": "src/app/configuration/tab-artificial-intelligence/styles.css",
    "chars": 1924,
    "preview": ".ui.menu{\n    margin-bottom: .1em !important;\n}\n\n\n.ui.secondary.pointing.menu .active.item {\n    color:  #3f51b5 !import"
  },
  {
    "path": "src/app/configuration/tab-artificial-intelligence/view.html",
    "chars": 3049,
    "preview": "<div *ngIf=\"env.boardConfiguration.ai == true\" class=\"ui equal width fields centered grid container\">\n\n    <div class=\"r"
  },
  {
    "path": "src/app/configuration/tab-boards/boards-configuration-tab.component.ts",
    "chars": 1480,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    Component, Output, EventEmitter, Input\n} from '@angular/core'"
  },
  {
    "path": "src/app/configuration/tab-boards/styles.css",
    "chars": 913,
    "preview": "\n\ninput {\n    padding: 5px;\n    font-weight: 300 !important;\n    font-family: 'Roboto', sans-serif !important;\n    font-"
  },
  {
    "path": "src/app/configuration/tab-boards/view.html",
    "chars": 982,
    "preview": "<table class=\"ui padded table\" dnd-sortable-container [sortableData]=\"dashboardList\">\n    <thead>\n    <th class=\"index-c"
  },
  {
    "path": "src/app/configuration/tab-endpoint/endpoint-configuration-tab.component.ts",
    "chars": 2749,
    "preview": "/**\n * Created by jayhamilton on 5/31/17.\n */\nimport {Component} from '@angular/core';\nimport {EndPoint} from './endpoin"
  },
  {
    "path": "src/app/configuration/tab-endpoint/endpoint.help.ts",
    "chars": 46,
    "preview": "/**\n * Created by jayhamilton on 5/18/17.\n */\n"
  },
  {
    "path": "src/app/configuration/tab-endpoint/endpoint.model.ts",
    "chars": 1229,
    "preview": "export interface TAG {\n    name: string;\n}\n\nexport class EndPoint {\n    public id: number;\n    public name: string;\n    "
  },
  {
    "path": "src/app/configuration/tab-endpoint/endpoint.service.ts",
    "chars": 2902,
    "preview": "/**\n * Created by jayhamilton on 2/7/17.\n */\nimport {Injectable} from '@angular/core';\n\nimport {Observable} from 'rxjs';"
  },
  {
    "path": "src/app/configuration/tab-endpoint/endpointDetail.component.ts",
    "chars": 7590,
    "preview": "/**\n * Created by jayhamilton on 5/16/17.\n */\nimport {AfterViewInit, Component, EventEmitter, Input, OnChanges, Output} "
  },
  {
    "path": "src/app/configuration/tab-endpoint/endpointDetail.html",
    "chars": 4391,
    "preview": "<div class=\"ui right aligned grid\">\n    <div class=\"right aligned column\">\n\n        <span *ngIf=\"currentState == 'save a"
  },
  {
    "path": "src/app/configuration/tab-endpoint/styles.css",
    "chars": 646,
    "preview": "\ntd.selected {\n    background-color: #3f51b5 !important;\n    color: white;\n    font-weight: bold;\n\n}\n\n.ui.table {\n    bo"
  },
  {
    "path": "src/app/configuration/tab-endpoint/view.html",
    "chars": 997,
    "preview": "<div *ngIf=\"env.boardConfiguration.endpoint == true\" class=\"ui equal width fields grid container\">\n\n    <div class=\"fiel"
  },
  {
    "path": "src/app/configuration/tab-options/options-configuration-tab.component.ts",
    "chars": 1412,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    Component\n} from '@angular/core';\nimport {OptionsService} fro"
  },
  {
    "path": "src/app/configuration/tab-options/service.ts",
    "chars": 1870,
    "preview": "import {Injectable} from \"@angular/core\";\nimport {Subject,Observable} from \"rxjs\";\n\n\n@Injectable()\nexport class OptionsS"
  },
  {
    "path": "src/app/configuration/tab-options/styles.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/app/configuration/tab-options/view.html",
    "chars": 640,
    "preview": "<br>\nThe following options control various aspects of the board's and gadget's behavior. Changes take effect immediately"
  },
  {
    "path": "src/app/configuration/tabs.model.ts",
    "chars": 427,
    "preview": "export const tabsModel: ({ groupId: string; displayName: string } | { groupId: string; displayName: string })[] = [\n    "
  },
  {
    "path": "src/app/configuration/view.html",
    "chars": 1578,
    "preview": "<div class=\"ui long modal\" #boardconfigmodal_tag>\n    <div class=\"header\">\n        <h2>{{modalheader}}</h2>\n    </div>\n\n"
  },
  {
    "path": "src/app/datalist/action-model.ts",
    "chars": 63,
    "preview": "interface ActionInterface {\n    name: string;\n    item: any;\n}\n"
  },
  {
    "path": "src/app/datalist/data-list.component.ts",
    "chars": 2087,
    "preview": "import {Component, ContentChild, Input, TemplateRef} from '@angular/core';\nimport {Facet} from '../facet/facet-model';\n\n"
  },
  {
    "path": "src/app/datalist/data-list.module.ts",
    "chars": 727,
    "preview": "import {CommonModule} from '@angular/common';\nimport {NgModule} from '@angular/core';\nimport {FacetModule} from '../face"
  },
  {
    "path": "src/app/datalist/styles.css",
    "chars": 386,
    "preview": ".content {\n    background-color:#f7f7f7;\n    margin-top: 25px;\n    margin-left: 25px;\n    padding:5px;\n}\n\nhr {\n    heigh"
  },
  {
    "path": "src/app/datalist/view.html",
    "chars": 1063,
    "preview": "<div class=\"content\">\n    <div class=\"ui grid\">\n        <div class=\"{{layoutColumnOneWidth}} wide column\">\n            <"
  },
  {
    "path": "src/app/detail/detail.component.ts",
    "chars": 3749,
    "preview": "import {Component, OnInit} from '@angular/core';\nimport {ActivatedRoute, NavigationEnd, Router} from \"@angular/router\";\n"
  },
  {
    "path": "src/app/detail/detail.model.ts",
    "chars": 59,
    "preview": "interface DetailModel {\n    name: string;\n    data: any;\n}\n"
  },
  {
    "path": "src/app/detail/detail.module.ts",
    "chars": 619,
    "preview": "import {CommonModule} from '@angular/common';\nimport {NgModule} from '@angular/core';\nimport {MatCheckboxModule} from '@"
  },
  {
    "path": "src/app/detail/detail.resolver.ts",
    "chars": 463,
    "preview": "import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';\nimport {Observable} from 'rxjs';\n\n"
  },
  {
    "path": "src/app/detail/filter.pipe.ts",
    "chars": 621,
    "preview": "import { Pipe, PipeTransform } from '@angular/core';\n@Pipe({\n    name: 'filter'\n})\nexport class FilterPipe implements Pi"
  },
  {
    "path": "src/app/detail/service.ts",
    "chars": 1565,
    "preview": "import {Injectable} from \"@angular/core\";\nimport {HttpClient, HttpParams} from \"@angular/common/http\";\nimport {RuntimeSe"
  },
  {
    "path": "src/app/detail/styles.css",
    "chars": 411,
    "preview": "a,\na label {\n    cursor: pointer;\n}\n\n.field {\n    background: #4a95c3;\n    color: white;\n}\n\n.ui .breadcrumb {\n    font-s"
  },
  {
    "path": "src/app/detail/view.html",
    "chars": 4025,
    "preview": "<div class=\"ui centered stackable grid\" style=\"margin-left: 5px; margin-right: 5px\">\n    <div class=\"row\">\n        <div "
  },
  {
    "path": "src/app/dynamic-form/dynamic-form-module.ts",
    "chars": 729,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {DynamicFormComponent} from"
  },
  {
    "path": "src/app/dynamic-form/dynamic-form-property.component.html",
    "chars": 2042,
    "preview": "<div [formGroup]=\"form\">\n\n    <div class=\"field\">\n        <label [attr.for]=\"property.key\">{{property.label}}</label>\n\n "
  },
  {
    "path": "src/app/dynamic-form/dynamic-form-property.component.ts",
    "chars": 2260,
    "preview": "/**\n * Created by jayhamilton on 2/5/17.\n */\nimport {AfterViewInit, Component, Input} from '@angular/core';\nimport {Form"
  },
  {
    "path": "src/app/dynamic-form/dynamic-form.component.html",
    "chars": 1483,
    "preview": "<div class=\"ui form\" style=\"text-align: left !important\">\n    <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\n\n       "
  },
  {
    "path": "src/app/dynamic-form/dynamic-form.component.ts",
    "chars": 3419,
    "preview": "/**\n * Created by jayhamilton on 2/5/17.\n */\nimport {\n    Component, Input, OnInit, Output, EventEmitter,\n    ChangeDete"
  },
  {
    "path": "src/app/dynamic-form/property-base.ts",
    "chars": 739,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nexport class PropertyBase<T> {\n    value: T;\n    key: string;\n    label: st"
  },
  {
    "path": "src/app/dynamic-form/property-checkbox.ts",
    "chars": 332,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {PropertyBase} from './property-base';\n\n\nexport class CheckboxProper"
  },
  {
    "path": "src/app/dynamic-form/property-control.service.ts",
    "chars": 695,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {Injectable} from '@angular/core';\nimport {FormControl, FormGroup, V"
  },
  {
    "path": "src/app/dynamic-form/property-dropdown.ts",
    "chars": 354,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {PropertyBase} from './property-base';\n\nexport class DropdownPropert"
  },
  {
    "path": "src/app/dynamic-form/property-dynamicdropdown.ts",
    "chars": 366,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {PropertyBase} from './property-base';\n\nexport class DynamicDropdown"
  },
  {
    "path": "src/app/dynamic-form/property-hidden.ts",
    "chars": 299,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {PropertyBase} from './property-base';\n\n\nexport class HiddenProperty"
  },
  {
    "path": "src/app/dynamic-form/property-number.ts",
    "chars": 324,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {PropertyBase} from './property-base';\n\n\nexport class NumberProperty"
  },
  {
    "path": "src/app/dynamic-form/property-textbox.ts",
    "chars": 313,
    "preview": "/**\n * Created by jayhamilton on 2/3/17.\n */\nimport {PropertyBase} from './property-base';\n\nexport class TextboxProperty"
  },
  {
    "path": "src/app/dynamic-form/styles-props.css",
    "chars": 507,
    "preview": ".field > label {\n    font-size: 1.1em !important;\n    color: #767676 !important;\n    font-weight: 300\n}\n\n.ui.tabular.men"
  },
  {
    "path": "src/app/error/error-handler.component.ts",
    "chars": 888,
    "preview": "import {\n    Component, Input\n} from '@angular/core';\n\nimport {\n    style, trigger, animate, transition\n} from '@angular"
  },
  {
    "path": "src/app/error/error-handler.ts",
    "chars": 5242,
    "preview": "import {ErrorObject, SolutionObject} from './error-model';\n\n/**\n * Created by jayhamilton on 7/5/17.\n */\nexport class Er"
  },
  {
    "path": "src/app/error/error-model.ts",
    "chars": 647,
    "preview": "/**\n * Created by jayhamilton on 6/22/17.\n */\nexport class ErrorObject {\n    detail: string;\n    summary: string;\n    so"
  },
  {
    "path": "src/app/error/error.module.ts",
    "chars": 326,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {ErrorHandlerComponent} fro"
  },
  {
    "path": "src/app/error/styles-error.css",
    "chars": 67,
    "preview": ".error-heading{\n    color:grey !important;\n    text-align: left;\n}\n"
  },
  {
    "path": "src/app/error/view.html",
    "chars": 706,
    "preview": "<div [@error]=\"errorExists\" *ngIf=\"errorExists\" class=\"ui bottom attached negative message\">\n    <i class=\"close icon\" ("
  },
  {
    "path": "src/app/facet/capitalize-first-character-pipe.ts",
    "chars": 573,
    "preview": "import { Pipe, PipeTransform } from '@angular/core';\n/*\n * Capitalize the first letter of the string\n * Takes a string a"
  },
  {
    "path": "src/app/facet/facet-component.ts",
    "chars": 3030,
    "preview": "import {Facet} from './facet-model';\nimport {\n    Component, EventEmitter, Input, OnInit, Output\n} from '@angular/core';"
  },
  {
    "path": "src/app/facet/facet-model.ts",
    "chars": 321,
    "preview": "export class Facet {\n    name: string;\n    tags: Array<Tag>;\n\n    constructor(name: string, tags: Array<Tag>) {\n\n       "
  },
  {
    "path": "src/app/facet/facet-tag-processor.ts",
    "chars": 2352,
    "preview": "import {Facet, Tag} from './facet-model';\n\nexport class FacetTagProcessor {\n\n    facet_tags: Array<Facet> = [];\n    obje"
  },
  {
    "path": "src/app/facet/facet.module.ts",
    "chars": 931,
    "preview": "import {CommonModule} from '@angular/common';\nimport {NgModule} from '@angular/core';\nimport {FacetComponent} from './fa"
  },
  {
    "path": "src/app/facet/filter-list-component.ts",
    "chars": 768,
    "preview": "import {Component, EventEmitter, Input, Output} from '@angular/core';\nimport {AddGadgetService} from '../add-gadget/serv"
  },
  {
    "path": "src/app/facet/filter-tag-component.ts",
    "chars": 1630,
    "preview": "import { Component, EventEmitter, Output} from '@angular/core';\n\nimport {\n    style, trigger, animate, transition\n} from"
  },
  {
    "path": "src/app/facet/styles.css",
    "chars": 677,
    "preview": ".ui.avatar.image {\n    width: 4.4em !important;\n    height: 4em !important\n}\n\nhr {\n    height: 2px !important;\n    color"
  },
  {
    "path": "src/app/gadgets/_common/base-chart-models/bar.model.ts",
    "chars": 249,
    "preview": "import {Series} from './series.model';\n\nexport abstract class Bar {\n\n    public name: string;\n    public series: Array<S"
  },
  {
    "path": "src/app/gadgets/_common/base-chart-models/series.model.ts",
    "chars": 184,
    "preview": "export class Series {\n\n    public name: string;\n    public value: number;\n\n    constructor(name: string, value: number) "
  },
  {
    "path": "src/app/gadgets/_common/gadget-base.ts",
    "chars": 8392,
    "preview": "import {ErrorObject} from '../../error/error-model';\nimport {EndPoint} from '../../configuration/tab-endpoint/endpoint.m"
  },
  {
    "path": "src/app/gadgets/_common/gadget-config-model.ts",
    "chars": 1578,
    "preview": "import {PropertyBase} from '../../dynamic-form/property-base';\n\n/**\n * Created by jayhamilton on 6/15/17.\n */\n\nexport cl"
  },
  {
    "path": "src/app/gadgets/_common/gadget-header-component.ts",
    "chars": 1319,
    "preview": "/**\n * Created by jayhamilton on 2/28/17.\n */\nimport {Component, Input, Output, EventEmitter} from '@angular/core';\n/**\n"
  },
  {
    "path": "src/app/gadgets/_common/gadget-header.html",
    "chars": 1387,
    "preview": "<div class=\"ui top attached label\">\n\n    <button class=\"compact ui button right floated\"\n            *ngIf=\"showControls"
  },
  {
    "path": "src/app/gadgets/_common/gadget-operation-control-component.ts",
    "chars": 1550,
    "preview": "import {Component, EventEmitter, Input, Output} from '@angular/core';\n\n/**\n * Created by jayhamilton on 6/29/17.\n */\n\n@C"
  },
  {
    "path": "src/app/gadgets/_common/gadget-property.service.ts",
    "chars": 2767,
    "preview": "import {Injectable} from '@angular/core';\nimport {DropdownProperty} from '../../dynamic-form/property-dropdown';\nimport "
  },
  {
    "path": "src/app/gadgets/_common/gadget-shared.module.ts",
    "chars": 897,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {GadgetHeaderComponent} fro"
  },
  {
    "path": "src/app/gadgets/_common/help-modal-component.ts",
    "chars": 1442,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    ViewChild, ElementRef, AfterViewInit, Component, Input\n} from"
  },
  {
    "path": "src/app/gadgets/_common/help-modal.html",
    "chars": 1021,
    "preview": "<div class=\"ui long modal\" #helpmodal_tag>\n    <div class=\"header\">\n        Help\n    </div>\n\n    <div class=\"ui basic se"
  },
  {
    "path": "src/app/gadgets/_common/igadget.ts",
    "chars": 435,
    "preview": "/**\n * Created by jayhamilton on 2/25/17.\n */\ninterface IGadget {\n\n    run();\n\n    stop();\n\n    toggleConfigMode();\n\n   "
  },
  {
    "path": "src/app/gadgets/_common/styles-gadget.css",
    "chars": 1983,
    "preview": ".gadget {\n    margin-bottom: 15px !important;\n    min-height: inherit !important;\n    font-family: 'Helvetica Neue', Hel"
  },
  {
    "path": "src/app/gadgets/_common/vis-drill-down-component.ts",
    "chars": 2731,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    ViewChild, ElementRef, AfterViewInit, Component\n} from '@angu"
  },
  {
    "path": "src/app/gadgets/_common/vis-drill-down.html",
    "chars": 272,
    "preview": "<div class=\"ui long modal\" #vismodal_tag>\n    <div class=\"header\">\n        <h2>{{modalheader}}</h2>\n    </div>\n\n\n    <di"
  },
  {
    "path": "src/app/gadgets/barchart/barchart-gadget.component.ts",
    "chars": 9298,
    "preview": "import {ChangeDetectorRef, Component, ElementRef, ViewChild} from '@angular/core';\nimport {GadgetInstanceService} from '"
  },
  {
    "path": "src/app/gadgets/barchart/service.ts",
    "chars": 512,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\n\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '."
  },
  {
    "path": "src/app/gadgets/barchart/view.html",
    "chars": 5658,
    "preview": "<div class=\"ui  center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/bubble/bubble-gadget.component.ts",
    "chars": 4012,
    "preview": "import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';\nimport {GadgetInstanceService} from '../."
  },
  {
    "path": "src/app/gadgets/bubble/service.ts",
    "chars": 532,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\n\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '."
  },
  {
    "path": "src/app/gadgets/bubble/view.html",
    "chars": 2227,
    "preview": "<div  class=\"ui  center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZon"
  },
  {
    "path": "src/app/gadgets/cpu/cpu-gadget.component.ts",
    "chars": 3938,
    "preview": "import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';\nimport {GadgetInstanceService} from '../."
  },
  {
    "path": "src/app/gadgets/cpu/service.ts",
    "chars": 515,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\n\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '."
  },
  {
    "path": "src/app/gadgets/cpu/view.html",
    "chars": 2391,
    "preview": "<div  class=\"ui  center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZon"
  },
  {
    "path": "src/app/gadgets/cpum/cpu.model.ts",
    "chars": 318,
    "preview": "\nimport {Series} from '../_common/base-chart-models/series.model';\nimport {Bar} from '../_common/base-chart-models/bar.m"
  },
  {
    "path": "src/app/gadgets/cpum/cpum-gadget.component.ts",
    "chars": 6798,
    "preview": "import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';\nimport {GadgetInstanceService} from '../."
  },
  {
    "path": "src/app/gadgets/cpum/view.html",
    "chars": 2592,
    "preview": "<div class=\"ui  center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/disk/disk-gadget.component.ts",
    "chars": 4972,
    "preview": "import {\n    ChangeDetectorRef, Component\n} from '@angular/core';\n\nimport {\n    style, trigger, animate, transition, sta"
  },
  {
    "path": "src/app/gadgets/disk/service.ts",
    "chars": 1378,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\n\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '."
  },
  {
    "path": "src/app/gadgets/disk/view.html",
    "chars": 4022,
    "preview": "<div class=\"ui center aligned  segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/donut/donut-gadget.component.ts",
    "chars": 4707,
    "preview": "import {\n    ChangeDetectorRef, Component, OnDestroy\n} from '@angular/core';\n\nimport {\n    style, trigger, animate, tran"
  },
  {
    "path": "src/app/gadgets/donut/drill-down-component.ts",
    "chars": 5238,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    ViewChild, ElementRef, AfterViewInit, Component\n} from '@angu"
  },
  {
    "path": "src/app/gadgets/donut/drill-down-style.css",
    "chars": 71,
    "preview": "h3 {\n    font-weight: 400;\n}\n\n.drill-down-blue {\n\n    color: #2c83d0\n\n}"
  },
  {
    "path": "src/app/gadgets/donut/drill-down.html",
    "chars": 3705,
    "preview": "<div class=\"ui long modal\" #drillmodal_tag>\n    <div class=\"header\">\n        <h2>{{modalheader}}</h2>\n    </div>\n\n\n    <"
  },
  {
    "path": "src/app/gadgets/donut/service.ts",
    "chars": 1289,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\n\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '."
  },
  {
    "path": "src/app/gadgets/donut/view.html",
    "chars": 3002,
    "preview": "<div class=\"ui center aligned  segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/edge-service-list/edge-service-list-gadget.component.ts",
    "chars": 8918,
    "preview": "import {ChangeDetectorRef, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core';\nimport {\n    style, trigge"
  },
  {
    "path": "src/app/gadgets/edge-service-list/service-list.ts",
    "chars": 1467,
    "preview": "/**\n * Created by jayhamilton on 1/28/17.\n */\nexport const serviceList: {\n    active: boolean,\n    applicationName: stri"
  },
  {
    "path": "src/app/gadgets/edge-service-list/service.ts",
    "chars": 1699,
    "preview": "import {Injectable} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service';\nimport {timer, "
  },
  {
    "path": "src/app/gadgets/edge-service-list/view.html",
    "chars": 6351,
    "preview": "<div  class=\"ui   segment left aligned gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/gadget.module.ts",
    "chars": 5497,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {CPUGadgetComponent} from '"
  },
  {
    "path": "src/app/gadgets/job-analysis/ja.css",
    "chars": 90,
    "preview": ".example-card {\n    width: 400px;\n}\n\n.example-header-image {\n    background-size: cover;\n}"
  },
  {
    "path": "src/app/gadgets/job-analysis/job-analysis-gadget.component.ts",
    "chars": 3210,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {GadgetInstanceService} from '../../grid/grid.service"
  },
  {
    "path": "src/app/gadgets/job-analysis/model.json",
    "chars": 945,
    "preview": "[\n  {\n    \"name\": \"IBM\",\n    \"series\": [\n      {\n        \"name\": \"January\",\n        \"value\": 3453\n      },\n      {\n     "
  },
  {
    "path": "src/app/gadgets/job-analysis/service.ts",
    "chars": 498,
    "preview": "import {Injectable} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service';\nimport {HttpCli"
  },
  {
    "path": "src/app/gadgets/job-analysis/view.html",
    "chars": 1359,
    "preview": "<div class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZones"
  },
  {
    "path": "src/app/gadgets/memory/memory-gadget.component.ts",
    "chars": 4531,
    "preview": "import {ChangeDetectorRef, Component, OnDestroy} from '@angular/core';\nimport {RuntimeService} from '../../services/runt"
  },
  {
    "path": "src/app/gadgets/memory/view.html",
    "chars": 2121,
    "preview": "<div  class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/news/news-gadget.component.ts",
    "chars": 3132,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service"
  },
  {
    "path": "src/app/gadgets/news/service.ts",
    "chars": 507,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '.."
  },
  {
    "path": "src/app/gadgets/news/view.html",
    "chars": 2444,
    "preview": "<div  class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/piechart/piechart-gadget.component.ts",
    "chars": 7858,
    "preview": "import {ChangeDetectorRef, Component, ElementRef, ViewChild} from '@angular/core';\nimport {GadgetInstanceService} from '"
  },
  {
    "path": "src/app/gadgets/piechart/service.ts",
    "chars": 512,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\n\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '."
  },
  {
    "path": "src/app/gadgets/piechart/view.html",
    "chars": 2947,
    "preview": "<div class=\"ui  center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/port-connection/port-connection-gadget.component.ts",
    "chars": 6287,
    "preview": "import {ChangeDetectorRef, Component, OnDestroy} from '@angular/core';\nimport {RuntimeService} from '../../services/runt"
  },
  {
    "path": "src/app/gadgets/port-connection/port-connection.css",
    "chars": 29,
    "preview": ".input-width{\n    width:45%\n}"
  },
  {
    "path": "src/app/gadgets/port-connection/result-view.component.ts",
    "chars": 948,
    "preview": "\nimport {Component, Input} from \"@angular/core\";\nimport {animate, style, transition, trigger} from \"@angular/animations\""
  },
  {
    "path": "src/app/gadgets/port-connection/result-view.html",
    "chars": 3210,
    "preview": "<div class=\"ui centered grid\">\n    <div class=\"ui basic segment\">\n        <table class=\" ui compact unstackable fixed ta"
  },
  {
    "path": "src/app/gadgets/port-connection/service.model.ts",
    "chars": 175,
    "preview": "\nexport class EndPointModel {\n\n    host: string;\n    port: string;\n\n    constructor(host: string, port: string) {\n\n     "
  },
  {
    "path": "src/app/gadgets/port-connection/service.ts",
    "chars": 1979,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '.."
  },
  {
    "path": "src/app/gadgets/port-connection/solution-view.component.ts",
    "chars": 255,
    "preview": "import {Component, Input} from \"@angular/core\";\n\n\n@Component({\n    selector: 'solution-view-component',\n    moduleId: mo"
  },
  {
    "path": "src/app/gadgets/port-connection/solution-view.html",
    "chars": 380,
    "preview": "\n<div class=\"ui basic segment full-width\">\n\n    <div class=\"grid-row\">\n        <mat-form-field class=\"input-width\">\n    "
  },
  {
    "path": "src/app/gadgets/port-connection/view.html",
    "chars": 2174,
    "preview": "<div class=\"ui left aligned segment gadget\" dnd-draggable [dragEnabled]=\"true\"\n     [dragData]=\"instanceId\" [dropZones]="
  },
  {
    "path": "src/app/gadgets/property-list/property-list-gadget.component.ts",
    "chars": 1739,
    "preview": "import {ChangeDetectorRef, Component, OnDestroy} from '@angular/core';\nimport {RuntimeService} from '../../services/runt"
  },
  {
    "path": "src/app/gadgets/property-list/view.html",
    "chars": 2095,
    "preview": "\n    <div class=\"ui left aligned segment gadget\" dnd-draggable [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZones]="
  },
  {
    "path": "src/app/gadgets/service-list/service-list-gadget.component.ts",
    "chars": 3593,
    "preview": "import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';\nimport {\n    style, trigger, animate, transitio"
  },
  {
    "path": "src/app/gadgets/service-list/service-list.ts",
    "chars": 1179,
    "preview": "/**\n * Created by jayhamilton on 1/28/17.\n */\nexport const serviceList: {\n    active: boolean,\n    applicationName: stri"
  },
  {
    "path": "src/app/gadgets/service-list/view.html",
    "chars": 2083,
    "preview": "<div  class=\"ui segment left aligned gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZones]"
  },
  {
    "path": "src/app/gadgets/statistic/service.ts",
    "chars": 545,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '.."
  },
  {
    "path": "src/app/gadgets/statistic/statistic-gadget.component.ts",
    "chars": 3305,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service"
  },
  {
    "path": "src/app/gadgets/statistic/view.html",
    "chars": 1603,
    "preview": "<div class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZones"
  },
  {
    "path": "src/app/gadgets/storage-object-list/service.ts",
    "chars": 513,
    "preview": "/**\n * Created by jayhamilton on 6/24/17.\n */\nimport {Injectable} from '@angular/core';\nimport {RuntimeService} from '.."
  },
  {
    "path": "src/app/gadgets/storage-object-list/storage-object-list.component.ts",
    "chars": 4325,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service"
  },
  {
    "path": "src/app/gadgets/storage-object-list/style.css",
    "chars": 512,
    "preview": ".storage{\n    overflow-y:hidden;\n    overflow-x:hidden;\n    padding-right:5px;\n    padding-left:5px;\n    height:100%;\n  "
  },
  {
    "path": "src/app/gadgets/storage-object-list/view.html",
    "chars": 6903,
    "preview": "<div  class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/gadgets/todo/service.ts",
    "chars": 520,
    "preview": "/**\n * Created by jayhamilton on 6/24/17. Todo Service\n */\nimport {Injectable} from '@angular/core';\nimport {RuntimeServ"
  },
  {
    "path": "src/app/gadgets/todo/todo-gadget.component.ts",
    "chars": 3373,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service"
  },
  {
    "path": "src/app/gadgets/todo/view.html",
    "chars": 2831,
    "preview": "<!--todo view -->\n<div class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"inst"
  },
  {
    "path": "src/app/gadgets/trend/service.ts",
    "chars": 463,
    "preview": "import {Injectable} from '@angular/core';\nimport {RuntimeService} from '../../services/runtime.service';\nimport {HttpCli"
  },
  {
    "path": "src/app/gadgets/trend/trend-gadget.component.ts",
    "chars": 3785,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {GadgetInstanceService} from '../../grid/grid.service"
  },
  {
    "path": "src/app/gadgets/trend/view.html",
    "chars": 2534,
    "preview": "<div class=\"ui center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZones"
  },
  {
    "path": "src/app/gadgets/trend-line/service.ts",
    "chars": 2164,
    "preview": "import {Injectable} from '@angular/core';\nimport {Observable, timer} from 'rxjs';\nimport {RuntimeService} from '../../se"
  },
  {
    "path": "src/app/gadgets/trend-line/trend-line-gadget.component.ts",
    "chars": 4823,
    "preview": "import {ChangeDetectorRef, Component} from '@angular/core';\nimport {GadgetInstanceService} from '../../grid/grid.service"
  },
  {
    "path": "src/app/gadgets/trend-line/view.html",
    "chars": 2639,
    "preview": "<div class=\"ui  center aligned segment gadget\" dnd-draggable\n     [dragEnabled]=\"true\" [dragData]=\"instanceId\" [dropZone"
  },
  {
    "path": "src/app/grid/cell.component.ts",
    "chars": 1548,
    "preview": "import {Component, Input, ViewContainerRef, OnInit, ComponentFactoryResolver} from '@angular/core';\nimport {GadgetInstan"
  },
  {
    "path": "src/app/grid/grid.component.ts",
    "chars": 15557,
    "preview": "import {Component, Output, EventEmitter} from '@angular/core';\nimport {GadgetInstanceService} from './grid.service';\nimp"
  },
  {
    "path": "src/app/grid/grid.html",
    "chars": 1245,
    "preview": "<div class=\"ui centered stackable grid\" style=\"margin-left: 5px; margin-right: 5px\">\n    <div *ngFor=\"let row of model.r"
  },
  {
    "path": "src/app/grid/grid.module.ts",
    "chars": 2238,
    "preview": "import {NgModule, ANALYZE_FOR_ENTRY_COMPONENTS} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimpo"
  },
  {
    "path": "src/app/grid/grid.service.ts",
    "chars": 3069,
    "preview": "/**\n * Created by jayhamilton on 1/28/17.\n */\nimport {Injectable} from '@angular/core';\nimport {Subject,Observable} from"
  },
  {
    "path": "src/app/grid/styles-grid.css",
    "chars": 257,
    "preview": ".ui.info.message {\n    background-color: #C8CBCE;\n    color: #ffffff\n}\n\n.ui.attached.info.message, .ui.info.message {\n  "
  },
  {
    "path": "src/app/layout/layout-component.ts",
    "chars": 1359,
    "preview": "/**\n * Created by jayhamilton on 1/24/17.\n */\nimport {\n    AfterViewInit, Component, Output, EventEmitter, Input\n} from "
  },
  {
    "path": "src/app/layout/layout.module.ts",
    "chars": 331,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {BoardLayoutManagerComponen"
  },
  {
    "path": "src/app/layout/model.ts",
    "chars": 4622,
    "preview": "/**\n * Created by jayhamilton on 1/31/17.\n */\nexport const boardLayouts = [\n\n    {\n        id: 0,\n        boardInstanceI"
  },
  {
    "path": "src/app/layout/styles.css",
    "chars": 196,
    "preview": "\n.layout-selected {\n    border-top: medium lawngreen solid;\n    padding-top:5px;\n}\nul{\n    text-align: center;\n}\nh2{\n   "
  },
  {
    "path": "src/app/layout/view.html",
    "chars": 373,
    "preview": "<br>\n\n<div style=\"text-align: center\">\n    <h2>{{modalHeader}}</h2>\n</div>\n<hr>\n\n<br>\n<br>\n<ul>\n    <li style='list-styl"
  },
  {
    "path": "src/app/menu/IEvent.ts",
    "chars": 54,
    "preview": "interface IEvent {\n    name: string;\n    data: any;\n}\n"
  },
  {
    "path": "src/app/menu/menu-service.ts",
    "chars": 1616,
    "preview": "import {Injectable} from '@angular/core';\nimport {Subject, Observable} from 'rxjs';\n\n/**\n The grid is primarily controll"
  },
  {
    "path": "src/app/menu/menu.component.ts",
    "chars": 4766,
    "preview": "import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';\nimport {ConfigurationService} from '../services/"
  },
  {
    "path": "src/app/menu/menu.module.ts",
    "chars": 1716,
    "preview": "import {NgModule} from '@angular/core';\nimport {CommonModule} from '@angular/common';\nimport {MatButtonModule, MatIconMo"
  },
  {
    "path": "src/app/menu/styles.css",
    "chars": 922,
    "preview": "\n\n.ui.secondary.pointing.menu .active.item {\n    color: #f9f9f9 !important;\n    font-weight: 500 !important;\n    border-"
  },
  {
    "path": "src/app/menu/view.html",
    "chars": 3174,
    "preview": "<div  class=\"ui inverted menu sticky\" #stickymenu_tag style=\"height: 66px !important\">\n\n\n    <app-typeahead-input *ngIf="
  }
]

// ... and 67 more files (download for full content)

About this extraction

This page contains the full source code of the catalogicsoftware/ngx-dynamic-dashboard-framework GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 267 files (604.7 KB), approximately 137.2k tokens, and a symbol index with 655 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!