@etsoo/materialui
Version:
TypeScript Material-UI Implementation
392 lines (391 loc) • 22 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NotifierMU = exports.NotificationMU = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const notificationbase_1 = require("@etsoo/notificationbase");
const shared_1 = require("@etsoo/shared");
const react_1 = __importDefault(require("react"));
const react_2 = require("@etsoo/react");
const DraggablePaperComponent_1 = require("./DraggablePaperComponent");
const LoadingButton_1 = require("./LoadingButton");
const Labels_1 = require("./app/Labels");
const DialogTitle_1 = __importDefault(require("@mui/material/DialogTitle"));
const styles_1 = require("@mui/material/styles");
const Dialog_1 = __importDefault(require("@mui/material/Dialog"));
const IconButton_1 = __importDefault(require("@mui/material/IconButton"));
const DialogContent_1 = __importDefault(require("@mui/material/DialogContent"));
const DialogActions_1 = __importDefault(require("@mui/material/DialogActions"));
const DialogContentText_1 = __importDefault(require("@mui/material/DialogContentText"));
const Fade_1 = __importDefault(require("@mui/material/Fade"));
const Alert_1 = __importDefault(require("@mui/material/Alert"));
const AlertTitle_1 = __importDefault(require("@mui/material/AlertTitle"));
const Switch_1 = __importDefault(require("@mui/material/Switch"));
const Slider_1 = __importDefault(require("@mui/material/Slider"));
const TextField_1 = __importDefault(require("@mui/material/TextField"));
const Typography_1 = __importDefault(require("@mui/material/Typography"));
const Button_1 = __importDefault(require("@mui/material/Button"));
const Popover_1 = __importDefault(require("@mui/material/Popover"));
const CircularProgress_1 = __importDefault(require("@mui/material/CircularProgress"));
const Backdrop_1 = __importDefault(require("@mui/material/Backdrop"));
const Box_1 = __importDefault(require("@mui/material/Box"));
const Snackbar_1 = __importDefault(require("@mui/material/Snackbar"));
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
const Done_1 = __importDefault(require("@mui/icons-material/Done"));
const Info_1 = __importDefault(require("@mui/icons-material/Info"));
const Warning_1 = __importDefault(require("@mui/icons-material/Warning"));
const Error_1 = __importDefault(require("@mui/icons-material/Error"));
const Help_1 = __importDefault(require("@mui/icons-material/Help"));
// Custom icon dialog title bar
const IconDialogTitle = (0, styles_1.styled)(DialogTitle_1.default, {
// Prevent the passing of the draggable prop to the underlying DOM element
shouldForwardProp: (prop) => prop !== "draggable"
}) `
${({ theme, draggable }) => `
cursor: ${draggable ? "move" : "default"};
display: flex;
align-items: center;
& .dialogTitle {
font-weight: bold;
font-size: 1.17em;
flex-grow: 3;
text-overflow: ellipsis;
padding-left: ${theme.spacing(1)};
}
& .MuiDialogContent-root-close-button {
padding-left: ${theme.spacing(1)};
}
`}
`;
/**
* MU notification
*/
class NotificationMU extends react_2.NotificationReact {
// Create alert
createAlert(_props, className) {
const labels = Labels_1.Labels.NotificationMU;
const { buttons, inputs, fullScreen, fullWidth = true, maxWidth, okLabel = labels.alertOK, primaryButton = true, primaryButtonProps, closable = false, draggable = fullScreen === true ? false : true } = this.inputProps ?? {};
let title = this.title;
let icon;
if (this.type === notificationbase_1.NotificationMessageType.Success) {
icon = (0, jsx_runtime_1.jsx)(Done_1.default, { color: "primary" });
title ??= labels.success;
}
else if (this.type === notificationbase_1.NotificationMessageType.Info) {
icon = (0, jsx_runtime_1.jsx)(Info_1.default, {});
title ??= labels.info;
}
else if (this.type === notificationbase_1.NotificationMessageType.Warning) {
icon = (0, jsx_runtime_1.jsx)(Warning_1.default, { color: "secondary" });
title ??= labels.warning;
}
else {
icon = (0, jsx_runtime_1.jsx)(Error_1.default, { color: "error" });
title ??= labels.alertTitle;
}
const setupProps = {
color: "primary"
};
// Setup callback
const options = this.renderSetup ? this.renderSetup(setupProps) : undefined;
// Callback
const callback = async (_event) => {
await this.returnValue(undefined);
return true;
};
return ((0, jsx_runtime_1.jsxs)(Dialog_1.default, { open: this.open, PaperComponent: draggable ? DraggablePaperComponent_1.DraggablePaperComponent : undefined, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen, ...options, children: [(0, jsx_runtime_1.jsxs)(IconDialogTitle, { draggable: draggable, className: draggable ? "dialog-title draggable-dialog-title" : "dialog-title", children: [icon, (0, jsx_runtime_1.jsx)("span", { className: "dialogTitle", children: title }), closable && ((0, jsx_runtime_1.jsx)(IconButton_1.default, { className: "MuiDialogContent-root-close-button", size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) }))] }), (0, jsx_runtime_1.jsxs)(DialogContent_1.default, { children: [typeof this.content === "string" ? ((0, jsx_runtime_1.jsx)(DialogContentText_1.default, { children: this.content })) : (this.content), inputs] }), (0, jsx_runtime_1.jsx)(DialogActions_1.default, { children: buttons
? buttons(this, callback)
: primaryButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { ...setupProps, onClick: callback, autoFocus: true, ...primaryButtonProps, children: okLabel })) })] }, this.id));
}
// Create confirm
createConfirm(_props, className) {
const labels = Labels_1.Labels.NotificationMU;
const title = this.title ?? labels.confirmTitle;
const { buttons, okLabel = labels.confirmYes, cancelLabel = labels.confirmNo, cancelButton = true, inputs, fullScreen, fullWidth = true, maxWidth, primaryButton = true, primaryButtonProps, closable = false, draggable = fullScreen === true ? false : true } = this.inputProps ?? {};
// Setup callback
const options = this.renderSetup ? this.renderSetup({}) : undefined;
const callback = async (_event, value) => {
await this.returnValue(value);
return true;
};
return ((0, jsx_runtime_1.jsxs)(Dialog_1.default, { open: this.open, PaperComponent: draggable ? DraggablePaperComponent_1.DraggablePaperComponent : undefined, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen, ...options, children: [(0, jsx_runtime_1.jsxs)(IconDialogTitle, { draggable: draggable, className: draggable ? "dialog-title draggable-dialog-title" : "dialog-title", children: [(0, jsx_runtime_1.jsx)(Help_1.default, { color: "action" }), (0, jsx_runtime_1.jsx)("span", { className: "dialogTitle", children: title }), closable && ((0, jsx_runtime_1.jsx)(IconButton_1.default, { className: "MuiDialogContent-root-close-button", size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) }))] }), (0, jsx_runtime_1.jsxs)(DialogContent_1.default, { children: [typeof this.content === "string" ? ((0, jsx_runtime_1.jsx)(DialogContentText_1.default, { children: this.content })) : (this.content), inputs] }), (0, jsx_runtime_1.jsx)(DialogActions_1.default, { children: buttons ? (buttons(this, callback)) : ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [cancelButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { color: "secondary", onClick: async (event) => await callback(event, false), children: cancelLabel })), primaryButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { color: "primary", onClick: async (event) => await callback(event, true), autoFocus: true, ...primaryButtonProps, children: okLabel }))] })) })] }, this.id));
}
createMessageColor() {
if (this.type === notificationbase_1.NotificationMessageType.Danger)
return "error";
if (this.type === notificationbase_1.NotificationMessageType.Success)
return "success";
if (this.type === notificationbase_1.NotificationMessageType.Warning)
return "warning";
return "info";
}
// Create message
createMessage(props, className) {
if (!this.open)
return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, {}, this.id);
const { closable = false } = props;
const setupProps = {
severity: this.createMessageColor(),
variant: "filled"
};
// Setup callback
const options = this.renderSetup ? this.renderSetup(setupProps) : undefined;
return ((0, jsx_runtime_1.jsx)(Fade_1.default, { in: true, children: (0, jsx_runtime_1.jsxs)(Alert_1.default, { ...setupProps, ...options, action: closable ? ((0, jsx_runtime_1.jsx)(IconButton_1.default, { size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) })) : undefined, onClose: () => this.dismiss(), className: className, children: [this.title && (0, jsx_runtime_1.jsx)(AlertTitle_1.default, { children: this.title }), this.content] }) }, this.id));
}
// Create prompt
createPrompt(_props, className) {
const labels = Labels_1.Labels.NotificationMU;
const title = this.title ?? labels.promptTitle;
const { buttons, cancelLabel = labels.promptCancel, okLabel = labels.promptOK, cancelButton = true, inputs, type, fullScreen, fullWidth = true, maxWidth, primaryButton = true, primaryButtonProps, inputProps, closable = false, draggable = fullScreen === true ? false : true } = this.inputProps ?? {};
const inputRef = react_1.default.createRef();
const errorRef = react_1.default.createRef();
const setError = (error) => {
if (errorRef.current == null)
return;
errorRef.current.innerText = error ?? "";
};
const handleSubmit = async (event) => {
// Result
let result = undefined;
const input = inputRef.current;
if (this.onReturn) {
// Inputs case, no HTMLForm set to value, set the current form
if (inputs && value == null)
value = event.currentTarget.form;
if (input) {
if (type === "switch") {
const boolValue = input.value === "true";
result = this.onReturn(boolValue);
}
else {
const inputValue = shared_1.DomUtils.getInputValue(input);
if ((inputValue == null || inputValue === "") && input.required) {
input.focus();
return false;
}
result = this.onReturn(inputValue);
}
}
else if (value != null) {
result = this.onReturn(value);
}
}
// Get the value
// returns false to prevent default dismiss
const v = await result;
if (v === false) {
input?.focus();
return false;
}
if (typeof v === "string") {
setError(v);
input?.focus();
return false;
}
this.dismiss();
return true;
};
let localInputs;
let value = undefined;
if (inputs == null) {
if (type === "switch") {
localInputs = ((0, jsx_runtime_1.jsx)(Switch_1.default, { inputRef: inputRef, ...inputProps, value: "true", autoFocus: true, required: true }));
}
else if (type === "slider") {
localInputs = (0, jsx_runtime_1.jsx)(Slider_1.default, { onChange: (_e, v) => (value = v) });
}
else {
localInputs = ((0, jsx_runtime_1.jsx)(TextField_1.default, { inputRef: inputRef, onChange: () => setError(undefined), autoFocus: true, margin: "dense", fullWidth: true, type: type, required: true, ...inputProps }));
}
}
else {
localInputs = inputs;
}
// Setup callback
const options = this.renderSetup ? this.renderSetup({}) : undefined;
return ((0, jsx_runtime_1.jsx)(Dialog_1.default, { open: this.open, PaperComponent: draggable ? DraggablePaperComponent_1.DraggablePaperComponent : undefined, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen, ...options, children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: (event) => {
event.preventDefault();
event.currentTarget.elements.namedItem("okButton")?.click();
return false;
}, children: [(0, jsx_runtime_1.jsxs)(IconDialogTitle, { draggable: draggable, className: draggable ? "dialog-title draggable-dialog-title" : "dialog-title", children: [(0, jsx_runtime_1.jsx)(Info_1.default, { color: "primary" }), (0, jsx_runtime_1.jsx)("span", { className: "dialogTitle", children: title }), closable && ((0, jsx_runtime_1.jsx)(IconButton_1.default, { className: "MuiDialogContent-root-close-button", size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) }))] }), (0, jsx_runtime_1.jsxs)(DialogContent_1.default, { children: [typeof this.content === "string" ? ((0, jsx_runtime_1.jsx)(DialogContentText_1.default, { children: this.content })) : (this.content), localInputs, (0, jsx_runtime_1.jsx)(Typography_1.default, { variant: "caption", display: "block", ref: errorRef, color: "error" })] }), (0, jsx_runtime_1.jsx)(DialogActions_1.default, { children: buttons ? (buttons(this, handleSubmit)) : ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [cancelButton && ((0, jsx_runtime_1.jsx)(Button_1.default, { color: "secondary", onClick: () => {
if (this.onReturn)
this.onReturn(undefined);
this.dismiss();
}, children: cancelLabel })), primaryButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { color: "primary", autoFocus: true, onClick: handleSubmit, name: "okButton", ...primaryButtonProps, children: okLabel }))] })) })] }) }, this.id));
}
createPopup(_props, className) {
// Destruct
// dismiss will trigger onReturn callback
const { content, id, open } = this;
// Setup callback
const options = this.renderSetup ? this.renderSetup({}) : undefined;
return ((0, jsx_runtime_1.jsx)(Popover_1.default, { open: open, className: className, onClose: () => this.dismiss(), ...options, children: content }, id));
}
// Create loading
createLoading(_props, className) {
// Properties
const setupProps = { color: "primary" };
const labels = Labels_1.Labels.NotificationMU;
// Input props
const { maxWidth = "xs" } = this.inputProps ?? {};
// Content
let content = this.content;
if (content === "@")
content = labels.loading.toString();
// Setup callback
const options = this.renderSetup ? this.renderSetup(setupProps) : undefined;
return ((0, jsx_runtime_1.jsx)(Backdrop_1.default, { className: className, sx: {
color: "#fff",
zIndex: (theme) => theme.zIndex.modal + 1
}, open: this.open, ...options, children: (0, jsx_runtime_1.jsxs)(Box_1.default, { display: "flex", flexDirection: "column", flexWrap: "nowrap", alignItems: "center", sx: {
"& > :not(style) + :not(style)": {
marginTop: (theme) => theme.spacing(1)
}
}, children: [(0, jsx_runtime_1.jsx)(CircularProgress_1.default, { ...setupProps }), content && ((0, jsx_runtime_1.jsx)(Box_1.default, { maxWidth: maxWidth === false ? undefined : maxWidth, children: content }))] }) }, this.id));
}
/**
* Render method
* @param props Props
* @param className Style class name
* @param classes Style classes
*/
render(props, className) {
// Loading bar
if (this.type === notificationbase_1.NotificationType.Loading) {
return this.createLoading(props, className);
}
else if (this.type === notificationbase_1.NotificationType.Confirm) {
return this.createConfirm(props, className);
}
else if (this.type === notificationbase_1.NotificationType.Prompt) {
return this.createPrompt(props, className);
}
else if (this.type === notificationbase_1.NotificationType.Popup) {
return this.createPopup(props, className);
}
else if (this.type === notificationbase_1.NotificationType.Error ||
(this.modal && this.type in notificationbase_1.NotificationMessageType)) {
// Alert or modal message
return this.createAlert(props, className);
}
else {
return this.createMessage(props, className);
}
}
}
exports.NotificationMU = NotificationMU;
/**
* Antd notifier
*/
class NotifierMU extends react_2.NotifierReact {
/**
* Create state and return provider
* @param className Style class name
* @param debug Debug mode
* @returns Provider
*/
static setup(className, debug = false) {
className ??= "notifier-mu";
// Create an instance
const instance = new NotifierMU();
instance.debug = debug;
const provider = instance.createProvider(className, debug);
react_2.NotifierReact.updateInstance(instance);
return provider;
}
// Calculate origin from align property
static getOrigin(align) {
if (align === notificationbase_1.NotificationAlign.TopLeft) {
return {
horizontal: "left",
vertical: "top"
};
}
if (align === notificationbase_1.NotificationAlign.TopCenter) {
return {
horizontal: "center",
vertical: "top"
};
}
if (align === notificationbase_1.NotificationAlign.TopRight) {
return {
horizontal: "right",
vertical: "top"
};
}
if (align === notificationbase_1.NotificationAlign.BottomLeft) {
return {
horizontal: "left",
vertical: "bottom"
};
}
if (align === notificationbase_1.NotificationAlign.BottomCenter) {
return {
horizontal: "center",
vertical: "bottom"
};
}
if (align === notificationbase_1.NotificationAlign.BottomRight) {
return {
horizontal: "right",
vertical: "bottom"
};
}
return {
horizontal: "center",
vertical: "top"
};
}
/**
* Create align container
* @param align Align
* @param children Children
* @param options Other options
*/
createContainer = (align, children) => {
// Each align group, class equal to something similar to 'align-topleft'
const alignText = notificationbase_1.NotificationAlign[align].toLowerCase();
let className = `align-${alignText}`;
if (children.length === 0) {
return (0, jsx_runtime_1.jsx)("div", { className: className }, `empty-${alignText}`);
}
if (align === notificationbase_1.NotificationAlign.Unknown) {
// div container for style control
return ((0, jsx_runtime_1.jsx)("div", { className: className, children: children }, `div-${alignText}`));
}
// Use SnackBar for layout
return ((0, jsx_runtime_1.jsx)(Snackbar_1.default, { anchorOrigin: NotifierMU.getOrigin(align), className: className, sx: align === notificationbase_1.NotificationAlign.Center
? { position: "fixed", top: "50%!important" }
: undefined, open: true, children: (0, jsx_runtime_1.jsx)(Box_1.default, { display: "flex", flexDirection: "column", flexWrap: "nowrap", sx: {
"& > :not(style) + :not(style)": {
marginTop: (theme) => theme.spacing(1)
}
}, children: children }, `box-${alignText}`) }, `layout-${alignText}`));
};
/**
* Add raw definition
* @param data Notification data definition
* @param modal Show as modal
*/
addRaw(data, modal) {
// Destruct
const { type, content, title, align, timespan = modal ? 0 : undefined, ...rest } = data;
if (this.debug) {
console.debug("NotificationMU.addRaw", data);
}
// Setup
const n = new NotificationMU(type, content, title, align, timespan);
// Assign other properties
Object.assign(n, rest);
// Is modal
if (modal != null)
n.modal = modal;
// Add to the collection
this.add(n);
// Return
return n;
}
}
exports.NotifierMU = NotifierMU;