UNPKG

stitch-ui

Version:

262 lines (257 loc) 8.3 kB
import React from "react"; // eslint-disable-line no-unused-vars import PropTypes from "prop-types"; import Modal from "react-modal"; import { Map } from "immutable"; import { Banner, Tooltip, Button, FormRow, FormRowInputGroup, FormRowLabelGroup } from "../../core"; import { PUSH_SAVE_ALERTKEY, SAVE_TYPE_DRAFT, SAVE_TYPE_SENT, FIELD_TEXT, FIELD_LABEL, FIELD_TOPIC, ALERT_TTL_MS } from "../constants"; class MessageEditor extends React.Component { static makeTopicPipeline(topicName, body) { return [ { service: "gcm", action: "send", args: { to: `/topics/${topicName}`, notification: { body } } } ]; } constructor(props) { super(props); this.saveDraft = this.saveDraft.bind(this); this.sendMessage = this.sendMessage.bind(this); } saveDraft(msg) { let p; if (this.props.editingMessageId) { // We're editing an existing message; just update the existing message data using its _id p = this.props.saveMessage(this.props.editingMessageId, { message: msg.get(FIELD_TEXT), label: msg.get(FIELD_LABEL), topic: msg.get(FIELD_TOPIC), type: SAVE_TYPE_DRAFT }); } else { // This is a new message that has not been saved yet, create it in the "Draft" state p = this.props.createMessage({ message: msg.get(FIELD_TEXT), label: msg.get(FIELD_LABEL), topic: msg.get(FIELD_TOPIC), type: SAVE_TYPE_DRAFT }); } return p .then(this.props.onClose) .then(() => this.props.addAlert( PUSH_SAVE_ALERTKEY, "Message has been saved as draft." ) ) .then(this.props.reloadList); } sendMessage(msg) { let p; let messageId = this.props.editingMessageId; if (this.props.editingMessageId) { p = this.props.saveMessage(this.props.editingMessageId, { message: msg.get(FIELD_TEXT), label: msg.get(FIELD_LABEL), topic: msg.get(FIELD_TOPIC), type: SAVE_TYPE_DRAFT }); } else { p = this.props .createMessage({ message: msg.get(FIELD_TEXT), label: msg.get(FIELD_LABEL), topic: msg.get(FIELD_TOPIC), type: SAVE_TYPE_DRAFT }) .then(m => { messageId = m._id; }); } return p .then(() => this.props.executePushPipeline( MessageEditor.makeTopicPipeline( msg.get(FIELD_TOPIC), msg.get(FIELD_TEXT) ), null, { systemUser: "1" } ) ) .then(this.props.onClose) .then(() => this.props.addAlert(PUSH_SAVE_ALERTKEY, "Message has been sent.", { timeout: ALERT_TTL_MS }) ) .then(() => this.props.setMessageStatus(messageId, SAVE_TYPE_SENT)) .then(() => this.props.reloadList()); } render() { const { error, newMessage, open, onClose, setNewMessageText, setNewMessageTopic, setNewMessageLabel } = this.props; return ( <Modal ref={ref => (this.modal = ref)} isOpen={open} onRequestClose={onClose} contentLabel="Send Message" className="view-modal-dialog" overlayClassName="view-modal-overlay" > <div className="view-modal-content"> <div className="view-modal-header"> <button className="button view-modal-close" onClick={onClose}> × </button> <h2 className="view-modal-title">New Push Notification</h2> </div> <div className="view-modal-body"> <Banner message={error} error /> <FormRow> <FormRowLabelGroup> <label htmlFor="message" className="form-row-label"> Message <Tooltip dataFor="tooltip-message" place="top" classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary" effect="float" > This is the content of your push notification. </Tooltip> </label> </FormRowLabelGroup> <FormRowInputGroup> <input type="text" name="message" className="text-input form-row-text-input" placeholder="Message" value={newMessage.get(FIELD_TEXT) || ""} onChange={e => setNewMessageText(e.target.value)} /> </FormRowInputGroup> </FormRow> <FormRow> <FormRowLabelGroup> <label htmlFor="label" className="form-row-label"> Message Label <Tooltip dataFor="tooltip-message-label" place="top" classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary" effect="float" > This is used to identify notifications in Stitch. This is not shown to your users. </Tooltip> </label> </FormRowLabelGroup> <FormRowInputGroup> <input type="text" name="label" className="text-input form-row-text-input" placeholder="Label" value={newMessage.get(FIELD_LABEL) || ""} onChange={e => setNewMessageLabel(e.target.value)} /> </FormRowInputGroup> </FormRow> <FormRow last> <FormRowLabelGroup> <label htmlFor="topic" className="form-row-label"> Topic <Tooltip dataFor="tooltip-topic" place="top" classNames="tooltip-indicator tooltip-indicator-small tooltip-indicator-secondary" effect="float" > This is a pub/sub pattern to send notifications to subscribers of this topic. </Tooltip> </label> </FormRowLabelGroup> <FormRowInputGroup> <input type="text" name="topic" className="text-input form-row-text-input" placeholder="Topic" value={newMessage.get("topic") || ""} onChange={e => setNewMessageTopic(e.target.value)} /> </FormRowInputGroup> </FormRow> <footer className="view-modal-footer"> <div className="view-modal-actions tabs-content-actions"> <div className="tabs-content-actions-left"> <Button onClick={onClose}>Cancel</Button> </div> <div className="tabs-content-actions-right"> <Button onClick={() => this.saveDraft(newMessage)}> Save Draft </Button> <Button primary onClick={() => this.sendMessage(newMessage)}> Send Message </Button> </div> </div> </footer> </div> </div> </Modal> ); } } MessageEditor.propTypes = { addAlert: PropTypes.func.isRequired, createMessage: PropTypes.func.isRequired, editingMessageId: PropTypes.string, error: PropTypes.string, executePushPipeline: PropTypes.func.isRequired, newMessage: PropTypes.instanceOf(Map).isRequired, onClose: PropTypes.func.isRequired, open: PropTypes.bool.isRequired, reloadList: PropTypes.func.isRequired, saveMessage: PropTypes.func.isRequired, setMessageStatus: PropTypes.func.isRequired, setNewMessageLabel: PropTypes.func.isRequired, setNewMessageText: PropTypes.func.isRequired, setNewMessageTopic: PropTypes.func.isRequired }; MessageEditor.defaultProps = { editingMessageId: null, error: null }; export default MessageEditor;