diff options
Diffstat (limited to 'deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal')
11 files changed, 0 insertions, 1234 deletions
diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-backdrop.spec.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-backdrop.spec.ts deleted file mode 100644 index 887b66e4..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-backdrop.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {TestBed} from '@angular/core/testing'; -import {PlxModalBackdrop} from './modal-backdrop'; - -describe('plx-modal-backdrop', () => { - - beforeEach(() => { - TestBed.configureTestingModule({declarations: [PlxModalBackdrop]}); - }); - - it('should render backdrop with required CSS classes', () => { - const fixture = TestBed.createComponent(PlxModalBackdrop); - - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveCssClass('modal-backdrop'); - }); -}); diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-backdrop.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-backdrop.ts deleted file mode 100644 index 07e2ff84..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-backdrop.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {Component} from '@angular/core'; - -@Component({ - selector: 'plx-modal-backdrop', - template: '', - host: {'class': 'modal-backdrop fade show'} -}) -export class PlxModalBackdrop { -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-dismiss-reasons.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-dismiss-reasons.ts deleted file mode 100644 index 08395852..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-dismiss-reasons.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum ModalDismissReasons { - BACKDROP_CLICK, - ESC -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-ref.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-ref.ts deleted file mode 100644 index 061dc70e..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-ref.ts +++ /dev/null @@ -1,109 +0,0 @@ -import {Injectable, ComponentRef} from '@angular/core'; -import {PlxModalBackdrop} from './modal-backdrop'; -import {PlxModalWindow} from './modal-window'; -import {ContentRef} from '../util/popup'; - -/** - * A reference to an active (currently opened) modal. Instances of this class - * can be injected into components passed as modal content. - */ -@Injectable() -export class PlxActiveModal { - /** - * Can be used to close a modal, passing an optional result. - */ - public close(result?: any): void { - // TO DO - } - - /** - * Can be used to dismiss a modal, passing an optional reason. - */ - public dismiss(reason?: any): void { - // TO DO - } -} - -/** - * A reference to a newly opened modal. - */ -@Injectable() -export class PlxModalRef { - private _resolve: (result?: any) => void; - private _reject: (reason?: any) => void; - - /** - * The instance of component used as modal's content. - * Undefined when a TemplateRef is used as modal's content. - */ - get componentInstance(): any { - if (this._contentRef.componentRef) { - return this._contentRef.componentRef.instance; - } - } - - // only needed to keep TS1.8 compatibility - set componentInstance(instance: any) { - // TO DO - } - - /** - * A promise that is resolved when a modal is closed and rejected when a modal is dismissed. - */ - public result: Promise<any>; - - constructor(private _windowCmptRef: ComponentRef<PlxModalWindow>, private _contentRef: ContentRef, - private _backdropCmptRef?: ComponentRef<PlxModalBackdrop>) { - _windowCmptRef.instance.dismissEvent.subscribe((reason: any) => { - this.dismiss(reason); - }); - - this.result = new Promise((resolve, reject) => { - this._resolve = resolve; - this._reject = reject; - }); - this.result.then(null, () => { - // TO DO - }); - } - - /** - * Can be used to close a modal, passing an optional result. - */ - public close(result?: any): void { - if (this._windowCmptRef) { - this._resolve(result); - this._removeModalElements(); - } - } - - /** - * Can be used to dismiss a modal, passing an optional reason. - */ - public dismiss(reason?: any): void { - if (this._windowCmptRef) { - this._reject(reason); - this._removeModalElements(); - } - } - - private _removeModalElements() { - const windowNativeEl = this._windowCmptRef.location.nativeElement; - windowNativeEl.parentNode.removeChild(windowNativeEl); - this._windowCmptRef.destroy(); - - if (this._backdropCmptRef) { - const backdropNativeEl = this._backdropCmptRef.location.nativeElement; - backdropNativeEl.parentNode.removeChild(backdropNativeEl); - this._backdropCmptRef.destroy(); - } - - if (this._contentRef && this._contentRef.viewRef) { - this._contentRef.viewRef.destroy(); - } - - this._windowCmptRef = null; - this._backdropCmptRef = null; - this._contentRef = null; - } -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-stack.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-stack.ts deleted file mode 100644 index 37f5b171..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-stack.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { - ApplicationRef, - Injectable, - Injector, - ReflectiveInjector, - ComponentFactory, - ComponentFactoryResolver, - ComponentRef, - TemplateRef -} from '@angular/core'; - -import {ContentRef} from '../util/popup'; -import {isDefined, isString} from '../util/util'; - -import {PlxModalBackdrop} from './modal-backdrop'; -import {PlxModalWindow} from './modal-window'; -import {PlxActiveModal, PlxModalRef} from './modal-ref'; - -@Injectable() -export class PlxModalStack { - private _backdropFactory: ComponentFactory<PlxModalBackdrop>; - private _windowFactory: ComponentFactory<PlxModalWindow>; - - constructor(private _applicationRef: ApplicationRef, private _injector: Injector, - private _componentFactoryResolver: ComponentFactoryResolver) { - this._backdropFactory = _componentFactoryResolver.resolveComponentFactory(PlxModalBackdrop); - this._windowFactory = _componentFactoryResolver.resolveComponentFactory(PlxModalWindow); - } - - public open(moduleCFR: ComponentFactoryResolver, contentInjector: Injector, content: any, options): PlxModalRef { - const containerSelector = options.container || 'body'; - const containerEl = document.querySelector(containerSelector);// 默认获取到body的DOM - - if (!containerEl) { - throw new Error(`The specified modal container "${containerSelector}" was not found in the DOM.`); - } - - const activeModal = new PlxActiveModal(); - const contentRef = this._getContentRef(moduleCFR, contentInjector, content, activeModal); - - let windowCmptRef: ComponentRef<PlxModalWindow>; - let backdropCmptRef: ComponentRef<PlxModalBackdrop>; - let ngbModalRef: PlxModalRef; - - - if (options.backdrop !== false) { - backdropCmptRef = this._backdropFactory.create(this._injector); - this._applicationRef.attachView(backdropCmptRef.hostView); - containerEl.appendChild(backdropCmptRef.location.nativeElement); - } - windowCmptRef = this._windowFactory.create(this._injector, contentRef.nodes); - - /** - * Attaches a view so that it will be dirty checked. - * The view will be automatically detached when it is destroyed. - * This will throw if the view is already attached to a ViewContainer. - */ - this._applicationRef.attachView(windowCmptRef.hostView); - - containerEl.appendChild(windowCmptRef.location.nativeElement); - - ngbModalRef = new PlxModalRef(windowCmptRef, contentRef, backdropCmptRef); - - activeModal.close = (result: any) => { - ngbModalRef.close(result); - }; - activeModal.dismiss = (reason: any) => { - ngbModalRef.dismiss(reason); - }; - - this._applyWindowOptions(windowCmptRef.instance, options); - - return ngbModalRef; - } - - private _applyWindowOptions(windowInstance: PlxModalWindow, options: Object): void { - ['backdrop', 'keyboard', 'size', 'windowClass'].forEach((optionName: string) => { - if (isDefined(options[optionName])) { - windowInstance[optionName] = options[optionName]; - } - }); - } - - private _getContentRef(moduleCFR: ComponentFactoryResolver, contentInjector: Injector, content: any, - context: PlxActiveModal): ContentRef { - if (!content) { - return new ContentRef([]); - } else if (content instanceof TemplateRef) { - const viewRef = content.createEmbeddedView(context); - this._applicationRef.attachView(viewRef); - return new ContentRef([viewRef.rootNodes], viewRef); - } else if (isString(content)) { - return new ContentRef([[document.createTextNode(`${content}`)]]); - } else { - const contentCmptFactory = moduleCFR.resolveComponentFactory(content); - const modalContentInjector = - ReflectiveInjector.resolveAndCreate([{provide: PlxActiveModal, useValue: context}], contentInjector); - const componentRef = contentCmptFactory.create(modalContentInjector); - this._applicationRef.attachView(componentRef.hostView); - return new ContentRef([[componentRef.location.nativeElement]], componentRef.hostView, componentRef); - } - } -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-window.spec.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-window.spec.ts deleted file mode 100644 index 5767bfee..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-window.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import {TestBed, ComponentFixture} from '@angular/core/testing'; - -import {PlxModalWindow} from './modal-window'; -import {ModalDismissReasons} from './modal-dismiss-reasons'; - -describe('plx-modal-dialog', () => { - - let fixture: ComponentFixture<PlxModalWindow>; - - beforeEach(() => { - TestBed.configureTestingModule({declarations: [PlxModalWindow]}); - fixture = TestBed.createComponent(PlxModalWindow); - }); - - describe('basic rendering functionality', () => { - - it('should render default modal window', () => { - fixture.detectChanges(); - - const modalEl: Element = fixture.nativeElement; - const dialogEl: Element = fixture.nativeElement.querySelector('.modal-dialog'); - - expect(modalEl).toHaveCssClass('modal'); - expect(dialogEl).toHaveCssClass('modal-dialog'); - }); - - it('should render default modal window with a specified size', () => { - fixture.componentInstance.size = 'sm'; - fixture.detectChanges(); - - const dialogEl: Element = fixture.nativeElement.querySelector('.modal-dialog'); - expect(dialogEl).toHaveCssClass('modal-dialog'); - expect(dialogEl).toHaveCssClass('modal-sm'); - }); - - it('should render default modal window with a specified class', () => { - fixture.componentInstance.windowClass = 'custom-class'; - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveCssClass('custom-class'); - }); - - it('aria attributes', () => { - fixture.detectChanges(); - const dialogEl: Element = fixture.nativeElement.querySelector('.modal-dialog'); - - expect(fixture.nativeElement.getAttribute('role')).toBe('dialog'); - expect(dialogEl.getAttribute('role')).toBe('document'); - }); - }); - - describe('dismiss', () => { - - it('should dismiss on backdrop click by default', (done) => { - fixture.detectChanges(); - - fixture.componentInstance.dismissEvent.subscribe(($event) => { - expect($event).toBe(ModalDismissReasons.BACKDROP_CLICK); - done(); - }); - - fixture.nativeElement.click(); - }); - - it('should not dismiss on modal content click when there is active backdrop', (done) => { - fixture.detectChanges(); - fixture.componentInstance.dismissEvent.subscribe( - () => { - done.fail(new Error('Should not trigger dismiss event')); - }); - - fixture.nativeElement.querySelector('.modal-content').click(); - setTimeout(done, 200); - }); - - it('should ignore backdrop clicks when there is no backdrop', (done) => { - fixture.componentInstance.backdrop = false; - fixture.detectChanges(); - - fixture.componentInstance.dismissEvent.subscribe(($event) => { - expect($event).toBe(ModalDismissReasons.BACKDROP_CLICK); - done.fail(new Error('Should not trigger dismiss event')); - }); - - fixture.nativeElement.querySelector('.modal-dialog').click(); - setTimeout(done, 200); - }); - - it('should ignore backdrop clicks when backdrop is "static"', (done) => { - fixture.componentInstance.backdrop = 'static'; - fixture.detectChanges(); - - fixture.componentInstance.dismissEvent.subscribe(($event) => { - expect($event).toBe(ModalDismissReasons.BACKDROP_CLICK); - done.fail(new Error('Should not trigger dismiss event')); - }); - - fixture.nativeElement.querySelector('.modal-dialog').click(); - setTimeout(done, 200); - }); - - it('should dismiss on esc press by default', (done) => { - fixture.detectChanges(); - - fixture.componentInstance.dismissEvent.subscribe(($event) => { - expect($event).toBe(ModalDismissReasons.ESC); - done(); - }); - - fixture.debugElement.triggerEventHandler('keyup.esc', {}); - }); - }); - -}); diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-window.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-window.ts deleted file mode 100644 index eda5b39f..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal-window.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - Component, - Output, - EventEmitter, - Input, - ElementRef, - Renderer, - OnInit, - AfterViewInit, - OnDestroy, ViewEncapsulation -} from '@angular/core'; - -import {ModalDismissReasons} from './modal-dismiss-reasons'; - -@Component({ - selector: 'plx-modal-window', - host: { - '[class]': '"modal plx-modal fade show" + (windowClass ? " " + windowClass : "")', - 'role': 'dialog', - 'tabindex': '-1', - 'style': 'display: block;', - '(keyup.esc)': 'escKey($event)', - '(click)': 'backdropClick($event)' - }, - template: ` - <div [class]="'modal-dialog' + (size ? ' modal-' + size : '')" role="document"> - <div class="modal-content"><ng-content></ng-content></div> - </div> - `, - styleUrls: ['modal.less'], - encapsulation: ViewEncapsulation.None -}) -export class PlxModalWindow implements OnInit, AfterViewInit, OnDestroy { - private _elWithFocus: Element; // element that is focused prior to modal opening - - @Input() public backdrop: boolean | string = true; - @Input() public keyboard = true; - @Input() public size: string; - @Input() public windowClass: string; - - @Output('dismiss') public dismissEvent = new EventEmitter(); - - constructor(private _elRef: ElementRef, private _renderer: Renderer) { - } - - public backdropClick($event): void { - if (this.backdrop === true && this._elRef.nativeElement === $event.target) { - this.dismiss(ModalDismissReasons.BACKDROP_CLICK); - } - } - - public escKey($event): void { - if (this.keyboard && !$event.defaultPrevented) { - this.dismiss(ModalDismissReasons.ESC); - } - } - - public dismiss(reason): void { - this.dismissEvent.emit(reason); - } - - public ngOnInit() { - this._elWithFocus = document.activeElement; - this._renderer.setElementClass(document.body, 'modal-open', true); - } - - public ngAfterViewInit() { - if (!this._elRef.nativeElement.contains(document.activeElement)) { - this._renderer.invokeElementMethod(this._elRef.nativeElement, 'focus', []); - } - } - - public ngOnDestroy() { - if (this._elWithFocus && document.body.contains(this._elWithFocus)) { - this._renderer.invokeElementMethod(this._elWithFocus, 'focus', []); - } else { - this._renderer.invokeElementMethod(document.body, 'focus', []); - } - this._elWithFocus = null; - this._renderer.setElementClass(document.body, 'modal-open', false); - } -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.less b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.less deleted file mode 100644 index 5868749c..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.less +++ /dev/null @@ -1,125 +0,0 @@ -@import "../../assets/components/themes/default/theme.less"; - -plx-modal-window { - .modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - display: none; - outline: 0; - z-index: 10000; - } - .modal-dialog { - position: relative; - max-width: 600px; - margin: 30px auto; - &.modal-sm { - max-width: 600px; - } - &.modal-lg { - max-width: 1000px; - } - } - .modal-content { - position: relative; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -ms-flex-direction: column; - flex-direction: column; - background-color: @component-bg; - background-clip: padding-box; - border-radius: @radius; - box-shadow: 0 5px 15px @shadow-color; - outline: 0; - .modal-header { - border-bottom: 0; - display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: justify; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 15px; - } - .modal-body { - .form-group:last-child, form:last-child { - margin-bottom: 0; - } - } - .modal-footer { - display: block; - border-top: 0; - margin-top: 0; - padding: 0 15px 15px 15px; - } - .modal-title { - font-size: @font-size-title-level1; - margin-bottom: 0; - line-height: 1.5; - } - .modal-btn { - text-align: center; - font-size: 0; - } - } - .close { - color: @fonticon-color; - font-size: @font-size-title-level2; - text-shadow: none; - width: 24px; - height: 24px; - background: @scene-textcolor; - border-radius: 20px; - padding-bottom: 2px; - outline: none; - &:hover { - color: @fonticon-color; - background: @fonticon-bg-color-hover; - } - } - .alert-modal { - &.row { - margin-left: 100px; - margin-bottom: 30px; - text-align: left; - .tip-img { - display: inline-block; - width: 52px; - height: 52px; - border-radius: 50px; - font-size: 45px; - text-align: center; - line-height: 1; - margin-top: -5px; - margin-right: 15px; - &::before { - content: "!"; - } - } - .tip-info { - width: 300px; - .alert-title { - font-size: @font-size-title-level2; - color: @title-text-color; - } - .alert-result { - margin-top: 5px; - font-size: @font-size; - color: @unselected-text-color; - } - } - .warning { - border: 3px solid @warning-color; - color: @warning-color; - } - .error { - border: 3px solid @error-color; - color: @error-color; - } - } - } -}
\ No newline at end of file diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.module.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.module.ts deleted file mode 100644 index 67fdb478..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {NgModule, ModuleWithProviders} from '@angular/core'; - -import {PlxModalBackdrop} from './modal-backdrop'; -import {PlxModalWindow} from './modal-window'; -import {PlxModalStack} from './modal-stack'; -import {PlxModal} from './modal'; - -export {PlxModal, PlxModalOptions} from './modal'; -export {PlxModalRef, PlxActiveModal} from './modal-ref'; -export {ModalDismissReasons} from './modal-dismiss-reasons'; - -@NgModule({ - declarations: [PlxModalBackdrop, PlxModalWindow], - entryComponents: [PlxModalBackdrop, PlxModalWindow], - providers: [PlxModal] -}) -export class PlxModalModule { - public static forRoot(): ModuleWithProviders { - return {ngModule: PlxModalModule, providers: [PlxModal, PlxModalStack]}; - } -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.spec.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.spec.ts deleted file mode 100644 index a99c86b1..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.spec.ts +++ /dev/null @@ -1,597 +0,0 @@ -import {Component, Injectable, ViewChild, OnDestroy, NgModule, getDebugNode, DebugElement} from '@angular/core'; -import {CommonModule} from '@angular/common'; -import {TestBed, ComponentFixture} from '@angular/core/testing'; - -import {PlxModalModule, PlxModal, PlxActiveModal, PlxModalRef} from './modal.module'; - -const NOOP = () => { -}; - -@Injectable() -class SpyService { - called = false; -} - -describe('plx-modal', () => { - - let fixture: ComponentFixture<TestComponent>; - - beforeEach(() => { - jasmine.addMatchers({ - toHaveModal: function (util, customEqualityTests) { - return { - compare: function (actual, content?, selector?) { - const allModalsContent = document.querySelector(selector || 'body').querySelectorAll('.modal-content'); - let pass = true; - let errMsg; - - if (!content) { - pass = allModalsContent.length > 0; - errMsg = 'at least one modal open but found none'; - } else if (Array.isArray(content)) { - pass = allModalsContent.length === content.length; - errMsg = `${content.length} modals open but found ${allModalsContent.length}`; - } else { - pass = allModalsContent.length === 1 && allModalsContent[0].textContent.trim() === content; - errMsg = `exactly one modal open but found ${allModalsContent.length}`; - } - - return {pass: pass, message: `Expected ${actual.outerHTML} to have ${errMsg}`}; - }, - negativeCompare: function (actual) { - const allOpenModals = actual.querySelectorAll('plx-modal-window'); - - return { - pass: allOpenModals.length === 0, - message: `Expected ${actual.outerHTML} not to have any modals open but found ${allOpenModals.length}` - }; - } - }; - } - }); - - jasmine.addMatchers({ - toHaveBackdrop: function (util, customEqualityTests) { - return { - compare: function (actual) { - return { - pass: document.querySelectorAll('plx-modal-backdrop').length === 1, - message: `Expected ${actual.outerHTML} to have exactly one backdrop element` - }; - }, - negativeCompare: function (actual) { - const allOpenModals = document.querySelectorAll('plx-modal-backdrop'); - - return { - pass: allOpenModals.length === 0, - message: `Expected ${actual.outerHTML} not to have any backdrop elements` - }; - } - }; - } - }); - }); - - beforeEach(() => { - TestBed.configureTestingModule({imports: [OesModalTestModule]}); - fixture = TestBed.createComponent(TestComponent); - }); - - afterEach(() => { - // detect left-over modals and close them or report errors when can't - - const remainingModalWindows = document.querySelectorAll('plx-modal-window'); - if (remainingModalWindows.length) { - fail(`${remainingModalWindows.length} modal windows were left in the DOM.`); - } - - const remainingModalBackdrops = document.querySelectorAll('plx-modal-backdrop'); - if (remainingModalBackdrops.length) { - fail(`${remainingModalBackdrops.length} modal backdrops were left in the DOM.`); - } - }); - - describe('basic functionality', () => { - - it('should open and close modal with default options', () => { - const modalInstance = fixture.componentInstance.open('foo'); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - modalInstance.close('some result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should open and close modal from a TemplateRef content', () => { - const modalInstance = fixture.componentInstance.openTpl(); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('Hello, World!'); - - modalInstance.close('some result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should properly destroy TemplateRef content', () => { - const spyService = fixture.debugElement.injector.get(SpyService); - const modalInstance = fixture.componentInstance.openDestroyableTpl(); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('Some content'); - expect(spyService.called).toBeFalsy(); - - modalInstance.close('some result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - expect(spyService.called).toBeTruthy(); - }); - - it('should open and close modal from a component type', () => { - const spyService = fixture.debugElement.injector.get(SpyService); - const modalInstance = fixture.componentInstance.openCmpt(DestroyableCmpt); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('Some content'); - expect(spyService.called).toBeFalsy(); - - modalInstance.close('some result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - expect(spyService.called).toBeTruthy(); - }); - - it('should inject active modal ref when component is used as content', () => { - fixture.componentInstance.openCmpt(WithActiveModalCmpt); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('Close'); - - (<HTMLElement>document.querySelector('button.closeFromInside')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should expose component used as modal content', () => { - const modalInstance = fixture.componentInstance.openCmpt(WithActiveModalCmpt); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('Close'); - expect(modalInstance.componentInstance instanceof WithActiveModalCmpt).toBeTruthy(); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should open and close modal from inside', () => { - fixture.componentInstance.openTplClose(); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - (<HTMLElement>document.querySelector('button#close')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should open and dismiss modal from inside', () => { - fixture.componentInstance.openTplDismiss().result.catch(NOOP); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - (<HTMLElement>document.querySelector('button#dismiss')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should resolve result promise on close', () => { - let resolvedResult; - fixture.componentInstance.openTplClose().result.then((result) => resolvedResult = result); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - (<HTMLElement>document.querySelector('button#close')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - - fixture.whenStable().then(() => { - expect(resolvedResult).toBe('myResult'); - }); - }); - - it('should reject result promise on dismiss', () => { - let rejectReason; - fixture.componentInstance.openTplDismiss().result.catch((reason) => rejectReason = reason); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - (<HTMLElement>document.querySelector('button#dismiss')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - - fixture.whenStable().then(() => { - expect(rejectReason).toBe('myReason'); - }); - }); - - it('should add / remove "modal-open" class to body when modal is open', () => { - const modalRef = fixture.componentInstance.open('bar'); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - expect(document.body).toHaveCssClass('modal-open'); - - modalRef.close('bar result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - expect(document.body).not.toHaveCssClass('modal-open'); - }); - - it('should not throw when close called multiple times', () => { - const modalInstance = fixture.componentInstance.open('foo'); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - modalInstance.close('some result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - - modalInstance.close('some result'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should not throw when dismiss called multiple times', () => { - const modalRef = fixture.componentInstance.open('foo'); - modalRef.result.catch(NOOP); - - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - modalRef.dismiss('some reason'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - - modalRef.dismiss('some reason'); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - }); - - describe('backdrop options', () => { - - it('should have backdrop by default', () => { - const modalInstance = fixture.componentInstance.open('foo'); - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveModal('foo'); - expect(fixture.nativeElement).toHaveBackdrop(); - - modalInstance.close('some reason'); - fixture.detectChanges(); - - expect(fixture.nativeElement).not.toHaveModal(); - expect(fixture.nativeElement).not.toHaveBackdrop(); - }); - - it('should open and close modal without backdrop', () => { - const modalInstance = fixture.componentInstance.open('foo', {backdrop: false}); - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveModal('foo'); - expect(fixture.nativeElement).not.toHaveBackdrop(); - - modalInstance.close('some reason'); - fixture.detectChanges(); - - expect(fixture.nativeElement).not.toHaveModal(); - expect(fixture.nativeElement).not.toHaveBackdrop(); - }); - - it('should open and close modal without backdrop from template content', () => { - const modalInstance = fixture.componentInstance.openTpl({backdrop: false}); - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveModal('Hello, World!'); - expect(fixture.nativeElement).not.toHaveBackdrop(); - - modalInstance.close('some reason'); - fixture.detectChanges(); - - expect(fixture.nativeElement).not.toHaveModal(); - expect(fixture.nativeElement).not.toHaveBackdrop(); - }); - - it('should dismiss on backdrop click', () => { - fixture.componentInstance.open('foo').result.catch(NOOP); - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveModal('foo'); - expect(fixture.nativeElement).toHaveBackdrop(); - - (<HTMLElement>document.querySelector('plx-modal-window')).click(); - fixture.detectChanges(); - - expect(fixture.nativeElement).not.toHaveModal(); - expect(fixture.nativeElement).not.toHaveBackdrop(); - }); - - it('should not dismiss on "static" backdrop click', () => { - const modalInstance = fixture.componentInstance.open('foo', {backdrop: 'static'}); - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveModal('foo'); - expect(fixture.nativeElement).toHaveBackdrop(); - - (<HTMLElement>document.querySelector('plx-modal-window')).click(); - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveModal(); - expect(fixture.nativeElement).toHaveBackdrop(); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should not dismiss on clicks outside content where there is no backdrop', () => { - const modalInstance = fixture.componentInstance.open('foo', {backdrop: false}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - (<HTMLElement>document.querySelector('plx-modal-window')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should not dismiss on clicks that result in detached elements', () => { - const modalInstance = fixture.componentInstance.openTplIf({}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - (<HTMLElement>document.querySelector('button#if')).click(); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - }); - - describe('container options', () => { - - it('should attach window and backdrop elements to the specified container', () => { - const modalInstance = fixture.componentInstance.open('foo', {container: '#testContainer'}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo', '#testContainer'); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should throw when the specified container element doesnt exist', () => { - const brokenSelector = '#notInTheDOM'; - expect(() => { - fixture.componentInstance.open('foo', {container: brokenSelector}); - }).toThrowError(`The specified modal container "${brokenSelector}" was not found in the DOM.`); - }); - }); - - describe('keyboard options', () => { - - it('should dismiss modals on ESC by default', () => { - fixture.componentInstance.open('foo').result.catch(NOOP); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - (<DebugElement>getDebugNode(document.querySelector('plx-modal-window'))).triggerEventHandler('keyup.esc', {}); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should not dismiss modals on ESC when keyboard option is false', () => { - const modalInstance = fixture.componentInstance.open('foo', {keyboard: false}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - (<DebugElement>getDebugNode(document.querySelector('plx-modal-window'))).triggerEventHandler('keyup.esc', {}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - it('should not dismiss modals on ESC when default is prevented', () => { - const modalInstance = fixture.componentInstance.open('foo', {keyboard: true}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - - (<DebugElement>getDebugNode(document.querySelector('plx-modal-window'))).triggerEventHandler('keyup.esc', { - defaultPrevented: true - }); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal(); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - }); - - describe('size options', () => { - - it('should render modals with specified size', () => { - const modalInstance = fixture.componentInstance.open('foo', {size: 'sm'}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - expect(document.querySelector('.modal-dialog')).toHaveCssClass('modal-sm'); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - }); - - describe('custom class options', () => { - - it('should render modals with the correct custom classes', () => { - const modalInstance = fixture.componentInstance.open('foo', {windowClass: 'bar'}); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - expect(document.querySelector('plx-modal-window')).toHaveCssClass('bar'); - - modalInstance.close(); - fixture.detectChanges(); - expect(fixture.nativeElement).not.toHaveModal(); - }); - - }); - - describe('focus management', () => { - - it('should focus modal window and return focus to previously focused element', () => { - fixture.detectChanges(); - const openButtonEl = fixture.nativeElement.querySelector('button#open'); - - openButtonEl.focus(); - openButtonEl.click(); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('from button'); - expect(document.activeElement).toBe(document.querySelector('plx-modal-window')); - - fixture.componentInstance.close(); - expect(fixture.nativeElement).not.toHaveModal(); - expect(document.activeElement).toBe(openButtonEl); - }); - - - it('should return focus to body if no element focused prior to modal opening', () => { - const modalInstance = fixture.componentInstance.open('foo'); - fixture.detectChanges(); - expect(fixture.nativeElement).toHaveModal('foo'); - expect(document.activeElement).toBe(document.querySelector('plx-modal-window')); - - modalInstance.close('ok!'); - expect(document.activeElement).toBe(document.body); - }); - }); - - describe('window element ordering', () => { - it('should place newer windows on top of older ones', () => { - const modalInstance1 = fixture.componentInstance.open('foo', {windowClass: 'window-1'}); - fixture.detectChanges(); - - const modalInstance2 = fixture.componentInstance.open('bar', {windowClass: 'window-2'}); - fixture.detectChanges(); - - let windows = document.querySelectorAll('plx-modal-window'); - expect(windows.length).toBe(2); - expect(windows[0]).toHaveCssClass('window-1'); - expect(windows[1]).toHaveCssClass('window-2'); - - modalInstance2.close(); - modalInstance1.close(); - fixture.detectChanges(); - }); - }); -}); - -@Component({selector: 'destroyable-cmpt', template: 'Some content'}) -export class DestroyableCmpt implements OnDestroy { - constructor(private _spyService: SpyService) { - } - - ngOnDestroy(): void { - this._spyService.called = true; - } -} - -@Component( - {selector: 'modal-content-cmpt', template: '<button class="closeFromInside" (click)="close()">Close</button>'}) -export class WithActiveModalCmpt { - constructor(public activeModal: PlxActiveModal) { - } - - close() { - this.activeModal.close('from inside'); - } -} - -@Component({ - selector: 'test-cmpt', - template: ` - <div id="testContainer"></div> - <template #content>Hello, {{name}}!</template> - <template #destroyableContent><destroyable-cmpt></destroyable-cmpt></template> - <template #contentWithClose let-close="close"><button id="close" (click)="close('myResult')">Close me</button></template> - <template #contentWithDismiss let-dismiss="dismiss"><button id="dismiss" (click)="dismiss('myReason')">Dismiss me</button></template> - <template #contentWithIf> - <template [ngIf]="show"> - <button id="if" (click)="show = false">Click me</button> - </template> - </template> - <button id="open" (click)="open('from button')">Open</button> - ` -}) -class TestComponent { - name = 'World'; - openedModal: PlxModalRef; - show = true; - @ViewChild('content') tplContent; - @ViewChild('destroyableContent') tplDestroyableContent; - @ViewChild('contentWithClose') tplContentWithClose; - @ViewChild('contentWithDismiss') tplContentWithDismiss; - @ViewChild('contentWithIf') tplContentWithIf; - - constructor(private modalService: PlxModal) { - } - - open(content: string, options?: Object) { - this.openedModal = this.modalService.open(content, options); - return this.openedModal; - } - - close() { - if (this.openedModal) { - this.openedModal.close('ok'); - } - } - - openTpl(options?: Object) { - return this.modalService.open(this.tplContent, options); - } - - openCmpt(cmptType: any, options?: Object) { - return this.modalService.open(cmptType, options); - } - - openDestroyableTpl(options?: Object) { - return this.modalService.open(this.tplDestroyableContent, options); - } - - openTplClose(options?: Object) { - return this.modalService.open(this.tplContentWithClose, options); - } - - openTplDismiss(options?: Object) { - return this.modalService.open(this.tplContentWithDismiss, options); - } - - openTplIf(options?: Object) { - return this.modalService.open(this.tplContentWithIf, options); - } -} - -@NgModule({ - declarations: [TestComponent, DestroyableCmpt, WithActiveModalCmpt], - exports: [TestComponent, DestroyableCmpt], - imports: [CommonModule, PlxModalModule.forRoot()], - entryComponents: [DestroyableCmpt, WithActiveModalCmpt], - providers: [SpyService] -}) -class OesModalTestModule { -} diff --git a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.ts b/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.ts deleted file mode 100644 index 5935eee6..00000000 --- a/deprecated-workflow-designer/sdc-workflow-designer-ui/src/app/paletx/plx-modal/modal.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {Injectable, Injector, ComponentFactoryResolver} from '@angular/core'; -import {PlxModalStack} from './modal-stack'; -import {PlxModalRef} from './modal-ref'; - -/** - * Represent options available when opening new modal windows. - */ -export interface PlxModalOptions { - /** - * Whether a backdrop element should be created for a given modal (true by default). - * Alternatively, specify 'static' for a backdrop which doesn't close the modal on click. - */ - backdrop?: boolean | 'static'; - - /** - * An element to which to attach newly opened modal windows. - */ - container?: string; - - /** - * Whether to close the modal when escape key is pressed (true by default). - */ - keyboard?: boolean; - - /** - * Size of a new modal window. - */ - size?: 'sm' | 'lg'; - - /** - * Custom class to append to the modal window - */ - windowClass?: string; -} - -/** - * A service to open modal windows. Creating a modal is straightforward: create a template and pass it as an argument to - * the "open" method! - */ -@Injectable() -export class PlxModal { - constructor(private _moduleCFR: ComponentFactoryResolver, private _injector: Injector, private _modalStack: PlxModalStack) { - } - - /** - * Opens a new modal window with the specified content and using supplied options. Content can be provided - * as a TemplateRef or a component type. If you pass a component type as content than instances of those - * components can be injected with an instance of the PlxActiveModal class. You can use methods on the - * PlxActiveModal class to close / dismiss modals from "inside" of a component. - */ - public open(content: any, options: PlxModalOptions = {}): PlxModalRef { - return this._modalStack.open(this._moduleCFR, this._injector, content, options); - } -} |