aboutsummaryrefslogtreecommitdiffstats
path: root/vid-webpack-master/src/app/shared/components
diff options
context:
space:
mode:
authorSonsino, Ofir (os0695) <os0695@intl.att.com>2018-07-10 15:57:37 +0300
committerSonsino, Ofir (os0695) <os0695@intl.att.com>2018-07-10 15:57:37 +0300
commitff76b5ed0aa91d5fdf9dc4f95e8b20f91ed9d072 (patch)
treeaae42404a93fdffdd16ff050eaa28129959f7577 /vid-webpack-master/src/app/shared/components
parentc72d565bb58226b20625b2bce5f0019046bee649 (diff)
New Angular UI from 1806
Change-Id: I39c160db0e0a6ec2e587ccf007ee1b23c6a08666 Issue-ID: VID-208 Signed-off-by: Sonsino, Ofir (os0695) <os0695@intl.att.com>
Diffstat (limited to 'vid-webpack-master/src/app/shared/components')
-rw-r--r--vid-webpack-master/src/app/shared/components/ellipsis/ellipsis.component.ts27
-rw-r--r--vid-webpack-master/src/app/shared/components/error/error.component.service.ts35
-rw-r--r--vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.html4
-rw-r--r--vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.scss14
-rw-r--r--vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.ts10
-rw-r--r--vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.html10
-rw-r--r--vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.scss48
-rw-r--r--vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.ts11
-rw-r--r--vid-webpack-master/src/app/shared/components/messageBox/messageBox.component.ts50
-rw-r--r--vid-webpack-master/src/app/shared/components/messageBox/messageBox.data.ts51
-rw-r--r--vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.spec.ts49
-rw-r--r--vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.ts18
-rw-r--r--vid-webpack-master/src/app/shared/components/model-information/model-information.component.ts42
-rw-r--r--vid-webpack-master/src/app/shared/components/model-information/model-information.html12
-rw-r--r--vid-webpack-master/src/app/shared/components/model-information/model-information.scss34
-rw-r--r--vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.html5
-rw-r--r--vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.scss26
-rw-r--r--vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.ts23
-rw-r--r--vid-webpack-master/src/app/shared/components/popover/popover.component.html8
-rw-r--r--vid-webpack-master/src/app/shared/components/popover/popover.component.scss4
-rw-r--r--vid-webpack-master/src/app/shared/components/popover/popover.component.ts17
-rw-r--r--vid-webpack-master/src/app/shared/components/spinner/spinner.component.html2
-rw-r--r--vid-webpack-master/src/app/shared/components/spinner/spinner.component.scss87
-rw-r--r--vid-webpack-master/src/app/shared/components/spinner/spinner.component.spec.ts42
-rw-r--r--vid-webpack-master/src/app/shared/components/spinner/spinner.component.ts18
-rw-r--r--vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.spec.ts39
-rw-r--r--vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.ts20
27 files changed, 706 insertions, 0 deletions
diff --git a/vid-webpack-master/src/app/shared/components/ellipsis/ellipsis.component.ts b/vid-webpack-master/src/app/shared/components/ellipsis/ellipsis.component.ts
new file mode 100644
index 000000000..fd58b6507
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/ellipsis/ellipsis.component.ts
@@ -0,0 +1,27 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector : 'custom-ellipsis',
+ template: `
+ <span
+ class="ellipsis"
+ id="{{id}}"
+ tooltip="{{value}}">{{value}}</span>`,
+ styles : [
+ `
+ .ellipsis {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: inline-block;
+ width: 99%;
+ text-align: left;
+ }
+ `
+ ]
+})
+export class EllipsisComponent {
+ @Input() value : string;
+ @Input() id : string;
+
+}
diff --git a/vid-webpack-master/src/app/shared/components/error/error.component.service.ts b/vid-webpack-master/src/app/shared/components/error/error.component.service.ts
new file mode 100644
index 000000000..35b83f0b6
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/error/error.component.service.ts
@@ -0,0 +1,35 @@
+import {Injectable} from "@angular/core";
+import {Subject} from "rxjs/Subject";
+import { MessageBoxService } from '../messageBox/messageBox.service';
+import { MessageBoxData, ModalSize, ModalType } from '../messageBox/messageBox.data';
+
+@Injectable()
+export class ErrorService {
+ static showErrorWithMessage(error : ErrorMessage) : void {
+ setTimeout(()=>{
+ let messageBoxData : MessageBoxData = new MessageBoxData(
+ error.title, // modal title
+ error.text,
+
+ ModalType.error,
+ ModalSize.medium,
+ [
+ {text:"Close", size:"large", closeModal:true}
+ ]);
+ MessageBoxService.openModal.next(messageBoxData);
+ }
+ ,500);
+ }
+}
+
+export class ErrorMessage {
+ title : string;
+ text : string;
+ errorNumber : number;
+
+ constructor( title : string, text : string,errorNumber : number){
+ this.title = title;
+ this.text = text;
+ this.errorNumber = errorNumber;
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.html b/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.html
new file mode 100644
index 000000000..daa35e659
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.html
@@ -0,0 +1,4 @@
+<div *ngIf="message">
+ <span class="icon-alert"></span>
+ <span class="message">{{message}}</span>
+</div>
diff --git a/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.scss b/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.scss
new file mode 100644
index 000000000..d174f511c
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.scss
@@ -0,0 +1,14 @@
+.icon-alert {
+ margin-top: 10px;
+ &:before {
+ content: "\e904";
+ font-size: 16px;
+ color: #cf2a2a;
+ }
+}
+
+.message {
+ font-size: 12px;
+ line-height: 14px;
+ color: #cf2a2a;
+}
diff --git a/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.ts b/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.ts
new file mode 100644
index 000000000..a20b26030
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formControlError/formControlError.component.ts
@@ -0,0 +1,10 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector : 'form-control-error',
+ templateUrl : 'formControlError.component.html',
+ styleUrls : ['formControlError.component.scss']
+})
+export class FormControlErrorComponent {
+ @Input() message = null;
+}
diff --git a/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.html b/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.html
new file mode 100644
index 000000000..4c794e686
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.html
@@ -0,0 +1,10 @@
+<div *ngIf="message" class="row row-padding">
+ <div class="col-md-2 icon-div"><span class="icon-alert"></span></div>
+ <div class="col-md-10 left-align parentbox">
+ <div class="childbox">
+ <span>{{message}}</span>
+ </div>
+ </div>
+</div>
+
+
diff --git a/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.scss b/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.scss
new file mode 100644
index 000000000..5271cad49
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.scss
@@ -0,0 +1,48 @@
+.icon-alert {
+ margin-top: 10px;
+ &:before {
+ content: "\e904";
+ font-size: 30px;
+ color: #ffffff;
+ }
+}
+
+.icon-div {
+ background: rgb(207,41,41);
+ text-align: center;
+ padding-top: 18px;
+ width: 77px;
+ height: 110px;
+ float: left;
+}
+
+
+.error-title {
+ color: #cf2a2a;
+}
+
+.row-padding {
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
+.left-align {
+ text-align: left;
+}
+
+.parentbox {
+ padding-right: 0;
+}
+
+.parentbox:before {
+ content: ' ';
+ display: inline-block;
+ vertical-align: middle;
+ height: 100%;
+}
+
+.childbox {
+ color: #cf2a2a;
+ display: inline-block;
+ vertical-align: middle;
+}
diff --git a/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.ts b/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.ts
new file mode 100644
index 000000000..0c0516a4d
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/formGeneralErrors/formGeneralErrors.component.ts
@@ -0,0 +1,11 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector : 'form-general-error',
+ templateUrl : 'formGeneralErrors.component.html',
+ styleUrls : ['formGeneralErrors.component.scss']
+})
+
+export class FormGeneralErrorsComponent {
+ @Input() message : string = null;
+}
diff --git a/vid-webpack-master/src/app/shared/components/messageBox/messageBox.component.ts b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.component.ts
new file mode 100644
index 000000000..08e199cf5
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.component.ts
@@ -0,0 +1,50 @@
+/************************************************************************************************
+ * @Component: Message box component
+ * In order to use component you need to do a number of things:
+ * 1) Inside your component constructor you need to add listener to the button trigger.
+ * 2) Inside the listener you should write your callback logic.
+ *
+ * Example:
+ * @Component({
+ * selector : 'some-component'
+ * ...
+ * })
+ *
+ * export class SomeComponent {
+ * openModal() : void {
+ * let messageBoxData : MessageBoxData = new MessageBoxData(
+ * "title", // modal title
+ * "message", ModalType.alert, // modal type
+ * [
+ {text:"Save", size:"'x-small'", callback: this.someFunction.bind(this), closeModal:true},
+ {text:"Cancel", size:"'x-small'", closeModal:true}
+ ]);
+ *
+ * MessageBoxService.openModal.next(messageBoxData); // open modal
+ * }
+ * }
+
+ ************************************************************************************************/
+
+
+import { Component } from '@angular/core';
+import { MessageBoxData} from './messageBox.data';
+import { MessageBoxService } from './messageBox.service';
+import { SdcUiComponents } from 'sdc-ui/lib/angular';
+
+@Component({
+ selector: 'message-box',
+ template: '<div id="message-box"></div>'
+})
+
+export class MessageBoxComponent {
+ modalService: SdcUiComponents.ModalService;
+
+ constructor(modalService: SdcUiComponents.ModalService, private _messageBoxService : MessageBoxService) {
+ this.modalService = modalService;
+ MessageBoxService.openModal.subscribe((messageBoxData: MessageBoxData) => {
+ modalService.openModal(this._messageBoxService.setConfig(messageBoxData))
+ });
+ }
+}
+
diff --git a/vid-webpack-master/src/app/shared/components/messageBox/messageBox.data.ts b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.data.ts
new file mode 100644
index 000000000..165140ba7
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.data.ts
@@ -0,0 +1,51 @@
+import { Subject } from 'rxjs/Subject';
+
+export class MessageBoxData {
+ title?: string;
+ message?: string;
+ size : ModalSize;
+ type: ModalType;
+ buttons: Array<IModalButtonComponent>;
+
+ constructor(title: string, message: string, type: ModalType, size : ModalSize, buttons: Array<IModalButtonComponent>) {
+ this.title = title;
+ this.message = message;
+ this.size = size;
+ this.type = type;
+ this.buttons = buttons;
+ }
+}
+
+export interface IModalConfig {
+ size?: string;
+ title?: string;
+ message?: string;
+ buttons?: Array<IModalButtonComponent>;
+ type?: string;
+}
+export interface IButtonComponent {
+ text: string;
+ disabled?: boolean;
+ type?: string;
+ size?: string;
+}
+export interface IModalButtonComponent extends IButtonComponent {
+ callback?: Function;
+ closeModal?: boolean;
+}
+export enum ModalType {
+ alert = "alert",
+ error = "error",
+ standard = "info",
+ custom = "custom",
+}
+export enum ModalSize {
+ xlarge = "xl",
+ large = "l",
+ medium = "md",
+ small = "sm",
+ xsmall = "xsm",
+}
+
+
+
diff --git a/vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.spec.ts b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.spec.ts
new file mode 100644
index 000000000..89562ac54
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.spec.ts
@@ -0,0 +1,49 @@
+import { TestBed, getTestBed } from '@angular/core/testing';
+import {
+ HttpClientTestingModule,
+ HttpTestingController
+} from '@angular/common/http/testing';
+
+import { MessageBoxService } from './messageBox.service';
+import {MessageBoxData, ModalSize, ModalType } from './messageBox.data';
+
+describe('MessageBoxService', () => {
+ let injector;
+ let service: MessageBoxService;
+ let httpMock: HttpTestingController;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [MessageBoxService]
+ });
+
+ injector = getTestBed();
+ service = injector.get(MessageBoxService);
+ httpMock = injector.get(HttpTestingController);
+ });
+
+ describe('#setConfig', () => {
+ it('should return <IModalConfig>', (done: DoneFn) => {
+ let title = "Delete Instantiation";
+ let message = "You are about to stop the instantiation process of this service. \nAll data will be lost. Are you sure you want to stop?";
+ let messageBoxData : MessageBoxData = new MessageBoxData(
+ title,
+ message,
+ ModalType.alert,
+ ModalSize.medium,
+ [
+ {text:"Stop Instantiation", size:"large", closeModal:true},
+ {text:"Cancel", size:"medium", closeModal:true}
+ ]);
+
+ let result = service.setConfig(messageBoxData);
+ expect(result.title).toEqual(title);
+ expect(result.message).toEqual(message);
+ expect(result.buttons.length).toEqual(2);
+ expect(result.type).toEqual(ModalType.alert);
+ expect(result.size).toEqual(ModalSize.medium);
+ done();
+ });
+ });
+});
diff --git a/vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.ts b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.ts
new file mode 100644
index 000000000..eaa012d3b
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/messageBox/messageBox.service.ts
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import { Subject } from 'rxjs/Subject';
+import { IModalConfig, MessageBoxData, ModalSize, ModalType } from './messageBox.data';
+
+@Injectable()
+export class MessageBoxService {
+ static openModal: Subject<MessageBoxData> = new Subject<MessageBoxData>();
+ setConfig(messageBoxData: MessageBoxData) : IModalConfig{
+ return {
+ size : ModalSize.medium,
+ title : messageBoxData.title,
+ type : messageBoxData.type,
+ message : messageBoxData.message,
+ buttons: messageBoxData.buttons
+ };
+ }
+
+}
diff --git a/vid-webpack-master/src/app/shared/components/model-information/model-information.component.ts b/vid-webpack-master/src/app/shared/components/model-information/model-information.component.ts
new file mode 100644
index 000000000..fea4c44c7
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/model-information/model-information.component.ts
@@ -0,0 +1,42 @@
+import {Component, Input} from '@angular/core';
+import * as _ from 'lodash';
+
+@Component({
+ selector: 'model-information',
+ templateUrl: 'model-information.html',
+ styleUrls: ['model-information.scss']
+})
+
+export class ModelInformationComponent {
+ private _modelInformationItems: Array<ModelInformationItem>;
+
+
+ get modelInformationItems(): Array<ModelInformationItem> {
+ return this._modelInformationItems;
+ }
+
+ @Input()
+ set modelInformationItems(_modelInformationItems: Array<ModelInformationItem>) {
+ if (_modelInformationItems) {
+ this._modelInformationItems = _modelInformationItems.filter(x => x.mandatory || (!_.isEmpty(x.values) && !_.isEmpty(x.values[0])));
+ }
+ }
+}
+
+
+export class ModelInformationItem {
+ label: string;
+ testsId: string;
+ values: Array<string>;
+ toolTipText: string;
+ mandatory: boolean;
+
+ constructor(label: string, testsId: string, values: Array<any>, toolTipText: string = "", mandatory: boolean = false,nested:boolean=false) {
+ this.label = label;
+ this.testsId = testsId;
+ this.values = values;
+ this.toolTipText = toolTipText;
+ this.mandatory = mandatory;
+ }
+
+}
diff --git a/vid-webpack-master/src/app/shared/components/model-information/model-information.html b/vid-webpack-master/src/app/shared/components/model-information/model-information.html
new file mode 100644
index 000000000..456dfdee4
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/model-information/model-information.html
@@ -0,0 +1,12 @@
+<div id="model-information">
+ <div *ngFor="let item of modelInformationItems" class="item" attr.data-tests-id="model-item-{{item.label}}">
+ <tooltip-content #a>
+ <span> {{item.toolTipText}}</span>
+ </tooltip-content>
+
+ <div class="wrapper" [tooltip]="a" [tooltipDisabled]="!item.toolTipText" tooltipPlacement="top" [tooltipAnimation]="false">
+ <label attr.data-tests-id="model-item-label-{{item.testsId}}">{{item.label}}</label>
+ <div *ngFor="let value of item.values" attr.data-tests-id="model-item-value-{{item.testsId}}">{{value}}</div>
+ </div>
+ </div>
+</div>
diff --git a/vid-webpack-master/src/app/shared/components/model-information/model-information.scss b/vid-webpack-master/src/app/shared/components/model-information/model-information.scss
new file mode 100644
index 000000000..cd42136ed
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/model-information/model-information.scss
@@ -0,0 +1,34 @@
+#model-information {
+ overflow: auto;
+
+}
+
+tooltip-content span {
+ font-family: OpenSans-Regular;
+ font-size: 12px;
+ color: #FFFFFF;
+ letter-spacing: 0;
+ line-height: 16px;
+}
+
+.item {
+ display: block;
+
+ .wrapper {
+
+ display: inline-block;
+ margin-bottom: 25px;
+
+ label {
+ font-family: OpenSans-Semibold;
+ font-size: 12px;
+ }
+
+ div {
+ font-family: OpenSans-Regular;
+ font-size: 14px;
+ }
+ }
+}
+
+
diff --git a/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.html b/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.html
new file mode 100644
index 000000000..bbe7bc78c
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.html
@@ -0,0 +1,5 @@
+<div class="width-100">
+ <div class="text-title" [ngClass]="titleClass">{{title}}</div>
+ <div class="text-subtitle" [ngClass]="subtitleClass">{{subtitle}}</div>
+ <img id="not-node-img-id" src="{{iconPath}}" alt="" class="no-content-icon" [ngClass]="iconClass" data-tests-id="no-content-icon">
+</div>
diff --git a/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.scss b/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.scss
new file mode 100644
index 000000000..1320ef731
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.scss
@@ -0,0 +1,26 @@
+.width-100 {
+ width: 100%;
+ margin-top: 126px;
+
+}
+
+.text-title {
+ font-family: OpenSans-Semibold;
+ font-size: 16px;
+ color: #4A4A4A;
+ text-align: center;
+}
+
+.text-subtitle {
+ font-family: OpenSans-Regular;
+ font-size: 16px;
+ color: #959595;
+ text-align: center;
+ margin-top: 7px;
+}
+
+.no-content-icon {
+ display: block;
+ vertical-align: middle;
+ margin: 30px auto;
+}
diff --git a/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.ts b/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.ts
new file mode 100644
index 000000000..7f4e98294
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/no-content-message-and-icon/no-content-message-and-icon.component.ts
@@ -0,0 +1,23 @@
+import {Component, Input} from '@angular/core';
+
+@Component({
+ selector: 'no-content-message-and-icon',
+ templateUrl: './no-content-message-and-icon.component.html',
+ styleUrls: ['./no-content-message-and-icon.component.scss']
+})
+
+
+export class NoContentMessageAndIconComponent {
+ constructor() {}
+
+ @Input() title: string;
+ @Input() subtitle: string;
+ @Input() iconPath: string;
+
+ @Input() titleClass: string="";
+ @Input() subtitleClass: string="";
+ @Input() iconClass: string="";
+
+}
+
+
diff --git a/vid-webpack-master/src/app/shared/components/popover/popover.component.html b/vid-webpack-master/src/app/shared/components/popover/popover.component.html
new file mode 100644
index 000000000..c5515596c
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/popover/popover.component.html
@@ -0,0 +1,8 @@
+<div
+ triggers="mouseenter:mouseleave"
+ popover="{{value}}"
+ [hidden]="value == null"
+ container="body">
+ <ng-content ></ng-content>
+</div>
+
diff --git a/vid-webpack-master/src/app/shared/components/popover/popover.component.scss b/vid-webpack-master/src/app/shared/components/popover/popover.component.scss
new file mode 100644
index 000000000..ca2800a27
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/popover/popover.component.scss
@@ -0,0 +1,4 @@
+.popover.popover-top.top {
+ color : green !important;
+ font-size: 10px;
+}
diff --git a/vid-webpack-master/src/app/shared/components/popover/popover.component.ts b/vid-webpack-master/src/app/shared/components/popover/popover.component.ts
new file mode 100644
index 000000000..d6a4c3ae1
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/popover/popover.component.ts
@@ -0,0 +1,17 @@
+import {Component, Input} from "@angular/core";
+
+@Component({
+ selector: 'custom-popover',
+ templateUrl: 'popover.component.html',
+ styles: [`
+ :host >>> .popover {
+ font-size: 13px;
+ text-align: left;
+ z-index: 10000;
+ }
+ `]
+})
+
+export class PopoverComponent {
+ @Input() value: String;
+}
diff --git a/vid-webpack-master/src/app/shared/components/spinner/spinner.component.html b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.html
new file mode 100644
index 000000000..cb11feea8
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.html
@@ -0,0 +1,2 @@
+<div *ngIf="show"
+ class="spinner"></div>
diff --git a/vid-webpack-master/src/app/shared/components/spinner/spinner.component.scss b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.scss
new file mode 100644
index 000000000..d31dfed80
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.scss
@@ -0,0 +1,87 @@
+.spinner {
+ height: 150px;
+ width: 150px;
+ margin: 0 auto;
+ -webkit-animation: rotation .6s infinite linear;
+ animation: rotation .6s infinite linear;
+ border: 6px solid rgba(0, 174, 239, 0.01);
+ border-radius: 100%;
+ position: absolute;
+ z-index: 1000;
+ left: 50%;
+ right: 50%;
+ top: 50%;
+ bottom: 50%;
+}
+
+
+
+.spinner:before {
+ content: "";
+ display: block;
+ position: absolute;
+ top: -6px;
+ height: 100%;
+ width: 100%;
+ border-top: 6px solid #009fdb;
+ border-left: 6px solid transparent;
+ border-bottom: 6px solid #c3161600;
+ border-right: 6px solid transparent;
+ border-radius: 100%;
+}
+
+@-webkit-keyframes rotation {
+ from {-webkit-transform: rotate(0deg);}
+ to {-webkit-transform: rotate(359deg);}
+}
+@-moz-keyframes rotation {
+ from {-moz-transform: rotate(0deg);}
+ to {-moz-transform: rotate(359deg);}
+}
+@-o-keyframes rotation {
+ from {-o-transform: rotate(0deg);}
+ to {-o-transform: rotate(359deg);}
+}
+@keyframes rotation {
+ from {transform: rotate(0deg);}
+ to {transform: rotate(359deg);}
+}
+
+.spinner-sm {
+ height:16px;
+ width:16px;
+}
+
+.spinner-md {
+ height:40px;
+ width:40px;
+}
+
+.spinner-lr {
+ height:150px;
+ width:150px;
+}
+
+.spinner-red {
+ border:6px solid rgba(216, 27, 34, .15);
+}
+
+.spinner-red:before {
+ border-top:6px solid rgba(216, 27, 34, 1);
+}
+
+.spinner-green {
+ border:6px solid rgba(40, 183, 121, .15);
+}
+
+.spinner-green:before {
+ border-top:6px solid rgba(40, 183, 121, 1);
+}
+
+.spinner-grey {
+ border:6px solid rgba(139, 146, 154, .15);
+}
+
+.spinner-grey:before {
+ border-top:6px solid rgba(139, 146, 154, 1);
+}
diff --git a/vid-webpack-master/src/app/shared/components/spinner/spinner.component.spec.ts b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.spec.ts
new file mode 100644
index 000000000..531ee8c62
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.spec.ts
@@ -0,0 +1,42 @@
+import {async, ComponentFixture, TestBed} from '@angular/core/testing';
+import {HttpClientTestingModule} from '@angular/common/http/testing';
+import { SpinnerComponent } from './spinner.component';
+
+describe('Spinner component', () => {
+ let component: SpinnerComponent;
+ let fixture: ComponentFixture<SpinnerComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [HttpClientTestingModule],
+ providers: [],
+ declarations: [SpinnerComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SpinnerComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('component should be defined', () => {
+ expect(component).toBeDefined();
+ });
+
+
+ it('component constructor should subscribe of showSpinner event with true', ()=> {
+ SpinnerComponent.showSpinner.next(true);
+ expect(component.show).toBeTruthy();
+ });
+
+ it('component constructor should subscribe of showSpinner event with false', ()=> {
+ SpinnerComponent.showSpinner.next(false);
+ expect(component.show).toBeFalsy();
+ });
+
+
+
+
+});
diff --git a/vid-webpack-master/src/app/shared/components/spinner/spinner.component.ts b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.ts
new file mode 100644
index 000000000..0ce5d2074
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/spinner/spinner.component.ts
@@ -0,0 +1,18 @@
+import { Component, Input } from '@angular/core';
+import { Subject } from 'rxjs/Subject';
+
+@Component({
+ selector : 'spinner-component',
+ templateUrl : './spinner.component.html',
+ styleUrls : ['./spinner.component.scss']
+})
+export class SpinnerComponent {
+ show : boolean = false;
+ static showSpinner: Subject<boolean> = new Subject<boolean>();
+
+ constructor(){
+ SpinnerComponent.showSpinner.subscribe((status) => {
+ this.show = status;
+ })
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.spec.ts b/vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.spec.ts
new file mode 100644
index 000000000..ec9f3f73e
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.spec.ts
@@ -0,0 +1,39 @@
+import { ReflectiveInjector } from '@angular/core';
+import { NumbersLettersUnderscoreValidator } from './numbersLettersUnderscore.validator';
+
+describe('Numbers letters underscore validator', () => {
+ let injector;
+ let service: NumbersLettersUnderscoreValidator;
+
+ beforeEach(() => {
+
+ let injector = ReflectiveInjector.resolveAndCreate([
+ NumbersLettersUnderscoreValidator
+ ]);
+
+ service = injector.get(NumbersLettersUnderscoreValidator);
+ });
+
+
+ describe('#valid', () => {
+ it("'legal' should return null", ()=> {
+ let legalVal: string = "legal";
+ let result = NumbersLettersUnderscoreValidator.valid(legalVal);
+ expect(result).toBeNull();
+ });
+
+ it("'illegal' should return object with invalidNumberLettersUnderscore true", ()=> {
+ let illegalVal: string = "illegal-Val";
+ let result = NumbersLettersUnderscoreValidator.valid(illegalVal);
+ expect(result.invalidNumberLettersUnderscore).toBeTruthy();
+ });
+
+ it("'null' should return null", ()=> {
+ let nullVal: string = null
+ let result = NumbersLettersUnderscoreValidator.valid(nullVal);
+ expect(result).toBeNull();
+ });
+
+
+ });
+});
diff --git a/vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.ts b/vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.ts
new file mode 100644
index 000000000..418bdfc4d
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/validators/numbersLettersUnderscore/numbersLettersUnderscore.validator.ts
@@ -0,0 +1,20 @@
+import { Injectable } from '@angular/core';
+import { isNullOrUndefined, isString } from 'util';
+
+@Injectable()
+export class NumbersLettersUnderscoreValidator {
+ static valid(control: any) {
+ let reg = /^[a-zA-Z0-9_]*$/;
+
+ if(isNullOrUndefined(control)) return null;
+ let val = isString(control) ? control : control.value;
+ if (val === null) {
+ return {'invalidNumberLettersUnderscore': true};
+ }
+ if (reg.test(val)) {
+ return null;
+ } else {
+ return {'invalidNumberLettersUnderscore': true};
+ }
+ }
+}