200 lines
7.0 KiB
TypeScript
Raw Normal View History

2021-02-16 21:51:59 -08:00
import React from "react";
2021-02-17 18:10:45 -08:00
import { FormattedMessage, useIntl } from "react-intl";
2021-02-19 17:37:55 -08:00
import { useMutation, useQuery, useQueryClient } from "react-query";
2021-02-16 21:51:59 -08:00
import { useSelector } from "react-redux";
2021-02-19 17:37:55 -08:00
import Client, { ErrorInfo, Permission } from "../../../../classes/client";
2021-02-16 21:51:59 -08:00
import { activeInstance } from '../../../../redux/clientSlice';
2021-02-19 17:37:55 -08:00
import { SimpleDialogProps } from "..";
2021-02-16 21:51:59 -08:00
import BaseDialog from "../base-dialog";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import IconButton from "@material-ui/core/IconButton";
2021-02-19 17:37:55 -08:00
2021-02-16 21:51:59 -08:00
import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction";
import DeleteIcon from '@material-ui/icons/Delete';
import Paper from "@material-ui/core/Paper";
2021-02-17 18:10:45 -08:00
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
2021-02-19 17:37:55 -08:00
import Typography from "@material-ui/core/Typography";
import { useStyles } from "./style";
import RoleIcon from "../../role-icon";
2021-02-19 18:43:28 -08:00
import Tooltip from "@material-ui/core/Tooltip";
2021-02-19 17:37:55 -08:00
2021-02-16 21:51:59 -08:00
2021-02-19 17:37:55 -08:00
type ShareModel = {
emails: string,
role: 'editor' | 'viewer',
message: string
}
2021-02-16 21:51:59 -08:00
2021-02-19 17:37:55 -08:00
const defaultModel: ShareModel = { emails: '', role: 'editor', message: '' };
2021-02-16 21:51:59 -08:00
const ShareDialog = ({ mapId, onClose }: SimpleDialogProps): React.ReactElement => {
const intl = useIntl();
const client: Client = useSelector(activeInstance);
const queryClient = useQueryClient();
2021-02-19 17:37:55 -08:00
const classes = useStyles();
const [showMessage, setShowMessage] = React.useState<boolean>(false);
const [model, setModel] = React.useState<ShareModel>(defaultModel);
const [error, setError] = React.useState<ErrorInfo>();
2021-02-16 21:51:59 -08:00
2021-02-19 18:41:49 -08:00
const deleteMutation = useMutation(
(email: string) => {
return client.deleteMapPermission(mapId, email);
},
{
onSuccess: () => {
queryClient.invalidateQueries(`perm-${mapId}`);
setModel(defaultModel);
},
onError: (error: ErrorInfo) => {
setError(error);
}
}
);
const addMutation = useMutation(
2021-02-19 17:37:55 -08:00
(model: ShareModel) => {
const emails = model.emails.split("'");
const permissions = emails.map((email) => { return { email: email, role: model.role } });
return client.addMapPermissions(mapId, model.message, permissions);
},
2021-02-16 21:51:59 -08:00
{
2021-02-19 17:37:55 -08:00
onSuccess: () => {
queryClient.invalidateQueries(`perm-${mapId}`);
setModel(defaultModel);
},
onError: (error: ErrorInfo) => {
setError(error);
}
2021-02-16 21:51:59 -08:00
}
);
const handleOnClose = (): void => {
onClose();
};
2021-02-19 17:37:55 -08:00
const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
event.preventDefault();
const name = event.target.name;
const value = event.target.value;
setModel({ ...model, [name as keyof ShareModel]: value });
2021-02-16 21:51:59 -08:00
}
2021-02-19 18:41:49 -08:00
const handleOnAddClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>): void => {
2021-02-19 17:37:55 -08:00
event.stopPropagation();
2021-02-19 18:41:49 -08:00
addMutation.mutate(model);
};
const handleOnDeleteClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>, email: string): void => {
event.stopPropagation();
deleteMutation.mutate(email);
2021-02-19 17:37:55 -08:00
};
const { isLoading, data: permissions = [] } = useQuery<unknown, ErrorInfo, Permission[]>(`perm-${mapId}`, () => {
return client.fetchMapPermissions(mapId);
});
2021-02-16 21:51:59 -08:00
return (
<div>
<BaseDialog
2021-02-19 17:37:55 -08:00
onClose={handleOnClose}
2021-02-17 18:10:45 -08:00
title={intl.formatMessage({ id: "share.delete-title", defaultMessage: "Share with people" })}
2021-02-19 18:41:49 -08:00
description={intl.formatMessage({ id: "share.delete-description", defaultMessage: "Invite people to collaborate with you in the creation of your midnmap. They will be notified by email. " })}
2021-02-19 17:37:55 -08:00
PaperProps={{ classes: { root: classes.paper } }}
error={error}
>
<div className={classes.actionContainer}>
<TextField
id="emails"
name="emails"
required={true}
style={{ width: '300px' }}
size="small"
type="email"
variant="outlined"
2021-02-19 18:41:49 -08:00
placeholder="Add collaborator email"
2021-02-19 17:37:55 -08:00
label="Emails"
onChange={handleOnChange}
value={model.emails}
/>
2021-02-16 21:51:59 -08:00
2021-02-17 18:10:45 -08:00
<Select
variant="outlined"
2021-02-19 17:37:55 -08:00
onChange={handleOnChange}
value={model.role}
name="role"
2021-02-17 18:10:45 -08:00
style={{ margin: '0px 10px' }}
>
2021-02-19 17:37:55 -08:00
<MenuItem value='editor'><FormattedMessage id="share.can-edit" defaultMessage="Can edit" /></MenuItem>
<MenuItem value='viewer'><FormattedMessage id="share.can-view" defaultMessage="Can view" /></MenuItem>
2021-02-17 18:10:45 -08:00
</Select>
2021-02-16 21:51:59 -08:00
2021-02-17 18:10:45 -08:00
<FormControlLabel
value="start"
2021-02-19 17:37:55 -08:00
onChange={(event, value) => { setShowMessage(value) }}
style={{ fontSize: "5px" }}
2021-02-17 18:10:45 -08:00
control={<Checkbox color="primary" />}
2021-02-19 17:37:55 -08:00
label={<Typography variant="subtitle2"><FormattedMessage id="share.add-message" defaultMessage="Add message" /></Typography>}
2021-02-17 18:10:45 -08:00
labelPlacement="end"
2021-02-19 17:37:55 -08:00
/>
<Button
color="primary"
type="button"
variant="contained"
disableElevation={true}
2021-02-19 18:41:49 -08:00
onClick={handleOnAddClick}>
2021-02-19 17:37:55 -08:00
<FormattedMessage id="share.add-button" defaultMessage="Add " />
</Button>
{showMessage &&
<TextField
multiline
rows={3}
rowsMax={3}
className={classes.textArea}
variant="filled"
name="message"
onChange={handleOnChange}
value={model.message}
2021-02-19 18:41:49 -08:00
label={intl.formatMessage({ id: 'share.message', defaultMessage: 'Message' })}
2021-02-17 18:10:45 -08:00
/>
2021-02-19 17:37:55 -08:00
}
2021-02-16 21:51:59 -08:00
</div>
2021-02-19 17:37:55 -08:00
{!isLoading &&
<Paper elevation={1} className={classes.listPaper} variant="outlined">
<List>
{permissions && permissions.map((permission) => {
return (
<ListItem key={permission.email} role={undefined} dense button>
2021-02-19 18:41:49 -08:00
<ListItemText id={permission.email} primary={`${permission.name}<${permission.email}>`} />
2021-02-19 17:37:55 -08:00
<RoleIcon role={permission.role} />
2021-02-19 18:41:49 -08:00
< ListItemSecondaryAction >
<Tooltip title={<FormattedMessage id="share.delete" defaultMessage="Delete collaborator" />}>
<IconButton edge="end" disabled={permission.role == 'owner'} onClick={e => handleOnDeleteClick(e, permission.email)}>
<DeleteIcon />
</IconButton>
</Tooltip>
2021-02-19 17:37:55 -08:00
</ListItemSecondaryAction>
</ListItem>
);
})}
</List>
</Paper>
}
2021-02-16 21:51:59 -08:00
</BaseDialog>
2021-02-17 18:10:45 -08:00
</div >
2021-02-16 21:51:59 -08:00
);
}
export default ShareDialog;