-
-
-
-
Removed from {channelName}
+
+
+
+
+
+
Removed from {channelName}
+
+
+
{remover} removed you from {channelName}
+
+
+
+
-
-
{remover} removed you from {channelName}
-
-
-
-
-
-
+
);
- } else {
- return
;
}
+
+ return
;
}
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/web/react/components/rhs_thread.jsx b/web/react/components/rhs_thread.jsx
index adddeccf07..dbb16872e6 100644
--- a/web/react/components/rhs_thread.jsx
+++ b/web/react/components/rhs_thread.jsx
@@ -33,7 +33,9 @@ export default class RhsThread extends React.Component {
if (pendingPostList) {
for (var pid in pendingPostList.posts) {
- postList.posts[pid] = pendingPostList.posts[pid];
+ if (pendingPostList.posts.hasOwnProperty(pid)) {
+ postList.posts[pid] = pendingPostList.posts[pid];
+ }
}
}
@@ -81,7 +83,9 @@ export default class RhsThread extends React.Component {
if (currentPosts.posts[currentPosts.order[0]].channel_id === currentSelected.posts[currentSelected.order[0]].channel_id) {
currentSelected.posts = {};
for (var postId in currentPosts.posts) {
- currentSelected.posts[postId] = currentPosts.posts[postId];
+ if (currentPosts.posts.hasOwnProperty(postId)) {
+ currentSelected.posts[postId] = currentPosts.posts[postId];
+ }
}
PostStore.storeSelectedPost(currentSelected);
@@ -128,9 +132,11 @@ export default class RhsThread extends React.Component {
var postsArray = [];
for (var postId in postList.posts) {
- var cpost = postList.posts[postId];
- if (cpost.root_id === rootPost.id) {
- postsArray.push(cpost);
+ if (postList.posts.hasOwnProperty(postId)) {
+ var cpost = postList.posts[postId];
+ if (cpost.root_id === rootPost.id) {
+ postsArray.push(cpost);
+ }
}
}
@@ -209,6 +215,7 @@ RhsThread.defaultProps = {
fromSearch: '',
isMentionSearch: false
};
+
RhsThread.propTypes = {
fromSearch: React.PropTypes.string,
isMentionSearch: React.PropTypes.bool
diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx
index 5b12ad7e9e..eaa8397337 100644
--- a/web/react/components/setting_picture.jsx
+++ b/web/react/components/setting_picture.jsx
@@ -1,25 +1,33 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
-module.exports = React.createClass({
- setPicture: function(file) {
+export default class SettingPicture extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.setPicture = this.setPicture.bind(this);
+ }
+
+ setPicture(file) {
if (file) {
var reader = new FileReader();
var img = this.refs.image.getDOMNode();
- reader.onload = function(e) {
+ reader.onload = function load(e) {
$(img).attr('src', e.target.result);
};
reader.readAsDataURL(file);
}
- },
- componentWillReceiveProps: function(nextProps) {
+ }
+
+ componentWillReceiveProps(nextProps) {
if (nextProps.picture) {
this.setPicture(nextProps.picture);
}
- },
- render: function() {
+ }
+
+ render() {
var clientError = null;
if (this.props.client_error) {
clientError =
;
@@ -31,14 +39,31 @@ module.exports = React.createClass({
var img = null;
if (this.props.picture) {
- img = (
![]()
);
+ img = (
+
![]()
+ );
} else {
- img = (

);
+ img = (
+

+ );
}
var confirmButton;
if (this.props.loadingPicture) {
- confirmButton =

;
+ confirmButton = (
+

+ );
} else {
var confirmButtonClass = 'btn btn-sm';
if (this.props.submitActive) {
@@ -46,9 +71,15 @@ module.exports = React.createClass({
} else {
confirmButtonClass += ' btn-inactive disabled';
}
- confirmButton =
Save;
+
+ confirmButton = (
+
Save
+ );
}
- var helpText = 'Upload a profile picture in either JPG or PNG format, at least ' + config.ProfileWidth + 'px in width and ' + config.ProfileHeight + 'px height.'
+ var helpText = 'Upload a profile picture in either JPG or PNG format, at least ' + config.ProfileWidth + 'px in width and ' + config.ProfileHeight + 'px height.';
var self = this;
return (
@@ -65,13 +96,36 @@ module.exports = React.createClass({
{serverError}
{clientError}
- Select
+ Select
+
{confirmButton}
- Cancel
+ Cancel
);
}
-});
+}
+
+SettingPicture.propTypes = {
+ client_error: React.PropTypes.string,
+ server_error: React.PropTypes.string,
+ src: React.PropTypes.string,
+ picture: React.PropTypes.object,
+ loadingPicture: React.PropTypes.bool,
+ submitActive: React.PropTypes.bool,
+ submit: React.PropTypes.func,
+ title: React.PropTypes.string,
+ pictureChange: React.PropTypes.func
+};
\ No newline at end of file
diff --git a/web/react/components/setting_upload.jsx b/web/react/components/setting_upload.jsx
index 5963243080..a7ab03018c 100644
--- a/web/react/components/setting_upload.jsx
+++ b/web/react/components/setting_upload.jsx
@@ -1,36 +1,37 @@
// 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,
- helpText: React.PropTypes.string
- },
- getInitialState: function() {
- return {
+export default class SettingsUpload extends React.Component {
+
+ constructor(props) {
+ super(props);
+
+ this.doFileSelect = this.doFileSelect.bind(this);
+ this.doSubmit = this.doSubmit.bind(this);
+ this.onFileSelect = this.onFileSelect.bind(this);
+
+ this.state = {
clientError: this.props.clientError,
serverError: this.props.serverError
};
- },
- componentWillReceiveProps: function() {
+ }
+
+ componentWillReceiveProps() {
this.setState({
clientError: this.props.clientError,
serverError: this.props.serverError
});
- },
- doFileSelect: function(e) {
+ }
+
+ doFileSelect(e) {
e.preventDefault();
this.setState({
clientError: '',
serverError: ''
});
- },
- doSubmit: function(e) {
+ }
+
+ doSubmit(e) {
e.preventDefault();
var inputnode = this.refs.uploadinput.getDOMNode();
if (inputnode.files && inputnode.files[0]) {
@@ -38,16 +39,18 @@ module.exports = React.createClass({
} else {
this.setState({clientError: 'No file selected.'});
}
- },
- onFileSelect: function(e) {
+ }
+
+ onFileSelect(e) {
var filename = $(e.target).val();
if (filename.substring(3, 11) === 'fakepath') {
filename = filename.substring(12);
}
$(e.target).closest('li').find('.file-status').addClass('hide');
$(e.target).closest('li').find('.file-name').removeClass('hide').html(filename);
- },
- render: function() {
+ }
+
+ render() {
var clientError = null;
if (this.state.clientError) {
clientError = (
@@ -67,7 +70,11 @@ module.exports = React.createClass({
);
}
-});
+}
+
+SettingsUpload.propTypes = {
+ title: React.PropTypes.string.isRequired,
+ submit: React.PropTypes.func.isRequired,
+ fileTypesAccepted: React.PropTypes.string.isRequired,
+ clientError: React.PropTypes.string,
+ serverError: React.PropTypes.string,
+ helpText: React.PropTypes.object
+};
\ No newline at end of file
diff --git a/web/react/components/sidebar_right_menu.jsx b/web/react/components/sidebar_right_menu.jsx
index 615bc4ef2a..fea889b338 100644
--- a/web/react/components/sidebar_right_menu.jsx
+++ b/web/react/components/sidebar_right_menu.jsx
@@ -5,12 +5,19 @@ var UserStore = require('../stores/user_store.jsx');
var client = require('../utils/client.jsx');
var utils = require('../utils/utils.jsx');
-module.exports = React.createClass({
- handleLogoutClick: function(e) {
+export default class SidebarRightMenu extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.handleLogoutClick = this.handleLogoutClick.bind(this);
+ }
+
+ handleLogoutClick(e) {
e.preventDefault();
client.logout();
- },
- render: function() {
+ }
+
+ render() {
var teamLink = '';
var inviteLink = '';
var teamSettingsLink = '';
@@ -23,14 +30,22 @@ module.exports = React.createClass({
inviteLink = (
- Invite New Member
+ Invite New Member
);
if (this.props.teamType === 'O') {
teamLink = (
- Get Team Invite Link
+ Get Team Invite Link
);
}
@@ -39,12 +54,20 @@ module.exports = React.createClass({
if (isAdmin) {
teamSettingsLink = (
- Team Settings
+ Team Settings
);
manageLink = (
- Manage Team
+ Manage Team
);
}
@@ -61,23 +84,48 @@ module.exports = React.createClass({
return (
);
}
-});
+}
+
+SidebarRightMenu.propTypes = {
+ teamType: React.PropTypes.string,
+ teamDisplayName: React.PropTypes.string
+};
\ No newline at end of file
diff --git a/web/react/components/team_import_tab.jsx b/web/react/components/team_import_tab.jsx
index e3415d7f44..627ff85f4b 100644
--- a/web/react/components/team_import_tab.jsx
+++ b/web/react/components/team_import_tab.jsx
@@ -4,26 +4,38 @@
var utils = require('../utils/utils.jsx');
var SettingUpload = require('./setting_upload.jsx');
-module.exports = React.createClass({
- displayName: 'Import Tab',
- getInitialState: function() {
- return {status: 'ready', link: ''};
- },
- onImportFailure: function() {
+export default class TeamImportTab extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.onImportFailure = this.onImportFailure.bind(this);
+ this.onImportSuccess = this.onImportSuccess.bind(this);
+ this.doImportSlack = this.doImportSlack.bind(this);
+
+ this.state = {
+ status: 'ready',
+ link: ''
+ };
+ }
+
+ onImportFailure() {
this.setState({status: 'fail', link: ''});
- },
- onImportSuccess: function(data) {
+ }
+
+ onImportSuccess(data) {
this.setState({status: 'done', link: 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(data)});
- },
- doImportSlack: function(file) {
+ }
+
+ doImportSlack(file) {
this.setState({status: 'in-progress', link: ''});
utils.importSlack(file, this.onImportSuccess, this.onImportFailure);
- },
- render: function() {
+ }
+
+ render() {
var uploadHelpText = (
- Slack does not allow you to export files, images, private groups or direct messages stored in Slack. Therefore, Slack import to Mattermost only supports importing of text messages in your Slack team's public channels.
+ Slack does not allow you to export files, images, private groups or direct messages stored in Slack. Therefore, Slack import to Mattermost only supports importing of text messages in your Slack team's public channels.
The Slack import to Mattermost is in "Preview". Slack bot posts and channels with underscores do not yet import.
@@ -39,22 +51,25 @@ module.exports = React.createClass({
var messageSection;
switch (this.state.status) {
- case 'ready':
- messageSection = '';
+
+ case 'ready':
+ messageSection = '';
break;
- case 'in-progress':
- messageSection = (
-
Importing...
+ case 'in-progress':
+ messageSection = (
+
Importing...
);
break;
- case 'done':
- messageSection = (
-
Import successful: View Summary
+ case 'done':
+ messageSection = (
+
Import successful: View Summary
);
break;
- case 'fail':
- messageSection = (
-
Import failure: View Summary
+ case 'fail':
+ messageSection = (
+
Import failure: View Summary
);
break;
}
@@ -62,10 +77,22 @@ module.exports = React.createClass({
return (
-
-
Import
+
+ Import
-
+
Import
{uploadSection}
@@ -75,4 +102,4 @@ module.exports = React.createClass({
);
}
-});
+}
diff --git a/web/react/components/team_members.jsx b/web/react/components/team_members.jsx
index 616fd2c995..86c321d06c 100644
--- a/web/react/components/team_members.jsx
+++ b/web/react/components/team_members.jsx
@@ -2,77 +2,131 @@
// See License.txt for license information.
var UserStore = require('../stores/user_store.jsx');
-var ChannelStore = require('../stores/channel_store.jsx');
var MemberListTeam = require('./member_list_team.jsx');
-var Client = require('../utils/client.jsx');
var utils = require('../utils/utils.jsx');
function getStateFromStores() {
var users = UserStore.getProfiles();
- var member_list = [];
- for (var id in users) member_list.push(users[id]);
+ var memberList = [];
+ for (var id in users) {
+ if (users.hasOwnProperty(id)) {
+ memberList.push(users[id]);
+ }
+ }
+
+ memberList.sort(function sort(a, b) {
+ if (a.username < b.username) {
+ return -1;
+ }
+
+ if (a.username > b.username) {
+ return 1;
+ }
- member_list.sort(function(a,b) {
- if (a.username < b.username) return -1;
- if (a.username > b.username) return 1;
return 0;
});
return {
- member_list: member_list
+ member_list: memberList
};
}
-module.exports = React.createClass({
- componentDidMount: function() {
- UserStore.addChangeListener(this._onChange);
+export default class TeamMembers extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.onChange = this.onChange.bind(this);
+
+ this.state = getStateFromStores();
+ }
+
+ componentDidMount() {
+ UserStore.addChangeListener(this.onChange);
var self = this;
- $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) {
- self.setState({ render_members: false });
+ $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function show() {
+ self.setState({render_members: false});
});
- $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
- self.setState({ render_members: true });
+ $(this.refs.modal.getDOMNode()).on('show.bs.modal', function hide() {
+ self.setState({render_members: true});
});
- },
- componentWillUnmount: function() {
- UserStore.removeChangeListener(this._onChange);
- },
- _onChange: function() {
+ }
+
+ componentWillUnmount() {
+ UserStore.removeChangeListener(this.onChange);
+ }
+
+ onChange() {
var newState = getStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
- },
- getInitialState: function() {
- return getStateFromStores();
- },
- render: function() {
- var server_error = this.state.server_error ?
: null;
+ }
+
+ render() {
+ var serverError = null;
+
+ if (this.state.server_error) {
+ serverError =
;
+ }
+
+ var renderMembers = '';
+
+ if (this.state.render_members) {
+ renderMembers =
;
+ }
return (
-
-
-
-
-
-
{this.props.teamDisplayName + " Members"}
-
-
-
-
- { this.state.render_members ?
: "" }
+
+
+
+
+
+
{this.props.teamDisplayName + ' Members'}
+
+
+
+
+ {renderMembers}
+
+ {serverError}
- { server_error }
+
+
+
-
-
-
-
);
}
-});
+}
+
+TeamMembers.propTypes = {
+ teamDisplayName: React.PropTypes.string
+};
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index 9b0e906c52..282fb76813 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -8,56 +8,82 @@ var SecurityTab = require('./user_settings_security.jsx');
var GeneralTab = require('./user_settings_general.jsx');
var AppearanceTab = require('./user_settings_appearance.jsx');
-module.exports = React.createClass({
- displayName: 'UserSettings',
- propTypes: {
- activeTab: React.PropTypes.string,
- activeSection: React.PropTypes.string,
- updateSection: React.PropTypes.func,
- updateTab: React.PropTypes.func
- },
- componentDidMount: function() {
+export default class UserSettings extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.onListenerChange = this.onListenerChange.bind(this);
+
+ this.state = {user: UserStore.getCurrentUser()};
+ }
+
+ componentDidMount() {
UserStore.addChangeListener(this.onListenerChange);
- },
- componentWillUnmount: function() {
+ }
+
+ componentWillUnmount() {
UserStore.removeChangeListener(this.onListenerChange);
- },
- onListenerChange: function () {
+ }
+
+ onListenerChange() {
var user = UserStore.getCurrentUser();
if (!utils.areStatesEqual(this.state.user, user)) {
this.setState({user: user});
}
- },
- getInitialState: function() {
- return {user: UserStore.getCurrentUser()};
- },
- render: function() {
+ }
+
+ render() {
if (this.props.activeTab === 'general') {
return (
-
+
);
} else if (this.props.activeTab === 'security') {
return (
-
+
);
} else if (this.props.activeTab === 'notifications') {
return (
-
+
);
} else if (this.props.activeTab === 'appearance') {
return (
);
- } else {
- return
;
}
+
+ return
;
}
-});
+}
+
+UserSettings.propTypes = {
+ activeTab: React.PropTypes.string,
+ activeSection: React.PropTypes.string,
+ updateSection: React.PropTypes.func,
+ updateTab: React.PropTypes.func
+};
\ No newline at end of file