123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import { Spin, Skeleton, Modal as AntModal } from 'antd';
- import React, { FC, ReactNode, useState } from 'react';
- import { ErrorBoundary } from 'react-error-boundary';
- import { ComponentError } from '../ComponentError/ComponentError';
- import styles from './Modal.module.scss';
- export type ModalProps = {
- title: string;
- url?: string;
- open: boolean;
- handleOk?: () => void;
- handleCancel?: () => void;
- afterClose?: () => void;
- children?: ReactNode;
- height?: string;
- width?: string;
- };
- export const Modal: FC<ModalProps> = ({
- title,
- url,
- open,
- handleOk,
- handleCancel,
- afterClose,
- height,
- width,
- children,
- }) => {
- const [loading, setLoading] = useState(!!url);
- let defaultHeight = '100%';
- let defaultWidth = '520px';
- if (url) {
- defaultHeight = '70vh';
- defaultWidth = '900px';
- }
- const modalContentBodyStyle = {
- padding: '0px',
- minHeight: height,
- height: height ?? defaultHeight,
- };
- const iframe = url && (
- <iframe
- title={title}
- src={url}
- width="100%"
- height="100%"
- sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
- frameBorder="0"
- allowFullScreen
- style={{ display: 'block' }}
- // eslint-disable-next-line react/no-unknown-property
- onLoad={() => setLoading(false)}
- />
- );
- const iframeDisplayStyle = loading ? 'none' : 'inline';
- return (
- <AntModal
- title={title}
- open={open}
- onOk={handleOk}
- onCancel={handleCancel}
- afterClose={afterClose}
- bodyStyle={modalContentBodyStyle}
- width={width ?? defaultWidth}
- zIndex={999}
- footer={null}
- centered
- destroyOnClose
- >
- <ErrorBoundary
- // eslint-disable-next-line react/no-unstable-nested-components
- fallbackRender={({ error, resetErrorBoundary }) => (
- <ComponentError
- componentName="Modal"
- message={error.message}
- retryFunction={resetErrorBoundary}
- />
- )}
- >
- <div id="modal-container" style={{ height: '100%' }}>
- {loading && (
- <Skeleton active={loading} style={{ padding: '10px' }} paragraph={{ rows: 10 }} />
- )}
- {iframe && <div style={{ display: iframeDisplayStyle }}>{iframe}</div>}
- {children && <div className={styles.content}>{children}</div>}
- {loading && <Spin className={styles.spinner} spinning={loading} size="large" />}
- </div>
- </ErrorBoundary>
- </AntModal>
- );
- };
- export default Modal;
- Modal.defaultProps = {
- url: undefined,
- children: undefined,
- handleOk: undefined,
- handleCancel: undefined,
- afterClose: undefined,
- };
|