import { Observable, BehaviorSubject } from "rxjs"; export class ModalService { private static instance: ModalService; private _modalToShow$: BehaviorSubject = new BehaviorSubject([]); private modalData: unknown = null; private constructor() {} public static getInstance() { if (!this.instance) { this.instance = new ModalService(); } return this.instance; } public getModalData(): Type { return this.modalData as Type; } public async openModal(modal: ModalComponent, options?: ModalOptions): Promise> { let resolver: (value: ModalResponse | PromiseLike) => void; const promise = new Promise>(resolve => { resolver = resolve as (value: ModalResponse | PromiseLike) => void; }); const modalObj = {modal: modal as ModalComponent, resolver, options}; this._modalToShow$.next([...this._modalToShow$.getValue(), modalObj]); promise.then(() => { this._modalToShow$.next(this._modalToShow$.getValue().filter(m => m !== modalObj)); }); return promise; } public getModalToShow(): Observable { return this._modalToShow$.asObservable(); } } export type ModalOptions = { readonly data?: T, readonly noStyle?: boolean, readonly closable?: boolean } export type ModalComponent = ({ resolver, options }: { readonly resolver: (x: ModalResponse) => void; readonly options?: ModalOptions }) => JSX.Element; export type ModalObject = {modal: ModalComponent, resolver: (value: ModalResponse | PromiseLike) => void, options: ModalOptions}; export const enum ModalExitCode { NO_CHOICE = -1, COMPLETED = 0, CLOSED = 1, CANCELED = 2, } export interface ModalResponse { exitCode: ModalExitCode; data?: T; }