aboutsummaryrefslogtreecommitdiffstats
path: root/vid-webpack-master/src/app/shared/components/customModal
diff options
context:
space:
mode:
authorYoav Schneiderman <yoav.schneiderman@intl.att.com>2020-01-08 14:46:14 +0200
committerIttay Stern <ittay.stern@att.com>2020-01-09 13:29:49 +0000
commit4ef3ee778fc944cdfe28146d4eed360ce096e5ee (patch)
treec641429928518b64f7a39acd1d241043a28978cd /vid-webpack-master/src/app/shared/components/customModal
parente8414b1fe839291418ead3a7e5a64bf382dc1121 (diff)
Upgrade to Angular 8
Issue-ID: VID-742 Change-Id: Ic4b3aae71d4c946e23d854847a49aa7e020c465d Signed-off-by: Yoav Schneiderman <yoav.schneiderman@intl.att.com>
Diffstat (limited to 'vid-webpack-master/src/app/shared/components/customModal')
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.html16
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.scss273
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.ts28
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/components/modalCloseButton/modal-close-button.component.ts36
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/directives/ripple-click.animation.directive.ts47
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/modal.component.html46
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/modal.component.ts166
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/models/button.type.ts8
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/models/modal-button.model.ts15
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/models/modal.model.ts26
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/models/modal.placement.ts6
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/models/modal.size.ts7
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/models/modal.type.ts10
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/services/create-dynamic-component.service.ts107
-rw-r--r--vid-webpack-master/src/app/shared/components/customModal/services/modal.service.ts64
15 files changed, 855 insertions, 0 deletions
diff --git a/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.html b/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.html
new file mode 100644
index 000000000..753a3923b
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.html
@@ -0,0 +1,16 @@
+<div>
+ <button class="custom-button sdc-button__{{ type }} btn-{{ size }} {{ iconPositionClass }}"
+ [disabled]="disabled || show_spinner"
+ [attr.data-tests-id]="testId">
+ <svg-icon
+ *ngIf="icon_name"
+ [name]="icon_name"
+ [mode]="icon_mode"
+ [size]="'medium'"
+ >
+ </svg-icon>
+ {{text}}
+ </button>
+ <svg-icon *ngIf="show_spinner" name="spinner" [size]="'medium'" class="sdc-button__spinner"
+ [ngClass]="{left: spinner_position === placement.right}"></svg-icon>
+</div>
diff --git a/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.scss b/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.scss
new file mode 100644
index 000000000..89f90d44d
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.scss
@@ -0,0 +1,273 @@
+.custom-button {
+ order: 1;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: row;
+ outline: none;
+ border-radius: 2px;
+ padding: 0 12px;
+ height: 36px;
+ line-height: 36px;
+ width: 120px;
+ min-width: 90px;
+ cursor: pointer;
+ text-align: center;
+ text-transform: uppercase;
+ font-family: OpenSans-Regular, Arial, sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 14px;
+ /*** Sizes ***/
+ /*** Sizes ***/
+ /*** Buttons with icons ***/
+}
+
+.custom-button:disabled {
+ cursor: default;
+}
+
+.custom-button.sdc-button__primary {
+ border: 1px solid transparent;
+ background-color: #009fdb;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__primary:not(:disabled):hover, .custom-button.sdc-button__primary:not(:disabled):active {
+ background-color: #1eb9f3;
+}
+
+.custom-button.sdc-button__primary:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #1eb9f3;
+ box-shadow: 0px 0px 0px 1px #1eb9f3;
+}
+
+.custom-button.sdc-button__primary:disabled {
+ background: #9dd9ef;
+}
+
+.custom-button.sdc-button__secondary {
+ border: 1px solid #009fdb;
+ background-color: transparent;
+ color: #009fdb;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):hover, .custom-button.sdc-button__secondary:not(:disabled):active {
+ background-color: #1eb9f3;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):focus:not(:active) {
+ color: #1eb9f3;
+ box-shadow: inset 0px 0px 0px 0px #0568ae, 0px 0px 0px 1px #009fdb;
+}
+
+.custom-button.sdc-button__secondary:not(:disabled):focus:not(:active):hover {
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__secondary:disabled {
+ color: #9dd9ef;
+ border-color: #9dd9ef;
+}
+
+.custom-button.sdc-button__link {
+ background-color: transparent;
+ color: #009fdb;
+ fill: #009fdb;
+ border: none;
+}
+
+.custom-button.sdc-button__link:not(:disabled):hover, .custom-button.sdc-button__link:not(:disabled):active {
+ color: #1eb9f3;
+}
+
+.custom-button.sdc-button__link:not(:disabled):focus:not(:active) {
+ border: 1px solid #0568ae;
+ color: #1eb9f3;
+}
+
+.custom-button.sdc-button__link:disabled {
+ color: #9dd9ef;
+}
+
+.custom-button.sdc-button__success {
+ border: 1px solid transparent;
+ background-color: #4ca90c;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__success:not(:disabled):hover, .custom-button.sdc-button__success:not(:disabled):active {
+ background-color: #57c00e;
+}
+
+.custom-button.sdc-button__success:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #57c00e;
+ box-shadow: 0px 0px 0px 1px #57c00e;
+}
+
+.custom-button.sdc-button__success:disabled {
+ background: #a5d485;
+}
+
+.custom-button.sdc-button__error, .custom-button.sdc-button__alert {
+ border: 1px solid transparent;
+ background-color: #cf2a2a;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__error:not(:disabled):hover, .custom-button.sdc-button__error:not(:disabled):active, .custom-button.sdc-button__alert:not(:disabled):hover, .custom-button.sdc-button__alert:not(:disabled):active {
+ background-color: #ed4141;
+}
+
+.custom-button.sdc-button__error:not(:disabled):focus:not(:active), .custom-button.sdc-button__alert:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #ed4141;
+ box-shadow: 0px 0px 0px 1px #ed4141;
+}
+
+.custom-button.sdc-button__error:disabled, .custom-button.sdc-button__alert:disabled {
+ background: #f4adad;
+}
+
+.custom-button.sdc-button__warning {
+ border: 1px solid transparent;
+ background-color: #ffb81c;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__warning:not(:disabled):hover, .custom-button.sdc-button__warning:not(:disabled):active {
+ background-color: #f6c632;
+}
+
+.custom-button.sdc-button__warning:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #f6c632;
+ box-shadow: 0px 0px 0px 1px #f6c632;
+}
+
+.custom-button.sdc-button__warning:disabled {
+ background: #ffdb8d;
+}
+
+.custom-button.sdc-button__info {
+ border: 1px solid transparent;
+ background-color: #009fdb;
+ color: #ffffff;
+}
+
+.custom-button.sdc-button__info:not(:disabled):hover, .custom-button.sdc-button__info:not(:disabled):active {
+ background-color: #1eb9f3;
+}
+
+.custom-button.sdc-button__info:not(:disabled):focus:not(:active) {
+ border: 1px solid #ffffff;
+ background-color: #1eb9f3;
+ box-shadow: 0px 0px 0px 1px #1eb9f3;
+}
+
+.custom-button.sdc-button__info:disabled {
+ background: #9dd9ef;
+}
+
+.custom-button.sdc-button__file-opener input[type=file] {
+ height: 36px;
+ opacity: 0;
+ position: absolute;
+ cursor: pointer;
+}
+
+.custom-button.btn-xx-large {
+ width: 350px;
+}
+
+.custom-button.btn-xx-large input[type=file] {
+ width: 350px;
+}
+
+.custom-button.btn-x-large {
+ width: 250px;
+}
+
+.custom-button.btn-x-large input[type=file] {
+ width: 250px;
+}
+
+.custom-button.btn-large {
+ width: 180px;
+}
+
+.custom-button.btn-large input[type=file] {
+ width: 180px;
+}
+
+.custom-button.btn-medium {
+ width: 140px;
+}
+
+.custom-button.btn-medium input[type=file] {
+ width: 140px;
+}
+
+.custom-button.btn-small {
+ width: 110px;
+}
+
+.custom-button.btn-small input[type=file] {
+ width: 110px;
+}
+
+.custom-button.btn-x-small {
+ width: 90px;
+}
+
+.custom-button.btn-x-small input[type=file] {
+ width: 90px;
+}
+
+.custom-button.btn-default {
+ width: auto;
+}
+
+.custom-button.btn-default input[type=file] {
+ width: auto;
+}
+
+.custom-button.sdc-icon-right {
+ flex-direction: row-reverse;
+}
+
+.custom-button.sdc-icon-right .svg-icon {
+ margin-left: 15px;
+}
+
+.custom-button.sdc-icon-left {
+ flex-direction: row;
+}
+
+.custom-button.sdc-icon-left .svg-icon {
+ margin-right: 15px;
+}
+
+.custom-button svg {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.sdc-button__wrapper {
+ display: inline-flex;
+}
+
+.sdc-button__spinner {
+ padding-top: 6px;
+ margin: 0 2px;
+}
+
+.sdc-button__spinner.left {
+ order: 2;
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.ts b/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.ts
new file mode 100644
index 000000000..d93c67851
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.ts
@@ -0,0 +1,28 @@
+import {Component, EventEmitter, HostListener, Input, Output} from "@angular/core";
+import {CustomButtonComponent} from "../../../customButton/custom-button.component";
+
+@Component({
+ selector: "custom-modal-button",
+ templateUrl: './modal-button.component.html',
+ styleUrls: ['./modal-button.component.scss']
+})
+export class CustomModalButtonComponent extends CustomButtonComponent {
+
+ @Input() public id?: string;
+ @Input() public callback: Function;
+ @Input() public closeModal: boolean;
+ @Output() closeModalEvent: EventEmitter<any> = new EventEmitter<any>();
+ @HostListener('click') invokeCallback = (): void => {
+ if (this.callback) {
+ this.callback();
+ }
+ if (this.closeModal) {
+ this.closeModalEvent.emit();
+ }
+ }
+
+ constructor() {
+ super();
+ this.closeModal = false;
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/components/modalCloseButton/modal-close-button.component.ts b/vid-webpack-master/src/app/shared/components/customModal/components/modalCloseButton/modal-close-button.component.ts
new file mode 100644
index 000000000..a3e741a32
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/components/modalCloseButton/modal-close-button.component.ts
@@ -0,0 +1,36 @@
+import {Component, ComponentRef, Input} from "@angular/core";
+import {ModalComponent} from "../../modal.component";
+import {CustomButtonComponent} from "../../../customButton/custom-button.component";
+import {RippleAnimationAction} from "../../directives/ripple-click.animation.directive";
+
+
+@Component({
+ selector: "sdc-modal-close-button",
+ template: `
+ <div class="sdc-modal__close-button"
+ customRippleClickAnimation
+ [ngClass]="disabled ? 'disabled' : ''"
+ [rippleOnAction]="!disabled && rippleAnimationAction"
+ [attr.data-tests-id]="testId"
+ (click)="!disabled && closeModal('close')"
+ >
+ <svg-icon name="close" [mode]="disabled? 'secondary' : 'info'" size="small"></svg-icon>
+ </div>
+ `
+})
+export class ModalCloseButtonComponent extends CustomButtonComponent {
+
+ @Input() testId: string;
+ @Input() disabled: boolean;
+ @Input() modalInstanceRef: ComponentRef<ModalComponent>;
+
+ public rippleAnimationAction: RippleAnimationAction = RippleAnimationAction.MOUSE_ENTER;
+
+ constructor() {
+ super();
+ }
+
+ public closeModal = (btnName: string): void => {
+ this.modalInstanceRef.instance.closeModal(btnName);
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/directives/ripple-click.animation.directive.ts b/vid-webpack-master/src/app/shared/components/customModal/directives/ripple-click.animation.directive.ts
new file mode 100644
index 000000000..d343d5dc2
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/directives/ripple-click.animation.directive.ts
@@ -0,0 +1,47 @@
+import { Directive, Input, HostBinding, HostListener } from "@angular/core";
+
+export enum RippleAnimationAction {
+ CLICK = 0,
+ MOUSE_ENTER = 1
+}
+
+@Directive({
+ selector: `[customRippleClickAnimation]`
+})
+export class CustomRippleClickAnimationDirective {
+ private animated: boolean;
+
+ @Input() rippleClickDisabled: boolean;
+ @Input() rippleOnAction:RippleAnimationAction = RippleAnimationAction.CLICK;
+
+ @HostBinding('class.sdc-ripple-click__animated') animationClass: string;
+
+ @HostListener('click') onClick() {
+ if(this.rippleOnAction === RippleAnimationAction.CLICK){
+ this.animateStart();
+ }
+ }
+
+ @HostListener('mouseenter') onMouseEnter() {
+ //console.log("Mouseenter!", this.rippleOnAction);
+ if(this.rippleOnAction === RippleAnimationAction.MOUSE_ENTER){
+ this.animateStart();
+ }
+ }
+
+ private animateStart():void{
+ if (!this.rippleClickDisabled) {
+ this.animated = true;
+ this.animationClass = 'sdc-ripple-click__animated';
+ }
+ }
+ @HostListener('animationend') onAnimationComplete() {
+ this.animated = false;
+ this.animationClass = '';
+ }
+
+ constructor() {
+ this.rippleClickDisabled = false;
+ this.animated = false;
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/modal.component.html b/vid-webpack-master/src/app/shared/components/customModal/modal.component.html
new file mode 100644
index 000000000..11455bc32
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/modal.component.html
@@ -0,0 +1,46 @@
+<div>
+ <div class="modal-background" [@toggleBackground]="modalVisible" ></div>
+ <div class="sdc-modal {{size}}">
+ <div class="sdc-modal__wrapper sdc-modal-type-{{type}}" [@toggleModal]="modalVisible" (@toggleModal.done)="modalToggled($event)">
+
+ <div class="sdc-modal__header sdc-{{type}}__header">
+ <div class="sdc-modal__icon" *ngIf="type!='custom'" [innerHtml]="svgIconContentSafeHtml"></div>
+
+ <div *ngIf="title" class="title" >
+ {{ title }}
+ <svg-icon
+ *ngIf="titleIcon"
+ [name]="titleIcon.iconName"
+ [mode]="titleIcon.iconMode"
+ [size]="titleIcon.iconSize">
+ </svg-icon>
+ </div>
+ <sdc-modal-close-button #modalCloseButton [testId]="'close' | calculateTestId : testId" [modalInstanceRef]="instanceRef"></sdc-modal-close-button>
+ </div>
+
+ <div class="sdc-modal__content">
+ <div *ngIf="message" [innerHtml]="message"></div>
+ <div #dynamicContentContainer></div>
+ <div class="disabled-modal" *ngIf="isDisabled"></div>
+ </div>
+
+ <div class="sdc-modal__footer">
+ <custom-modal-button *ngFor="let button of buttons"
+ [text]="button.text"
+ [type]="button.type || 'primary'"
+ [disabled]="button.disabled"
+ [size] = "button.size ? button.size : 'default'"
+ [closeModal]="button.closeModal"
+ [spinner_position]="button.spinner_position"
+ [show_spinner]="button.show_spinner"
+ [callback]="button.callback"
+ [testId]="'button-' + button.text | calculateTestId : testId"
+ (closeModalEvent)="closeModal(button.text)"
+ >
+ </custom-modal-button>
+ </div>
+
+ </div>
+ </div>
+</div>
+
diff --git a/vid-webpack-master/src/app/shared/components/customModal/modal.component.ts b/vid-webpack-master/src/app/shared/components/customModal/modal.component.ts
new file mode 100644
index 000000000..eb001c068
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/modal.component.ts
@@ -0,0 +1,166 @@
+import {
+ Component,
+ ComponentRef,
+ EventEmitter,
+ Input,
+ OnInit,
+ Output,
+ Renderer,
+ ViewChild,
+ ViewContainerRef
+} from "@angular/core";
+import {animate, style, transition, trigger} from "@angular/animations";
+import {TitleIconDetails} from "./models/modal.model";
+import {ModalType} from "./models/modal.type";
+import {DomSanitizer, SafeHtml} from "@angular/platform-browser";
+import {ModalCloseButtonComponent} from "./components/modalCloseButton/modal-close-button.component";
+import {CustomModalButtonComponent} from "./components/modalButton/modal-button.component";
+
+@Component({
+ selector: 'sdc-modal',
+ templateUrl: './modal.component.html',
+ animations: [
+ trigger('toggleBackground', [
+ transition('* => 1', [style({ opacity: 0 }), animate('.45s cubic-bezier(0.23, 1, 0.32, 1)')]),
+ transition('1 => *', [animate('.35s cubic-bezier(0.23, 1, 0.32, 1)', style({ opacity: 0 }))])
+ ]),
+ trigger('toggleModal', [
+ transition('* => 1', [style({ opacity: 0, transform: 'translateY(-80px)' }), animate('.45s cubic-bezier(0.23, 1, 0.32, 1)')]),
+ transition('1 => *', [style({ opacity: 1, transform: 'translateY(0px)' }), animate('.35s ease-in-out', style({ opacity: 0, transform: 'translateY(-80px)' }))])
+ ])
+ ]
+})
+
+export class ModalComponent implements OnInit {
+
+ @Input() size: string; 'xl|l|md|sm|xsm';
+ @Input() title: string;
+ @Input() titleIcon: TitleIconDetails;
+ @Input() message: string;
+ @Input() buttons: CustomModalButtonComponent[];
+ @Input() type: ModalType;
+ @Input() testId: string;
+ @Input() isDisabled: boolean;
+ @Input() instanceRef: ComponentRef<ModalComponent>; // the component ref is injected to the component in order to destroy the componet from itself
+
+ @Output() onClose : EventEmitter<string> = new EventEmitter<string>();
+
+ @ViewChild('modalCloseButton', {static: false})
+ set refCloseButton(_modalCloseButton: ModalCloseButtonComponent) {
+ this.modalCloseButton = _modalCloseButton;
+ }
+
+ modalVisible: boolean;
+ // Allows for custom component as body instead of simple message.
+ @ViewChild('dynamicContentContainer', { read: ViewContainerRef, static: true }) dynamicContentContainer: ViewContainerRef;
+ innerModalContent: ComponentRef<any>;
+
+ public calculatedTestId: string;
+ public modalCloseButton: ModalCloseButtonComponent;
+ public svgIconContentSafeHtml: SafeHtml;
+
+
+ private infoSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24">
+ <defs><path fill="#000" id="info-a" d="M11,20 C6,20 2,16 2,11 C2,6 6,2 11,2 C16,2 20,6 20,11 C20,16 16,20 11,20 M11,0 C4.9,0 0,4.9 0,11 C0,17.101 4.9,22 11,22 C17.1,22 22,17.101 22,11 C22,4.9 17.1,0 11,0 M11,10 C10.4,
+ 10 10,10.4 10,11 L10,15 C10,15.601 10.4,16 11,16 C11.6,16 12,15.601 12,15 L12,11 C12,10.4 11.6,10 11,10 M10.2998,6.2998 C10.0998,6.4998 9.9998,6.6998 9.9998,6.9998 C9.9998,7.2998 10.0998,7.4998 10.2998,7.6998 C10.4998,
+ 7.9008 10.6998,7.9998 10.9998,7.9998 C11.2998,7.9998 11.4998,7.9008 11.6998,7.6998 C11.9008,7.4998 11.9998,7.2998 11.9998,6.9998 C11.9998,6.6998 11.9008,6.4998 11.6998,6.2998 C11.2998,5.9008 10.6998,5.9008 10.2998,6.2998"/>
+ </defs><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><use class="sdc-modal__svg-use" xlink:href="#info-a"/></g></svg>`;
+ private warningSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24"><defs><path fill="#000" id="alert-a" d="M20.5815,18.7997 C20.3815,
+ 18.9997 20.0815,19.0997 19.8815,19.0997 L2.8815,19.0997 C2.6815,19.0997 2.5815,19.0997 2.3815,18.9997 C1.8815,18.6997 1.7815,18.0997 1.9815,17.5997 L10.4815,3.4997 C10.5815,3.4007 10.6815,3.1997 10.7815,3.1997 C11.2815,
+ 2.9007 11.8815,3.0997 12.1815,3.4997 L20.6825,17.5997 C20.7815,17.6997 20.7815,17.9007 20.7815,18.0997 C20.8815,18.4007 20.6825,18.5997 20.5815,18.7997 M22.3815,16.5997 L13.9815,2.4007 C13.5815,1.6997 12.8815,1.1997 12.0815,
+ 0.9997 C11.2815,0.7997 10.4815,0.9007 9.7815,1.2997 C9.3815,1.4997 8.9815,1.9007 8.7815,2.2997 L0.3815,16.5997 C-0.4185,17.9997 0.0815,19.9007 1.4815,20.6997 C1.8815,20.9997 2.3815,21.0997 2.8815,21.0997 L19.8815,
+ 21.0997 C20.6825,21.0997 21.4815,20.7997 21.9815,20.1997 C22.5815,19.5997 22.8815,18.9007 22.8815,18.0997 C22.7815,17.5997 22.6825,16.9997 22.3815,16.5997 M11,7 C10.4,7 10,7.4 10,8 L10,12 C10,12.601 10.4,13 11,13 C11.6,13 12,
+ 12.601 12,12 L12,8 C12,7.4 11.6,7 11,7 M10.3,15.3 C10.1,15.499 10,15.699 10,15.999 C10,16.3 10.1,16.499 10.3,16.699 C10.5,16.9 10.7,16.999 11,16.999 C11.3,16.999 11.5,16.9 11.7,16.699 C11.9,16.499 12,16.199 12,15.999 C12,
+ 15.8 11.9,15.499 11.7,15.3 C11.3,14.9 10.7,14.9 10.3,15.3"/></defs><g fill="#ffb81c" fill-rule="evenodd" transform="translate(1 1)"><use class="sdc-modal__svg-use" xlink:href="#alert-a"/></g></svg>`;
+ private errorSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24"><defs><path fill="#000" id="x-a" d="M11,20 C6,20 2,16 2,11 C2,6 6,2 11,
+ 2 C16,2 20,6 20,11 C20,16 16,20 11,20 M11,0 C4.9,0 0,4.9 0,11 C0,17.1 4.9,22 11,22 C17.1,22 22,17.1 22,11 C22,4.9 17.1,0 11,0 M14.2591,7.29935 C13.8591,6.90035 13.2591,6.90035 12.8591,7.29935 L10.5591,9.59935 L8.2591,
+ 7.29935 C7.8591,6.90035 7.2591,6.90035 6.8591,7.29935 C6.4591,7.69935 6.4591,8.29935 6.8591,8.69935 L9.1581,10.99935 L6.8591,13.29935 C6.4591,13.69935 6.4591,14.29935 6.8591,14.69935 C7.0591,14.90035 7.2591,14.99935 7.5591,
+ 14.99935 C7.8591,14.99935 8.0591,14.90035 8.2591,14.69935 L10.5591,12.40035 L12.8591,14.69935 C13.0591,14.90035 13.3591,14.99935 13.5591,14.99935 C13.7591,14.99935 14.0591,14.90035 14.2591,14.69935 C14.6581,14.29935 14.6581,
+ 13.69935 14.2591,13.29935 L11.9591,10.99935 L14.2591,8.69935 C14.6581,8.29935 14.6581,7.69935 14.2591,7.29935"/></defs><g fill="none" fill-rule="evenodd" transform="translate(1 1)">
+ <use class="sdc-modal__svg-use" xlink:href="#x-a"/></g></svg>`;
+ private successSvg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30" viewBox="0 0 24 24" fill="#4ca90c"><path id="success+20-a" d="M20.1825992,10.445793 C20.6735306,
+ 10.445793 21.0008182,10.7730806 21.0008182,11.264012 L21.0008182,12.0004091 C21.0008182,16.9915451 16.9915451,21 12.0004091,21 C7.00927315,21 3,16.9915451 3,12.0004091 C3,7.00927315 7.00927315,3 12.0004091,3 C13.3095595,3 14.536888,
+ 3.3272876 15.6823947,3.81821901 C16.0915042,3.98186281 16.255148,4.47279422 16.0915042,4.88190372 C15.9278604,5.29101323 15.436929,5.45465703 15.0278194,5.29101323 C14.0459566,4.88190372 13.0640938,4.63643802 12.0004091,
+ 4.63643802 C7.90931406,4.63643802 4.63643802,7.90931406 4.63643802,12.0004091 C4.63643802,16.0906859 7.90931406,19.363562 12.0004091,19.363562 C16.0915042,19.363562 19.3643802,16.0906859 19.3643802,12.0004091 L19.3643802,
+ 11.264012 C19.3643802,10.7730806 19.6916678,10.445793 20.1825992,10.445793 Z M21.5737352,4.06343925 C21.9002046,4.39072685 21.9002046,4.88165826 21.5737352,5.20894586 L12.5733261,14.209355 C12.4096823,14.3729988 12.1642166,
+ 14.4548207 12.0005728,14.4548207 C11.836929,14.4548207 11.5914632,14.3729988 11.4278194,14.209355 L8.97316242,11.7546979 C8.64587481,11.4274103 8.64587481,10.9364789 8.97316242,10.6091913 C9.30045002,10.2819037 9.79138143,
+ 10.2819037 10.118669,10.6091913 L12.0005728,12.491095 L20.4282286,4.06343925 C20.7555162,3.73615164 21.2464476,3.73615164 21.5737352,4.06343925 Z"></path></svg>`;
+ private noSvg = ``;
+
+ constructor(private renderer: Renderer,
+ private domSanitizer: DomSanitizer) {
+ this.modalVisible = true;
+ }
+
+ ngOnInit() {
+
+ switch (this.type) {
+ case ModalType.info:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.infoSvg);
+ break;
+ case ModalType.warning:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.warningSvg);
+ break;
+ case ModalType.error:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.errorSvg);
+ break;
+ case ModalType.success:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.successSvg);
+ break;
+ default:
+ this.svgIconContentSafeHtml = this.domSanitizer.bypassSecurityTrustHtml(this.noSvg);
+ }
+ }
+
+ public modalToggled = (toggleEvent: any) => {
+ if (!toggleEvent.toState) {
+ this.instanceRef.destroy();
+ }
+ }
+
+ public getCloseButton = (): ModalCloseButtonComponent => {
+ return this.modalCloseButton;
+ }
+
+ public getButtonById = (id: string): CustomModalButtonComponent => {
+ // Support ES5
+ // return this.buttons.find((button) => {
+ return this.buttons.filter((button) => {
+ return button.id && button.id === id;
+ })[0];
+ }
+
+ public getButtons = (): CustomModalButtonComponent[] => {
+ return this.buttons;
+ }
+
+ public setButtons = (_buttons: CustomModalButtonComponent[]): void => {
+ this.buttons = _buttons;
+ }
+
+ public getTitle = (): string => {
+ return this.title;
+ }
+
+ public setTitle = (_title: string): void => {
+ this.title = _title;
+ }
+
+ public hoverAnimation(evn: MouseEvent) {
+ this.renderer.setElementClass(evn.target as HTMLElement, 'sdc-ripple-click__animated', true);
+ // evn.taregt.classList.add('sdc-ripple-click__animated');
+ }
+
+ public closeModal = (btnName : string): void => {
+ this.onClose.emit(btnName);
+ this.modalVisible = false;
+ }
+
+ public disabledModal = (isDisabled: boolean): void => {
+ this.isDisabled = isDisabled;
+ this.buttons.forEach((button: CustomModalButtonComponent) => {
+ button.disabled = isDisabled;
+ });
+ this.modalCloseButton.disabled = false;
+ }
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/models/button.type.ts b/vid-webpack-master/src/app/shared/components/customModal/models/button.type.ts
new file mode 100644
index 000000000..a0673013d
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/models/button.type.ts
@@ -0,0 +1,8 @@
+export enum ButtonType {
+ primary = 'primary',
+ secondary = 'secondary',
+ success = 'success',
+ error = 'error',
+ warning = 'warning',
+ info = 'info'
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/models/modal-button.model.ts b/vid-webpack-master/src/app/shared/components/customModal/models/modal-button.model.ts
new file mode 100644
index 000000000..5e1f4a4a8
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/models/modal-button.model.ts
@@ -0,0 +1,15 @@
+import {ButtonType} from "onap-ui-angular/dist/dist/common";
+import {Placement} from "./modal.placement";
+
+export interface IButtonComponent {
+ text: string;
+ disabled?: boolean;
+ type?: ButtonType;
+ testId?: string;
+ preventDoubleClick?: boolean;
+ icon_name?: string;
+ icon_position?: string;
+ show_spinner?: boolean;
+ spinner_position?: Placement;
+ size?: string;
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/models/modal.model.ts b/vid-webpack-master/src/app/shared/components/customModal/models/modal.model.ts
new file mode 100644
index 000000000..4b814f0aa
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/models/modal.model.ts
@@ -0,0 +1,26 @@
+import {ModalType} from "./modal.type";
+import {IButtonComponent} from "./modal-button.model";
+
+export interface IModalConfig {
+ size?: string; // xl|l|md|sm|xsm
+ title?: string;
+ titleIcon?: TitleIconDetails;
+ message?: string;
+ buttons?: IModalButtonComponent[];
+ testId?: string;
+ type?: ModalType;
+}
+
+export interface IModalButtonComponent extends IButtonComponent {
+ id?: string;
+ callback?: () => void;
+ closeModal?: boolean;
+}
+
+export interface TitleIconDetails {
+ iconName?: string;
+ iconMode?: string;
+ iconSize?: string;
+}
+
+
diff --git a/vid-webpack-master/src/app/shared/components/customModal/models/modal.placement.ts b/vid-webpack-master/src/app/shared/components/customModal/models/modal.placement.ts
new file mode 100644
index 000000000..f7f229cd4
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/models/modal.placement.ts
@@ -0,0 +1,6 @@
+export enum Placement {
+ left = 'left',
+ right = 'right',
+ top = 'top',
+ bottom = 'bottom'
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/models/modal.size.ts b/vid-webpack-master/src/app/shared/components/customModal/models/modal.size.ts
new file mode 100644
index 000000000..0a96810c7
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/models/modal.size.ts
@@ -0,0 +1,7 @@
+export enum ModalSize {
+ xlarge = "xl",
+ large = "l",
+ medium = "md",
+ small = "sm",
+ xsmall = "xsm"
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/models/modal.type.ts b/vid-webpack-master/src/app/shared/components/customModal/models/modal.type.ts
new file mode 100644
index 000000000..ca987ebba
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/models/modal.type.ts
@@ -0,0 +1,10 @@
+export enum ModalType {
+ info = 'info',
+ warning = 'warning',
+ error = 'error',
+ success = 'success',
+ action = 'action',
+ custom = 'custom'
+}
+
+
diff --git a/vid-webpack-master/src/app/shared/components/customModal/services/create-dynamic-component.service.ts b/vid-webpack-master/src/app/shared/components/customModal/services/create-dynamic-component.service.ts
new file mode 100644
index 000000000..64fe66ce6
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/services/create-dynamic-component.service.ts
@@ -0,0 +1,107 @@
+import {
+ ApplicationRef,
+ ComponentFactoryResolver,
+ ComponentRef,
+ EmbeddedViewRef,
+ Injectable,
+ Injector, Type, ViewContainerRef
+} from "@angular/core";
+
+@Injectable()
+export class CreateDynamicComponentService {
+
+ constructor(private componentFactoryResolver: ComponentFactoryResolver,
+ private applicationRef: ApplicationRef,
+ private injector: Injector) {
+ }
+
+ /**
+ * Gets the root view container to inject the component to.
+ *
+ * @returns {ComponentRef<any>}
+ *
+ * @memberOf InjectionService
+ */
+ private getRootViewContainer(): ComponentRef<any> {
+ const rootComponents = this.applicationRef['components'];
+ if (rootComponents.length) {
+ return rootComponents[0];
+ }
+ throw new Error('View Container not found! ngUpgrade needs to manually set this via setRootViewContainer.');
+ }
+
+ /**
+ * Gets the html element for a component ref.
+ *
+ * @param {ComponentRef<any>} componentRef
+ * @returns {HTMLElement}
+ *
+ * @memberOf InjectionService
+ */
+ private getComponentRootNode(componentRef: ComponentRef<any>): HTMLElement {
+ return (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
+ }
+
+ /**
+ * Gets the root component container html element.
+ *
+ * @returns {HTMLElement}
+ *
+ * @memberOf InjectionService
+ */
+ private getRootViewContainerNode(): HTMLElement {
+ return this.getComponentRootNode(this.getRootViewContainer());
+ }
+
+ /**
+ * Projects the inputs onto the component
+ *
+ * @param {ComponentRef<any>} component
+ * @param {*} options
+ * @returns {ComponentRef<any>}
+ *
+ * @memberOf InjectionService
+ */
+ private projectComponentInputs(component: ComponentRef<any>, options: any): ComponentRef<any> {
+ if (options) {
+ const props = Object.getOwnPropertyNames(options);
+ for (const prop of props) {
+ component.instance[prop] = options[prop];
+ }
+ }
+
+ return component;
+ }
+
+ public createComponentDynamically<T>(componentClass: Type<T>, options: any = {}, location: Element = this.getRootViewContainerNode()): ComponentRef<any> {
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentClass);
+ const componentRef = componentFactory.create(this.injector);
+ const componentRootNode = this.getComponentRootNode(componentRef);
+
+ // project the options passed to the component instance
+ this.projectComponentInputs(componentRef, options);
+ this.applicationRef.attachView(componentRef.hostView);
+
+ componentRef.onDestroy(() => {
+ this.applicationRef.detachView(componentRef.hostView);
+ });
+
+ location.appendChild(componentRootNode);
+ return componentRef;
+ }
+
+ /**
+ * Inserts a component into an existing viewContainer
+ * @param componentType - type of component to create
+ * @param options - Inputs to project on new component
+ * @param vcRef - viewContainerRef in which to insert the newly created component
+ */
+ public insertComponentDynamically<T>(componentType: Type<T>, options: any = {}, vcRef: ViewContainerRef): ComponentRef<any> {
+ const factory = this.componentFactoryResolver.resolveComponentFactory(componentType);
+ const dynamicComponent = factory.create(vcRef.parentInjector);
+ this.projectComponentInputs(dynamicComponent, options);
+ vcRef.insert(dynamicComponent.hostView);
+ return dynamicComponent;
+ }
+
+}
diff --git a/vid-webpack-master/src/app/shared/components/customModal/services/modal.service.ts b/vid-webpack-master/src/app/shared/components/customModal/services/modal.service.ts
new file mode 100644
index 000000000..f46ee4896
--- /dev/null
+++ b/vid-webpack-master/src/app/shared/components/customModal/services/modal.service.ts
@@ -0,0 +1,64 @@
+import {ComponentRef, Injectable, Type} from "@angular/core";
+import {CreateDynamicComponentService} from "./create-dynamic-component.service";
+import {ModalType} from "../models/modal.type";
+import {ButtonType} from "../models/button.type";
+import {ModalButtonComponent} from "onap-ui-angular/dist/modals/modal-button.component";
+import {ModalSize} from "../models/modal.size";
+import {IModalConfig} from "../models/modal.model";
+import {ModalComponent} from "../modal.component";
+
+
+@Injectable()
+export class ModalService {
+
+ constructor(private createDynamicComponentService: CreateDynamicComponentService) {
+ }
+
+ private getBaseModal = (type: ModalType | ButtonType, title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ const modalConfig = {
+ size: ModalSize.small,
+ title: title,
+ message: message,
+ testId: testId,
+ buttons: buttons ? buttons : [{text: 'OK', type: type, closeModal: true}],
+ type: type
+ } as IModalConfig;
+ const modalInstance: ComponentRef<ModalComponent> = this.openModal(modalConfig);
+ return modalInstance.instance;
+ };
+
+ /* Shortcut method to open basic modals with title, message, and OK button that simply closes the modal. */
+ public openInfoModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+
+ return this.getBaseModal(ModalType.info, title, message, testId, buttons);
+ };
+
+ public openWarningModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ return this.getBaseModal(ModalType.warning, title, message, testId, buttons);
+ };
+
+ public openErrorModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ return this.getBaseModal(ModalType.error, title, message, testId, buttons);
+ };
+
+ public openSuccessModal = (title: string, message: string, testId: string, buttons?: ModalButtonComponent[]): ModalComponent => {
+ return this.getBaseModal(ModalType.success, title, message, testId, buttons);
+ };
+
+ public openCustomModal = (modalConfig: IModalConfig, dynamicComponentType: Type<any>, dynamicComponentInput?: any) => {
+ const modalInstance: ComponentRef<ModalComponent> = this.openModal(modalConfig);
+ this.createInnnerComponent(modalInstance, dynamicComponentType, dynamicComponentInput);
+ return modalInstance.instance;
+ };
+
+ public createInnnerComponent = (modalInstance: ComponentRef<ModalComponent>, dynamicComponentType: Type<any>, dynamicComponentInput?: any): void => {
+ modalInstance.instance.innerModalContent = this.createDynamicComponentService.insertComponentDynamically(dynamicComponentType, dynamicComponentInput, modalInstance.instance.dynamicContentContainer);
+ };
+
+ public openModal = (customModalData: IModalConfig): ComponentRef<ModalComponent> => {
+ let modalInstance: ComponentRef<ModalComponent> = this.createDynamicComponentService.createComponentDynamically(ModalComponent, customModalData);
+ modalInstance.instance.instanceRef = modalInstance;
+ return modalInstance;
+ }
+
+}