parent
0cf491deee
commit
c57e807904
@ -1,9 +1,17 @@ |
||||
import React from "react"; |
||||
import PropTypes from "prop-types"; |
||||
|
||||
import moment from "moment"; |
||||
|
||||
export default ({ timestamp }) => { |
||||
const Date = ({ timestamp }) => { |
||||
const m = moment(timestamp); |
||||
const shortDate = m.format("L"); |
||||
const fullDate = m.format("LLLL"); |
||||
return <span title={fullDate}>{shortDate}</span>; |
||||
}; |
||||
|
||||
Date.propTypes = { |
||||
timestamp: PropTypes.number.isRequired, |
||||
}; |
||||
|
||||
export default Date; |
@ -1,10 +1,20 @@ |
||||
import React from "react"; |
||||
import PropTypes from "prop-types"; |
||||
|
||||
import Button from "react-bootstrap/Button"; |
||||
|
||||
import "./css/NewItemButton.scss"; |
||||
|
||||
export default ({ onClick, className, t }) => ( |
||||
const NewItemButton = ({ onClick, className, t }) => ( |
||||
<Button variant="primary" {...{ onClick }} title={t("buttonTooltip")}> |
||||
<span className={`NewItemButton ${className}`}>{t("button")}</span> |
||||
</Button> |
||||
); |
||||
|
||||
NewItemButton.propTypes = { |
||||
onClick: PropTypes.func.isRequired, |
||||
className: PropTypes.string.isRequired, |
||||
t: PropTypes.func.isRequired, |
||||
}; |
||||
|
||||
export default NewItemButton; |
@ -1,66 +0,0 @@ |
||||
import React, { useRef, useState } from "react"; |
||||
import { useMutate } from "restful-react"; |
||||
import { useTranslation } from "react-i18next"; |
||||
|
||||
import NewItemModal from "./NewItemModal"; |
||||
import NewUserForm from "./NewUserForm"; |
||||
|
||||
export default ({ modalShow, setModalShow, userList, newUserLocalEcho }) => { |
||||
const { t } = useTranslation("usersTab"); |
||||
|
||||
const [feedback, setFeedback] = useState(null); |
||||
|
||||
const { mutate: post, loading } = useMutate({ |
||||
verb: "POST", |
||||
path: "watcha_register", |
||||
}); |
||||
|
||||
const onSubmit = data => { |
||||
const payload = makePayload(data); |
||||
post(payload) |
||||
.then(response => { |
||||
const user = makeUser(data); |
||||
newUserLocalEcho(user); |
||||
setFeedback({ variant: "success", message: t("success") }); |
||||
}) |
||||
.catch(error => setFeedback({ variant: "danger", message: t("danger") })); |
||||
}; |
||||
|
||||
const onHide = () => { |
||||
setModalShow(false); |
||||
setFeedback(null); |
||||
}; |
||||
|
||||
const submitFormRef = useRef(); |
||||
const bindSubmitForm = submitForm => { |
||||
submitFormRef.current = submitForm; |
||||
}; |
||||
|
||||
return ( |
||||
<NewItemModal |
||||
show={modalShow} |
||||
title={t("button")} |
||||
onSave={() => submitFormRef.current()} |
||||
onClick={() => setFeedback(null)} |
||||
{...{ feedback, loading, onHide }} |
||||
> |
||||
<NewUserForm {...{ userList, onSubmit, bindSubmitForm, feedback }} /> |
||||
</NewItemModal> |
||||
); |
||||
}; |
||||
|
||||
const makePayload = data => ({ |
||||
admin: data.isSynapseAdministrator, |
||||
email: data.emailAddress, |
||||
}); |
||||
|
||||
const makeUser = data => ({ |
||||
userId: _genRandomString(), |
||||
displayName: "", |
||||
emailAddress: data.emailAddress, |
||||
lastSeen: null, |
||||
role: data.isSynapseAdministrator ? "administrator" : "collaborator", |
||||
status: "active", |
||||
}); |
||||
|
||||
const _genRandomString = () => Math.floor(Math.random() * 1000000).toString(); |
@ -0,0 +1,91 @@ |
||||
import React, { useRef, useState } from "react"; |
||||
import PropTypes from "prop-types"; |
||||
|
||||
import { useMutate } from "restful-react"; |
||||
import { useTranslation } from "react-i18next"; |
||||
|
||||
import NewItemModal from "./NewItemModal"; |
||||
import NewUserForm from "./NewUserForm"; |
||||
|
||||
const NewUserModal = ({ modalShow, setModalShow, userList, newUserLocalEcho }) => { |
||||
const { t } = useTranslation("usersTab"); |
||||
|
||||
const [feedback, setFeedback] = useState(null); |
||||
|
||||
const { mutate: post, loading } = useMutate({ |
||||
verb: "POST", |
||||
path: "watcha_register", |
||||
}); |
||||
|
||||
const makePayload = data => ({ |
||||
admin: data.isSynapseAdministrator, |
||||
email: data.emailAddress, |
||||
}); |
||||
|
||||
const genRandomString = () => Math.floor(Math.random() * 1000000).toString(); |
||||
|
||||
const makeUser = data => ({ |
||||
userId: genRandomString(), |
||||
displayName: "", |
||||
emailAddress: data.emailAddress, |
||||
lastSeen: null, |
||||
role: data.isSynapseAdministrator ? "administrator" : "collaborator", |
||||
status: "active", |
||||
}); |
||||
|
||||
const onSubmit = data => { |
||||
const payload = makePayload(data); |
||||
post(payload) |
||||
.then(() => { |
||||
const user = makeUser(data); |
||||
newUserLocalEcho(user); |
||||
setFeedback({ variant: "success", message: t("success") }); |
||||
}) |
||||
.catch(() => setFeedback({ variant: "danger", message: t("danger") })); |
||||
}; |
||||
|
||||
const onHide = () => { |
||||
setModalShow(false); |
||||
setFeedback(null); |
||||
}; |
||||
|
||||
const submitFormRef = useRef(); |
||||
const bindSubmitForm = submitForm => { |
||||
submitFormRef.current = submitForm; |
||||
}; |
||||
|
||||
return ( |
||||
<NewItemModal |
||||
show={modalShow} |
||||
title={t("button")} |
||||
onSave={() => submitFormRef.current()} |
||||
onClick={() => setFeedback(null)} |
||||
{...{ feedback, loading, onHide }} |
||||
> |
||||
<NewUserForm {...{ userList, onSubmit, bindSubmitForm, feedback }} /> |
||||
</NewItemModal> |
||||
); |
||||
}; |
||||
|
||||
NewUserModal.defaultProps = { |
||||
userList: null, |
||||
}; |
||||
|
||||
NewUserModal.propTypes = { |
||||
modalShow: PropTypes.bool.isRequired, |
||||
setModalShow: PropTypes.func.isRequired, |
||||
userList: PropTypes.arrayOf( |
||||
PropTypes.shape({ |
||||
userId: PropTypes.string.isRequired, |
||||
itemId: PropTypes.string, |
||||
displayName: PropTypes.string.isRequired, |
||||
emailAddress: PropTypes.string.isRequired, |
||||
lastSeen: PropTypes.number, |
||||
role: PropTypes.string.isRequired, |
||||
creationTs: PropTypes.number, |
||||
}) |
||||
), |
||||
newUserLocalEcho: PropTypes.func.isRequired, |
||||
}; |
||||
|
||||
export default NewUserModal; |
@ -1,10 +0,0 @@ |
||||
import React from "react"; |
||||
|
||||
import "./css/PanelRow.scss"; |
||||
|
||||
export default ({ label, value }) => ( |
||||
<div className="PanelRow"> |
||||
<div className="PanelRow_label">{label}</div> |
||||
<div className="PanelRow_value">{value}</div> |
||||
</div> |
||||
); |
@ -0,0 +1,22 @@ |
||||
import React from "react"; |
||||
import PropTypes from "prop-types"; |
||||
|
||||
import "./css/PanelRow.scss"; |
||||
|
||||
const PanelRow = ({ label, value }) => ( |
||||
<div className="PanelRow"> |
||||
<div className="PanelRow_label">{label}</div> |
||||
<div className="PanelRow_value">{value}</div> |
||||
</div> |
||||
); |
||||
|
||||
PanelRow.defaultProps = { |
||||
value: "", |
||||
}; |
||||
|
||||
PanelRow.propTypes = { |
||||
label: PropTypes.node.isRequired, |
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), |
||||
}; |
||||
|
||||
export default PanelRow; |
@ -1,5 +0,0 @@ |
||||
import React from "react"; |
||||
|
||||
import "./css/Status.scss"; |
||||
|
||||
export default ({ status, t }) => <span className={`Status ${status}`} title={t(`status.${status}`)} />; |
@ -0,0 +1,13 @@ |
||||
import React from "react"; |
||||
import PropTypes from "prop-types"; |
||||
|
||||
import "./css/Status.scss"; |
||||
|
||||
const Status = ({ status, t }) => <span className={`Status ${status}`} title={t(`status.${status}`)} />; |
||||
|
||||
Status.propTypes = { |
||||
status: PropTypes.string.isRequired, |
||||
t: PropTypes.func.isRequired, |
||||
}; |
||||
|
||||
export default Status; |
Loading…
Reference in new issue