import React, { useCallback, useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import Portal from '../Portal';
import { bottomLeftNode, bottomRightNode, topLeftNode, topRightNode } from '../Portal/register';
import { uniqueId } from '../../utils/helpers';
const mapDefaultNode = {
'bottom-left': bottomLeftNode,
'bottom-right': bottomRightNode,
'top-left': topLeftNode,
'top-right': topRightNode,
};
const notificationRef = {
max: 3,
update: ({ max }) => {
notificationRef.max = max || notificationRef.max;
},
nodes: {},
instances: new Map(),
isDuplicate: (id) => {
return id && notificationRef.instances.has(id);
},
keepMax: () => {
if (notificationRef.instances.size > notificationRef.max - 1) {
let counter = 0;
const willClose = [];
for (const [key, { doClose }] of notificationRef.instances) {
if (counter <= notificationRef.instances.size - notificationRef.max) {
willClose.push({
key,
doClose,
});
}
counter++;
}
willClose.forEach(({ doClose }) => doClose());
}
},
closeAll: () => {
const willClose = [];
for (const [key, { doClose }] of notificationRef.instances) {
willClose.push({
key,
doClose,
});
}
willClose.forEach(({ doClose }) => doClose());
},
closeById: (id) => {
const notiInstance = notificationRef.instances.get(id);
if (notiInstance) {
notiInstance.doClose();
}
},
};
const PusherNotification = ({ id, renderFunc, autoClose, onUnmounted, placement, ...otherProps }) => {
const ref = useRef();
const [isOpen, setIsOpen] = useState(true);
const doClose = useCallback(() => setIsOpen(false), [setIsOpen]);
useEffect(() => {
if (autoClose) {
ref.current = setTimeout(() => doClose(), autoClose);
return () => clearTimeout(ref.current);
}
}, [autoClose, doClose, ref]);
useEffect(() => {
if (isOpen) {
notificationRef.instances.set(id, {
doClose,
});
}
}, [id, isOpen, doClose]);
useEffect(() => {
if (!isOpen) {
notificationRef.instances.delete(id);
}
return () => notificationRef.instances.delete(id);
}, []);
useEffect(() => {
if (!isOpen && onUnmounted) {
onUnmounted();
}
}, [isOpen, onUnmounted]);
if (isOpen) {
return (
<Portal {...otherProps} node={mapDefaultNode[placement]}>
{renderFunc({ doClose })}
</Portal>
);
}
return null;
};
PusherNotification.propTypes = {
id: PropTypes.string.isRequired,
renderFunc: PropTypes.func.isRequired,
autoClose: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
onUnmounted: PropTypes.func,
placement: PropTypes.oneOf(['bottom-left', 'bottom-right', 'top-left', 'top-right'])
};
PusherNotification.defaultProps = {
autoClose: 9000,
onUnmounted: f => f,
placement: 'bottom-left',
};
notificationRef.push = (renderFunc, params) => {
const { id, ...otherProps } = params || {};
const _id = id || uniqueId();
const isDuplicate = notificationRef.isDuplicate(_id);
const node = window.document.createElement('div');
const onUnmounted = () => ReactDOM.unmountComponentAtNode(node);
if (isDuplicate) {
ReactDOM.unmountComponentAtNode(notificationRef.nodes[_id]);
notificationRef.instances.delete(_id);
}
notificationRef.keepMax();
notificationRef.nodes[_id] = node;
ReactDOM.render((
<PusherNotification
renderFunc={renderFunc}
onUnmounted={onUnmounted}
id={_id}
{...otherProps}
/>
), node);
};
export { notificationRef };
export default PusherNotification;
import React, { useState, useCallback, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import Portal from '../Portal';
import { uniqueId } from '../../utils/helpers';
import {
bottomLeftNode,
bottomRightNode,
topLeftNode,
topRightNode,
topCenterNode,
bottomCenterNode,
} from '../Portal/register';
const mapDefaultNode = {
'bottom-left': bottomLeftNode,
'bottom-right': bottomRightNode,
'top-left': topLeftNode,
'top-right': topRightNode,
'top-center': topCenterNode,
'bottom-center': bottomCenterNode,
};
const alertRef = {
max: 9,
update: ({ max }) => {
alertRef.max = max || alertRef.max;
},
nodes: {},
instances: new Map(),
isDuplicate: (id) => {
return id && alertRef.instances.has(id);
},
keepMax: () => {
if (alertRef.instances.size > alertRef.max - 1) {
let counter = 0;
const willClose = [];
for (const [key, { doClose }] of alertRef.instances) {
if (counter <= alertRef.instances.size - alertRef.max) {
willClose.push({
key,
doClose,
});
}
counter++;
}
willClose.forEach(({ doClose }) => doClose());
}
},
closeAll: () => {
const willClose = [];
for (const [key, { doClose }] of alertRef.instances) {
willClose.push({
key,
doClose,
});
}
willClose.forEach(({ doClose }) => doClose());
},
closeById: (id) => {
const alertInstance = alertRef.instances.get(id);
if (alertInstance) {
alertInstance.doClose();
}
},
};
const PusherAlert = ({ id, renderFunc, placement, onUnmounted, autoClose, ...otherProps }) => {
const ref = useRef();
const [isOpen, setIsOpen] = useState(true);
const doClose = useCallback(() => setIsOpen(false), [setIsOpen]);
useEffect(() => {
if (autoClose) {
ref.current = setTimeout(() => doClose(), autoClose);
return () => clearTimeout(ref.current);
}
}, [autoClose, doClose, ref]);
useEffect(() => {
if (isOpen) {
alertRef.instances.set(id, {
doClose,
});
}
}, [id, isOpen, doClose]);
useEffect(() => {
if (!isOpen) {
alertRef.instances.delete(id);
}
return () => alertRef.instances.delete(id);
}, []);
useEffect(() => {
if (!isOpen && onUnmounted) {
onUnmounted();
}
}, [isOpen, onUnmounted]);
if (isOpen) {
return (
<Portal {...otherProps} node={mapDefaultNode[placement]}>
<div className="fpusher-alert-wrapper">
{renderFunc({ doClose })}
</div>
</Portal>
);
}
return null;
};
PusherAlert.propTypes = {
id: PropTypes.string.isRequired,
renderFunc: PropTypes.func.isRequired,
autoClose: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
onUnmounted: PropTypes.func,
placement: PropTypes.oneOf(['bottom-left', 'bottom-right', 'top-left', 'top-right', 'top-center', 'bottom-center'])
};
PusherAlert.defaultProps = {
autoClose: 9000,
onUnmounted: f => f,
placement: 'top-center',
};
alertRef.push = (renderFunc, params) => {
const { id, ...otherProps } = params || {};
const _id = id || uniqueId();
const isDuplicate = alertRef.isDuplicate(_id);
const node = window.document.createElement('div');
const onUnmounted = () => ReactDOM.unmountComponentAtNode(node);
if (isDuplicate) {
ReactDOM.unmountComponentAtNode(alertRef.nodes[_id]);
alertRef.instances.delete(_id);
}
alertRef.keepMax();
alertRef.nodes[_id] = node;
ReactDOM.render((
<PusherAlert
id={_id}
renderFunc={renderFunc}
onUnmounted={onUnmounted}
{...otherProps}
/>
), node);
};
export { alertRef };
export default PusherAlert;
var FormUtils = {
displayError: function (returnMessage)
{
alert(returnMessage);
},
showConfirmMessageBox: function (msg, callback, type, buttontext)
{
if (buttontext !== null && buttontext !== undefined && buttontext !== '') {
$('#confirm-btn').text(buttontext);
}
var isConfirm = false;
$('#popup_confirm_message_box_content').text(msg);
$('#popup_confirm_message_box').show();
$('#popup_confirm_message_box_dim').click(function (e)
{
doClose();
});
$('#popup_confirm_message_box_close').click(function (e)
{
doClose();
});
$('#confirm-btn-cancel').click(function () {
isConfirm = false;
doClose();
});
$('#confirm-btn').click(function () {
isConfirm = true;
doClose();
});
function doClose()
{
$('#popup_confirm_message_box').hide();
if (callback !== undefined && callback !== null && isConfirm) {
callback();
callback = null;
}
$('#popup_confirm_message_box_dim').unbind("click");
$('#confirm-btn-cancel').unbind("click");
$('#confirm-btn-delete').unbind("click");
$('#popup_confirm_message_box_close').unbind("click");
}
switch (type)
{
case "error":
$('#popup_message_panel').attr("class", "panel panel-danger");
break;
case "success":
$('#popup_message_panel').attr("class", "panel panel-success");
break;
default:
$('#popup_message_panel').attr("class", "panel panel-default");
break;
}
$('#popup_confirm_message_box_dim').css('height', $(document).height() + 'px');
},
showMessageBox: function (msg, callback, type)
{
$('#msg_header').html("Thông báo");
$('#popup_message_box_content').text(msg);
$('#popup_message_box').show();
$('#popup_message_box_dim').click(function (e)
{
doClose();
});
$('#popup_message_box_close').click(function (e)
{
doClose();
});
function doClose()
{
$('#popup_message_box').hide();
if (callback !== undefined && callback !== null)
callback();
}
switch (type)
{
case "error":
$('#popup_message_panel').attr("class", "panel panel-danger");
break;
case "success":
$('#popup_message_panel').attr("class", "panel panel-success");
break;
default:
$('#popup_message_panel').attr("class", "panel panel-default");
break;
}
$('#popup_message_box_dim').css('height', $(document).height() + 'px');
},
showMessageBoxWithTitle: function (msg, title, callback, type)
{
$('#msg_header').html(title);
$('#popup_message_box_content').text(msg);
$('#popup_message_box').show();
$('#popup_message_box_dim').click(function (e)
{
doClose();
});
$('#popup_message_box_close').click(function (e)
{
doClose();
});
function doClose()
{
$('#popup_message_box').hide();
if (callback !== undefined && callback !== null)
callback();
}
switch (type)
{
case "error":
$('#popup_message_panel').attr("class", "panel panel-danger");
break;
case "success":
$('#popup_message_panel').attr("class", "panel panel-success");
break;
default:
$('#popup_message_panel').attr("class", "panel panel-default");
break;
}
$('#popup_message_box_dim').css('height', $(document).height() + 'px');
},
clearError: function () {
$("input").change(function () {
$(this).parent().parent().removeClass('has-error');
$(this).next().empty();
});
$("textarea").change(function () {
$(this).parent().parent().removeClass('has-error');
$(this).next().empty();
});
$("select").change(function () {
$(this).parent().parent().removeClass('has-error');
$(this).next().empty();
});
},
};
Accelerate Your Automation Test Cycles With LambdaTest
Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.