mirror of
https://gitlab.com/comunic/comunicconsole
synced 2025-04-20 11:40:54 +00:00
325 lines
7.0 KiB
TypeScript
325 lines
7.0 KiB
TypeScript
/**
|
|
* Application dialogs provider
|
|
*
|
|
* @author Pierre Hubert
|
|
*/
|
|
|
|
import {
|
|
Dialog,
|
|
DialogTitle,
|
|
DialogContent,
|
|
DialogContentText,
|
|
DialogActions,
|
|
Button,
|
|
TextField,
|
|
Snackbar,
|
|
IconButton,
|
|
} from "@material-ui/core";
|
|
import { Close } from "@material-ui/icons";
|
|
import React from "react";
|
|
|
|
let cache: ApplicationDialogsProvider;
|
|
|
|
export interface TextInputOptions {
|
|
title?: string;
|
|
message?: string;
|
|
initialValue?: string;
|
|
minLength?: number;
|
|
maxLength?: number;
|
|
label: string;
|
|
}
|
|
|
|
interface AppDiagProvState {
|
|
// Alert dialog
|
|
alertMessage: string;
|
|
showAlert: boolean;
|
|
|
|
// Simple snackbar
|
|
snackBarMessage: string;
|
|
showSnackBar: boolean;
|
|
|
|
// Confirm dialog
|
|
confirmMessage: string;
|
|
showConfirm: boolean;
|
|
resolveConfirm?: (confirmed: boolean) => void;
|
|
|
|
// Text input dialog
|
|
showInputDialog: boolean;
|
|
inputValue: string;
|
|
inputOptions: TextInputOptions;
|
|
resolveInput?: (text: string) => void;
|
|
}
|
|
|
|
export class ApplicationDialogsProvider extends React.Component<
|
|
{},
|
|
AppDiagProvState
|
|
> {
|
|
private acceptConfirm: () => void;
|
|
private rejectConfirm: () => void;
|
|
private cancelInput: () => void;
|
|
private confirmInput: () => void;
|
|
|
|
constructor(props: any) {
|
|
super(props);
|
|
|
|
this.state = {
|
|
// Alert dialog
|
|
alertMessage: "",
|
|
showAlert: false,
|
|
|
|
// Simple snackbar
|
|
snackBarMessage: "",
|
|
showSnackBar: false,
|
|
|
|
// Confirm dialog
|
|
showConfirm: false,
|
|
confirmMessage: "",
|
|
resolveConfirm: undefined,
|
|
|
|
// Text input dialog
|
|
showInputDialog: false,
|
|
inputValue: "",
|
|
inputOptions: {
|
|
label: "",
|
|
},
|
|
resolveInput: undefined,
|
|
};
|
|
|
|
this.handleCloseAlert = this.handleCloseAlert.bind(this);
|
|
|
|
this.handleCloseSnackbar = this.handleCloseSnackbar.bind(this);
|
|
|
|
this.acceptConfirm = this.handleCloseConfirm.bind(this, true);
|
|
this.rejectConfirm = this.handleCloseConfirm.bind(this, false);
|
|
|
|
this.handleInputValueChanged = this.handleInputValueChanged.bind(this);
|
|
this.cancelInput = this.handleCloseInput.bind(this, true);
|
|
this.confirmInput = this.handleCloseInput.bind(this, false);
|
|
}
|
|
|
|
showAlert(message: string) {
|
|
this.setState({
|
|
showAlert: true,
|
|
alertMessage: message,
|
|
});
|
|
}
|
|
|
|
handleCloseAlert() {
|
|
this.setState({ showAlert: false });
|
|
}
|
|
|
|
showSnackbar(message: string) {
|
|
this.setState({ showSnackBar: true, snackBarMessage: message });
|
|
}
|
|
|
|
handleCloseSnackbar(
|
|
_event: React.SyntheticEvent | React.MouseEvent,
|
|
reason?: string
|
|
) {
|
|
if (reason === "clickaway") {
|
|
return;
|
|
}
|
|
|
|
this.setState({ showSnackBar: false });
|
|
}
|
|
|
|
showConfirm(message: string): Promise<boolean> {
|
|
return new Promise((res, _rej) => {
|
|
this.setState({
|
|
showConfirm: true,
|
|
confirmMessage: message,
|
|
resolveConfirm: res,
|
|
});
|
|
});
|
|
}
|
|
|
|
handleCloseConfirm(accept: boolean) {
|
|
this.setState({
|
|
showConfirm: false,
|
|
});
|
|
|
|
this.state.resolveConfirm && this.state.resolveConfirm(accept);
|
|
}
|
|
|
|
showInput(options: TextInputOptions): Promise<string> {
|
|
return new Promise((res, _rej) => {
|
|
this.setState({
|
|
showInputDialog: true,
|
|
inputOptions: options,
|
|
resolveInput: res,
|
|
inputValue: options.initialValue || "",
|
|
});
|
|
});
|
|
}
|
|
|
|
handleInputValueChanged(e: React.ChangeEvent<HTMLInputElement>) {
|
|
this.setState({ inputValue: e.target.value });
|
|
}
|
|
|
|
handleCloseInput(cancel: boolean) {
|
|
this.setState({
|
|
showInputDialog: false,
|
|
});
|
|
|
|
if (!cancel)
|
|
this.state.resolveInput &&
|
|
this.state.resolveInput(this.state.inputValue);
|
|
}
|
|
|
|
get isInputValid(): boolean {
|
|
const options = this.state.inputOptions;
|
|
const value = this.state.inputValue;
|
|
|
|
if (options.minLength && value.length < options.minLength) return false;
|
|
|
|
if (options.maxLength && value.length > options.maxLength) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
render() {
|
|
cache = this;
|
|
|
|
if (this.state == null) return <div></div>;
|
|
|
|
return (
|
|
<div>
|
|
{/* Simple alert dialog */}
|
|
<Dialog
|
|
open={this.state.showAlert}
|
|
onClose={this.handleCloseAlert}
|
|
aria-labelledby="alert-dialog-title"
|
|
aria-describedby="alert-dialog-description"
|
|
>
|
|
<DialogTitle
|
|
id="alert-dialog-title"
|
|
style={{ minWidth: "300px" }}
|
|
>
|
|
Message
|
|
</DialogTitle>
|
|
<DialogContent>
|
|
<DialogContentText id="alert-dialog-description">
|
|
{this.state.alertMessage}
|
|
</DialogContentText>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={this.handleCloseAlert} color="default">
|
|
OK
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
|
|
{/* Simple snackbar */}
|
|
<Snackbar
|
|
anchorOrigin={{
|
|
vertical: "bottom",
|
|
horizontal: "left",
|
|
}}
|
|
open={this.state.showSnackBar}
|
|
autoHideDuration={6000}
|
|
onClose={this.handleCloseSnackbar}
|
|
message={this.state.snackBarMessage}
|
|
action={
|
|
<React.Fragment>
|
|
<IconButton
|
|
size="small"
|
|
aria-label="close"
|
|
color="inherit"
|
|
onClick={this.handleCloseSnackbar}
|
|
>
|
|
<Close fontSize="small" />
|
|
</IconButton>
|
|
</React.Fragment>
|
|
}
|
|
/>
|
|
|
|
{/* Confirm dialog */}
|
|
<Dialog
|
|
open={this.state.showConfirm}
|
|
onClose={this.rejectConfirm}
|
|
aria-labelledby="alert-dialog-title"
|
|
aria-describedby="alert-dialog-description"
|
|
>
|
|
<DialogTitle
|
|
id="alert-dialog-title"
|
|
style={{ minWidth: "300px" }}
|
|
>
|
|
Confirm action
|
|
</DialogTitle>
|
|
<DialogContent>
|
|
<DialogContentText id="alert-dialog-description">
|
|
{this.state.confirmMessage}
|
|
</DialogContentText>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={this.rejectConfirm} color="default">
|
|
Cancel
|
|
</Button>
|
|
<Button onClick={this.acceptConfirm} color="default">
|
|
Confirm
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
|
|
{/* Text input dialog */}
|
|
<Dialog
|
|
open={this.state.showInputDialog}
|
|
onClose={this.rejectConfirm}
|
|
aria-labelledby="alert-dialog-title"
|
|
aria-describedby="alert-dialog-description"
|
|
>
|
|
<DialogTitle id="alert-dialog-title">
|
|
{this.state.inputOptions.title ||
|
|
this.state.inputOptions.label}
|
|
</DialogTitle>
|
|
<DialogContent>
|
|
{this.state.inputOptions.message ? (
|
|
<DialogContentText id="alert-dialog-description">
|
|
{this.state.inputOptions.message} <br />
|
|
<br />
|
|
</DialogContentText>
|
|
) : (
|
|
<span></span>
|
|
)}
|
|
|
|
<TextField
|
|
label={this.state.inputOptions.label}
|
|
variant="outlined"
|
|
value={this.state.inputValue}
|
|
onChange={this.handleInputValueChanged}
|
|
/>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button onClick={this.cancelInput} color="default">
|
|
Cancel
|
|
</Button>
|
|
<Button
|
|
onClick={this.confirmInput}
|
|
color="default"
|
|
disabled={!this.isInputValid}
|
|
>
|
|
OK
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export function matAlert(msg: string) {
|
|
cache.showAlert(msg);
|
|
}
|
|
|
|
export function snackbar(msg: string) {
|
|
cache.showSnackbar(msg);
|
|
}
|
|
|
|
export function matConfirm(msg: string): Promise<boolean> {
|
|
return cache.showConfirm(msg);
|
|
}
|
|
|
|
export function input(options: TextInputOptions): Promise<string> {
|
|
return cache.showInput(options);
|
|
}
|