diff --git a/model/incoming_webhook.go b/model/incoming_webhook.go index 4ebc7e8b10..de58093ff1 100644 --- a/model/incoming_webhook.go +++ b/model/incoming_webhook.go @@ -7,6 +7,7 @@ import ( "bytes" "encoding/json" "io" + "net/http" "regexp" ) @@ -79,35 +80,36 @@ func IncomingWebhookListFromJson(data io.Reader) []*IncomingWebhook { func (o *IncomingWebhook) IsValid() *AppError { if len(o.Id) != 26 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.id.app_error", nil, "") + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.id.app_error", nil, "", http.StatusBadRequest) + } if o.CreateAt == 0 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.create_at.app_error", nil, "id="+o.Id) + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) } if o.UpdateAt == 0 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.update_at.app_error", nil, "id="+o.Id) + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) } if len(o.UserId) != 26 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.user_id.app_error", nil, "") + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.user_id.app_error", nil, "", http.StatusBadRequest) } if len(o.ChannelId) != 26 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.channel_id.app_error", nil, "") + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.channel_id.app_error", nil, "", http.StatusBadRequest) } if len(o.TeamId) != 26 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "") + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "", http.StatusBadRequest) } if len(o.DisplayName) > 64 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.display_name.app_error", nil, "") + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.display_name.app_error", nil, "", http.StatusBadRequest) } if len(o.Description) > 128 { - return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.description.app_error", nil, "") + return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.description.app_error", nil, "", http.StatusBadRequest) } return nil diff --git a/webapp/components/integrations/components/abstract_incoming_webhook.jsx b/webapp/components/integrations/components/abstract_incoming_webhook.jsx index a75c29fac3..1253842a78 100644 --- a/webapp/components/integrations/components/abstract_incoming_webhook.jsx +++ b/webapp/components/integrations/components/abstract_incoming_webhook.jsx @@ -12,48 +12,57 @@ import SpinnerButton from 'components/spinner_button.jsx'; import {Link} from 'react-router/es6'; export default class AbstractIncomingWebhook extends React.Component { - static get propTypes() { - return { - team: PropTypes.object - }; + static propTypes = { + + /** + * The current team + */ + team: PropTypes.object.isRequired, + + /** + * The header text to render, has id and defaultMessage + */ + header: PropTypes.object.isRequired, + + /** + * The footer text to render, has id and defaultMessage + */ + footer: PropTypes.object.isRequired, + + /** + * The server error text after a failed action + */ + serverError: PropTypes.string.isRequired, + + /** + * The hook used to set the initial state + */ + initialHook: PropTypes.object, + + /** + * The async function to run when the action button is pressed + */ + action: PropTypes.func.isRequired } constructor(props) { super(props); - this.handleSubmit = this.handleSubmit.bind(this); + this.state = this.getStateFromHook(this.props.initialHook || {}); + } - this.updateDisplayName = this.updateDisplayName.bind(this); - this.updateDescription = this.updateDescription.bind(this); - this.updateChannelId = this.updateChannelId.bind(this); - - this.state = { - displayName: '', - description: '', - channelId: '', + getStateFromHook = (hook) => { + return { + displayName: hook.display_name || '', + description: hook.description || '', + channelId: hook.channel_id || '', saving: false, serverError: '', clientError: null }; - - if (typeof this.performAction === 'undefined') { - throw new TypeError('Subclasses must override performAction'); - } - - if (typeof this.header === 'undefined') { - throw new TypeError('Subclasses must override header'); - } - - if (typeof this.footer === 'undefined') { - throw new TypeError('Subclasses must override footer'); - } - - this.performAction = this.performAction.bind(this); - this.header = this.header.bind(this); - this.footer = this.footer.bind(this); } - handleSubmit(e) { + handleSubmit = (e) => { e.preventDefault(); if (this.state.saving) { @@ -86,30 +95,31 @@ export default class AbstractIncomingWebhook extends React.Component { description: this.state.description }; - this.performAction(hook); + this.props.action(hook).then(() => this.setState({saving: false})); } - updateDisplayName(e) { + updateDisplayName = (e) => { this.setState({ displayName: e.target.value }); } - updateDescription(e) { + updateDescription = (e) => { this.setState({ description: e.target.value }); } - updateChannelId(e) { + updateChannelId = (e) => { this.setState({ channelId: e.target.value }); } render() { - var headerToRender = this.header(); - var footerToRender = this.footer(); + var headerToRender = this.props.header; + var footerToRender = this.props.footer; + return (