Files
bs-manager/src/renderer/services/modale.service.ts
T
2024-09-04 08:21:26 +08:00

57 lines
2.0 KiB
TypeScript

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