import React from 'react'; import _ from 'lodash'; const normalizeUrl = (url: string) => { return { url, shouldReload: true, }; }; enum DataType { HTML = 'html', React = 'react', } export interface ModalProps { url: string; requestData?: object; requestType?: 'GET' | 'POST'; events: Record void>; // map from event name to callback isActive?: boolean; onModalClosed: (eventData: string) => void; } export interface ModalState { type: DataType | null; reactComponent: React.ReactNode; shouldTemplateFetcherUpdate: boolean; normalizedUrl: string; } class Modal extends React.Component { state: ModalState = { type: null, reactComponent: null, shouldTemplateFetcherUpdate: true, normalizedUrl: '', }; componentDidMount() { this.handleUrlChanged(); } componentDidUpdate(prevProps: ModalProps) { if (prevProps.url !== this.props.url) { this.handleUrlChanged(); } } componentWillUnmount() { // unregister from parent modal } handleUrlChanged = () => { const { url, shouldReload } = normalizeUrl(this.props.url); const type = this.getContentType(url); this.setState({ type, normalizedUrl: url, shouldTemplateFetcherUpdate: shouldReload }); }; getContentType = (url: string) => { // If given url exists in router if (url) { return DataType.React; } return DataType.HTML; }; close = (eventData: string) => { this.props.onModalClosed(eventData); if (!_.isUndefined(eventData)) { this.triggerEvent('data-received', eventData); } this.triggerEvent('disposing'); this.triggerEvent('hide', eventData); }; triggerEvent = (eventName: string, eventData?: string) => { this.props.events[eventName](eventData); }; setupEventListeners = () => { // ajaxify functionality here }; render() { const { type, normalizedUrl, reactComponent, shouldTemplateFetcherUpdate } = this.state; if (!type) { return 'Loader'; } return type === DataType.React ? (
{reactComponent}
) : ( ); } } export default Modal;