From 4ef3ee778fc944cdfe28146d4eed360ce096e5ee Mon Sep 17 00:00:00 2001 From: Yoav Schneiderman Date: Wed, 8 Jan 2020 14:46:14 +0200 Subject: Upgrade to Angular 8 Issue-ID: VID-742 Change-Id: Ic4b3aae71d4c946e23d854847a49aa7e020c465d Signed-off-by: Yoav Schneiderman --- .../modalButton/modal-button.component.html | 16 ++ .../modalButton/modal-button.component.scss | 273 +++++++++++++++++++++ .../modalButton/modal-button.component.ts | 28 +++ .../modal-close-button.component.ts | 36 +++ .../directives/ripple-click.animation.directive.ts | 47 ++++ .../components/customModal/modal.component.html | 46 ++++ .../components/customModal/modal.component.ts | 166 +++++++++++++ .../components/customModal/models/button.type.ts | 8 + .../customModal/models/modal-button.model.ts | 15 ++ .../components/customModal/models/modal.model.ts | 26 ++ .../customModal/models/modal.placement.ts | 6 + .../components/customModal/models/modal.size.ts | 7 + .../components/customModal/models/modal.type.ts | 10 + .../services/create-dynamic-component.service.ts | 107 ++++++++ .../customModal/services/modal.service.ts | 64 +++++ 15 files changed, 855 insertions(+) create mode 100644 vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.html create mode 100644 vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.scss create mode 100644 vid-webpack-master/src/app/shared/components/customModal/components/modalButton/modal-button.component.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/components/modalCloseButton/modal-close-button.component.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/directives/ripple-click.animation.directive.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/modal.component.html create mode 100644 vid-webpack-master/src/app/shared/components/customModal/modal.component.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/models/button.type.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/models/modal-button.model.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/models/modal.model.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/models/modal.placement.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/models/modal.size.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/models/modal.type.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/services/create-dynamic-component.service.ts create mode 100644 vid-webpack-master/src/app/shared/components/customModal/services/modal.service.ts (limited to 'vid-webpack-master/src/app/shared/components/customModal') 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 @@ +
+ + +
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 = new EventEmitter(); + @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: ` +
+ +
+ ` +}) +export class ModalCloseButtonComponent extends CustomButtonComponent { + + @Input() testId: string; + @Input() disabled: boolean; + @Input() modalInstanceRef: ComponentRef; + + 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 @@ +
+ +
+
+ +
+
+ +
+ {{ title }} + + +
+ +
+ +
+
+
+
+
+ + + +
+
+
+ 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; // the component ref is injected to the component in order to destroy the componet from itself + + @Output() onClose : EventEmitter = new EventEmitter(); + + @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; + + public calculatedTestId: string; + public modalCloseButton: ModalCloseButtonComponent; + public svgIconContentSafeHtml: SafeHtml; + + + private infoSvg = ` + + `; + private warningSvg = ``; + private errorSvg = ` + `; + private successSvg = ``; + 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} + * + * @memberOf InjectionService + */ + private getRootViewContainer(): ComponentRef { + 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} componentRef + * @returns {HTMLElement} + * + * @memberOf InjectionService + */ + private getComponentRootNode(componentRef: ComponentRef): HTMLElement { + return (componentRef.hostView as EmbeddedViewRef).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} component + * @param {*} options + * @returns {ComponentRef} + * + * @memberOf InjectionService + */ + private projectComponentInputs(component: ComponentRef, options: any): ComponentRef { + if (options) { + const props = Object.getOwnPropertyNames(options); + for (const prop of props) { + component.instance[prop] = options[prop]; + } + } + + return component; + } + + public createComponentDynamically(componentClass: Type, options: any = {}, location: Element = this.getRootViewContainerNode()): ComponentRef { + 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(componentType: Type, options: any = {}, vcRef: ViewContainerRef): ComponentRef { + 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 = 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, dynamicComponentInput?: any) => { + const modalInstance: ComponentRef = this.openModal(modalConfig); + this.createInnnerComponent(modalInstance, dynamicComponentType, dynamicComponentInput); + return modalInstance.instance; + }; + + public createInnnerComponent = (modalInstance: ComponentRef, dynamicComponentType: Type, dynamicComponentInput?: any): void => { + modalInstance.instance.innerModalContent = this.createDynamicComponentService.insertComponentDynamically(dynamicComponentType, dynamicComponentInput, modalInstance.instance.dynamicContentContainer); + }; + + public openModal = (customModalData: IModalConfig): ComponentRef => { + let modalInstance: ComponentRef = this.createDynamicComponentService.createComponentDynamically(ModalComponent, customModalData); + modalInstance.instance.instanceRef = modalInstance; + return modalInstance; + } + +} -- cgit 1.2.3-korg