diff options
Diffstat (limited to 'web/react')
-rw-r--r-- | web/react/components/setting_upload.jsx | 79 | ||||
-rw-r--r-- | web/react/components/team_settings.jsx | 72 | ||||
-rw-r--r-- | web/react/components/team_settings_modal.jsx | 1 | ||||
-rw-r--r-- | web/react/utils/client.jsx | 16 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 9 |
5 files changed, 176 insertions, 1 deletions
diff --git a/web/react/components/setting_upload.jsx b/web/react/components/setting_upload.jsx new file mode 100644 index 000000000..870710850 --- /dev/null +++ b/web/react/components/setting_upload.jsx @@ -0,0 +1,79 @@ +// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. +// See License.txt for license information. + +module.exports = React.createClass({ + displayName: 'Setting Upload', + propTypes: { + title: React.PropTypes.string.isRequired, + submit: React.PropTypes.func.isRequired, + fileTypesAccepted: React.PropTypes.string.isRequired, + clientError: React.PropTypes.string, + serverError: React.PropTypes.string + }, + getInitialState: function() { + return { + clientError: this.props.clientError, + serverError: this.props.serverError + }; + }, + componentWillReceiveProps: function() { + this.setState({ + clientError: this.props.clientError, + serverError: this.props.serverError + }); + }, + doFileSelect: function(e) { + e.preventDefault(); + this.setState({ + clientError: '', + serverError: '' + }); + }, + doSubmit: function(e) { + e.preventDefault(); + var inputnode = this.refs.uploadinput.getDOMNode(); + if (inputnode.files && inputnode.files[0]) { + this.props.submit(inputnode.files[0]); + } else { + this.setState({clientError: 'No file selected.'}); + } + }, + doCancel: function(e) { + e.preventDefault(); + this.refs.uploadinput.getDOMNode().value = ''; + this.setState({ + clientError: '', + serverError: '' + }); + }, + render: function() { + var clientError = null; + if (this.state.clientError) { + clientError = ( + <div className='form-group has-error'><label className='control-label'>{this.state.clientError}</label></div> + ); + } + var serverError = null; + if (this.state.serverError) { + serverError = ( + <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div> + ); + } + return ( + <ul className='section-max'> + <li className='col-xs-12 section-title'>{this.props.title}</li> + <li className='col-xs-offset-3 col-xs-8'> + <ul className='setting-list'> + <li className='setting-list-item'> + {serverError} + {clientError} + <span className='btn btn-sm btn-primary btn-file sel-btn'>SelectFile<input ref='uploadinput' accept={this.props.fileTypesAccepted} type='file' onChange={this.onFileSelect}/></span> + <a className={'btn btn-sm btn-primary'} onClick={this.doSubmit}>Import</a> + <a className='btn btn-sm theme' href='#' onClick={this.doCancel}>Cancel</a> + </li> + </ul> + </li> + </ul> + ); + } +}); diff --git a/web/react/components/team_settings.jsx b/web/react/components/team_settings.jsx index 3bbb5e892..433ec9177 100644 --- a/web/react/components/team_settings.jsx +++ b/web/react/components/team_settings.jsx @@ -6,6 +6,7 @@ var TeamStore = require('../stores/team_store.jsx'); var SettingItemMin = require('./setting_item_min.jsx'); var SettingItemMax = require('./setting_item_max.jsx'); var SettingPicture = require('./setting_picture.jsx'); +var SettingUpload = require('./setting_upload.jsx'); var utils = require('../utils/utils.jsx'); var client = require('../utils/client.jsx'); @@ -126,6 +127,69 @@ var FeatureTab = React.createClass({ } }); +var ImportTab = React.createClass({ + getInitialState: function() { + return {status: 'ready'}; + }, + onImportFailure: function() { + this.setState({status: 'fail'}); + }, + onImportSuccess: function(data) { + this.setState({status: 'done'}); + }, + doImportSlack: function(file) { + this.setState({status: 'in-progress'}); + utils.importSlack(file, this.onImportSuccess, this.onImportFailure); + }, + render: function() { + + uploadSection = ( + <SettingUpload + title="Import from Slack" + submit={this.doImportSlack} + fileTypesAccepted='.zip'/> + ); + + var messageSection; + switch (this.state.status) { + case 'ready': + messageSection = ''; + break; + case 'in-progress': + messageSection = ( + <p>Importing...</p> + ); + break; + case 'done': + messageSection = ( + <p>Import sucessfull: <a href={this.state.link} download='MattermostImportSummery.txt'>View Summery</a></p> + ); + break; + case 'fail': + messageSection = ( + <p>Import failure: <a href={this.state.link} download='MattermostImportSummery.txt'>View Summery</a></p> + ); + break; + } + + return ( + <div> + <div className="modal-header"> + <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 className="modal-title" ref="title"><i className="modal-back"></i>Import</h4> + </div> + <div ref="wrapper" className="user-settings"> + <h3 className="tab-header">Import</h3> + <div className="divider-dark first"/> + {uploadSection} + {messageSection} + <div className="divider-dark"/> + </div> + </div> + ); + } +}); + module.exports = React.createClass({ componentDidMount: function() { TeamStore.addChangeListener(this._onChange); @@ -154,7 +218,13 @@ module.exports = React.createClass({ <FeatureTab team={this.state.team} activeSection={this.props.activeSection} updateSection={this.props.updateSection} /> </div> ); - } else { + } else if (this.props.activeTab === 'import') { + return ( + <div> + <ImportTab team={this.state.team} activeSection={this.props.activeSection} updateSection={this.props.updateSection} /> + </div> + ); + } else { return <div/>; } } diff --git a/web/react/components/team_settings_modal.jsx b/web/react/components/team_settings_modal.jsx index b1c38fd16..f935daf82 100644 --- a/web/react/components/team_settings_modal.jsx +++ b/web/react/components/team_settings_modal.jsx @@ -27,6 +27,7 @@ module.exports = React.createClass({ render: function() { var tabs = []; tabs.push({name: "feature", ui_name: "Features", icon: "glyphicon glyphicon-wrench"}); + tabs.push({name: "import", ui_name: "Import", icon: "glyphicon glyphicon-upload"}); return ( <div className="modal fade" ref="modal" id="team_settings" role="dialog" tabIndex="-1" aria-hidden="true"> diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx index da0b74081..f4c72ba46 100644 --- a/web/react/utils/client.jsx +++ b/web/react/utils/client.jsx @@ -862,6 +862,22 @@ module.exports.uploadProfileImage = function(imageData, success, error) { }); }; +module.exports.importSlack = function(fileData, success, error) { + $.ajax({ + url: "/api/v1/teams/import_team", + type: 'POST', + data: fileData, + cache: false, + contentType: false, + processData: false, + success: success, + error: function(xhr, status, err) { + e = handleError("importTeam", xhr, status, err); + error(e); + } + }); +} + module.exports.getStatuses = function(success, error) { $.ajax({ url: "/api/v1/users/status", diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 618cc1557..f0a343513 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -982,3 +982,12 @@ module.exports.getUserIdFromChannelName = function(channel) { return otherUserId; }; + +module.exports.importSlack = function(file, success, error) { + formData = new FormData(); + formData.append('file', file, file.name); + formData.append('filesize', file.size); + formData.append('importFrom', 'slack'); + + client.importSlack(formData, success, error); +}; |