Merge branch 'release-3.1'
Conflicts: webapp/components/create_comment.jsx
Этот коммит содержится в:
@@ -239,6 +239,22 @@ export default class AdminSidebar extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
let customBranding = null;
|
||||
|
||||
if (window.mm_license.IsLicensed === 'true') {
|
||||
customBranding = (
|
||||
<AdminSidebarSection
|
||||
name='custom_brand'
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='admin.sidebar.customBrand'
|
||||
defaultMessage='Custom Branding'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='admin-sidebar'>
|
||||
<AdminSidebarHeader/>
|
||||
@@ -515,16 +531,7 @@ export default class AdminSidebar extends React.Component {
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdminSidebarSection
|
||||
name='custom_brand'
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='admin.sidebar.customBrand'
|
||||
defaultMessage='Custom Branding'
|
||||
/>
|
||||
|
||||
}
|
||||
/>
|
||||
{customBranding}
|
||||
<AdminSidebarSection
|
||||
name='legal_and_support'
|
||||
title={
|
||||
|
||||
@@ -343,7 +343,7 @@ export default class LdapSettings extends AdminSettings {
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.ldap.syncIntervalHelpText'
|
||||
defaultMessage='LDAP Synchronization is the process by which Mattermost updates its users to reflect any updated data on the LDAP server. For example if a name for a user is updated on the LDAP server, the change will be reflected in Mattermost when the synchronization is performed. Accounts that have been removed from the LDAP server will have their active sessions cleared and no longer be able to login to Mattermost. Mattermost will perform this synchronization regularly according to the interval supplied here. For example, if 60 is supplied, Mattermost will update the users every hour.'
|
||||
defaultMessage='LDAP Synchronization is the process by which Mattermost updates its users to reflect any updated data on the LDAP server. For example if a name for a user is updated on the LDAP server, the change will be reflected in Mattermost when the synchronization is performed. Accounts that have been removed from the LDAP server will have their active sessions cleared and no longer be able to login to Mattermost. Mattermost will perform this synchronization regularly according to the interval supplied here. For example, if 60 is supplied, Mattermost will update the users every hour. Changing this will require a server restart before taking effect.'
|
||||
/>
|
||||
}
|
||||
value={this.state.syncIntervalMinutes}
|
||||
|
||||
@@ -50,6 +50,7 @@ export default class MultiSelectSetting extends React.Component {
|
||||
labelKey='text'
|
||||
options={this.props.values}
|
||||
joinValues={true}
|
||||
clearable={false}
|
||||
disabled={this.props.disabled}
|
||||
noResultsText={this.props.noResultText}
|
||||
onChange={this.handleChange}
|
||||
|
||||
@@ -22,8 +22,8 @@ export default class StorageSettings extends AdminSettings {
|
||||
|
||||
this.renderSettings = this.renderSettings.bind(this);
|
||||
|
||||
//maxFileSize: props.config.FileSettings.MaxFileSize,
|
||||
this.state = Object.assign(this.state, {
|
||||
maxFileSize: props.config.FileSettings.MaxFileSize,
|
||||
driverName: props.config.FileSettings.DriverName,
|
||||
directory: props.config.FileSettings.Directory,
|
||||
amazonS3AccessKeyId: props.config.FileSettings.AmazonS3AccessKeyId,
|
||||
@@ -34,7 +34,7 @@ export default class StorageSettings extends AdminSettings {
|
||||
}
|
||||
|
||||
getConfigFromState(config) {
|
||||
config.FileSettings.MaxFileSize = this.parseInt(this.state.maxFileSize);
|
||||
//config.FileSettings.MaxFileSize = this.parseInt(this.state.maxFileSize);
|
||||
config.FileSettings.DriverName = this.state.driverName;
|
||||
config.FileSettings.Directory = this.state.directory;
|
||||
config.FileSettings.AmazonS3AccessKeyId = this.state.amazonS3AccessKeyId;
|
||||
@@ -57,26 +57,27 @@ export default class StorageSettings extends AdminSettings {
|
||||
}
|
||||
|
||||
renderSettings() {
|
||||
/*<TextSetting
|
||||
id='maxFileSize'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.image.maxFileSizeTitle'
|
||||
defaultMessage='Max File Size:'
|
||||
/>
|
||||
}
|
||||
placeholder={Utils.localizeMessage('admin.image.maxFileSizeExample', 'Ex "52428800"')}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.image.maxFileSizeDescription'
|
||||
defaultMessage='Max File Size in bytes. If blank, will be set to 52428800 (50MB).'
|
||||
/>
|
||||
}
|
||||
value={this.state.maxFileSize}
|
||||
onChange={this.handleChange}
|
||||
/>*/
|
||||
|
||||
return (
|
||||
<SettingsGroup>
|
||||
<TextSetting
|
||||
id='maxFileSize'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.image.maxFileSizeTitle'
|
||||
defaultMessage='Max File Size:'
|
||||
/>
|
||||
}
|
||||
placeholder={Utils.localizeMessage('admin.image.maxFileSizeExample', 'Ex "52428800"')}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.image.maxFileSizeDescription'
|
||||
defaultMessage='Max File Size in bytes. If blank, will be set to 52428800 (50MB).'
|
||||
/>
|
||||
}
|
||||
value={this.state.maxFileSize}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
<DropdownSetting
|
||||
id='driverName'
|
||||
values={[
|
||||
|
||||
@@ -23,26 +23,26 @@ export default class DoughnutChart extends React.Component {
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!Utils.areObjectsEqual(prevProps.data, this.props.data) || !Utils.areObjectsEqual(prevProps.options, this.props.options)) {
|
||||
if (this.chart) {
|
||||
this.chart.destroy();
|
||||
}
|
||||
this.initChart();
|
||||
this.initChart(true);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.chart) {
|
||||
if (this.chart && this.refs.canvas) {
|
||||
this.chart.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
initChart() {
|
||||
initChart(update) {
|
||||
if (!this.refs.canvas) {
|
||||
return;
|
||||
}
|
||||
var el = ReactDOM.findDOMNode(this.refs.canvas);
|
||||
var ctx = el.getContext('2d');
|
||||
this.chart = new Chart(ctx, {type: 'doughnut', data: this.props.data, options: this.props.options || {}}); //eslint-disable-line new-cap
|
||||
if (update) {
|
||||
this.chart.update();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -23,26 +23,26 @@ export default class LineChart extends React.Component {
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!Utils.areObjectsEqual(prevProps.data, this.props.data) || !Utils.areObjectsEqual(prevProps.options, this.props.options)) {
|
||||
if (this.chart) {
|
||||
this.chart.destroy();
|
||||
}
|
||||
this.initChart();
|
||||
this.initChart(true);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.chart) {
|
||||
if (this.chart && this.refs.canvas) {
|
||||
this.chart.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
initChart() {
|
||||
initChart(update) {
|
||||
if (!this.refs.canvas) {
|
||||
return;
|
||||
}
|
||||
var el = ReactDOM.findDOMNode(this.refs.canvas);
|
||||
var ctx = el.getContext('2d');
|
||||
this.chart = new Chart(ctx, {type: 'line', data: this.props.data, options: this.props.options || {}}); //eslint-disable-line new-cap
|
||||
if (update) {
|
||||
this.chart.update();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -147,7 +147,7 @@ class CreateComment extends React.Component {
|
||||
Client.createPost(
|
||||
post,
|
||||
() => {
|
||||
// DO nothing. Websockets will handle this.
|
||||
PostStore.removePendingPost(post.channel_id, post.pending_post_id);
|
||||
},
|
||||
(err) => {
|
||||
if (err.id === 'api.post.create_post.root_id.app_error') {
|
||||
|
||||
@@ -180,7 +180,7 @@ class CreatePost extends React.Component {
|
||||
|
||||
Client.createPost(post,
|
||||
() => {
|
||||
// DO nothing. Websockets will handle this.
|
||||
PostStore.removePendingPost(post.pending_post_id);
|
||||
},
|
||||
(err) => {
|
||||
if (err.id === 'api.post.create_post.root_id.app_error') {
|
||||
|
||||
@@ -67,6 +67,7 @@ class EditPostModal extends React.Component {
|
||||
Client.updatePost(
|
||||
updatedPost,
|
||||
() => {
|
||||
AsyncClient.getPosts(updatedPost.channel_id);
|
||||
window.scrollTo(0, 0);
|
||||
},
|
||||
(err) => {
|
||||
|
||||
@@ -69,13 +69,13 @@ export default class LoginController extends React.Component {
|
||||
this.setState({loginId});
|
||||
}
|
||||
|
||||
let password = this.refs.password.value;
|
||||
const password = this.refs.password.value;
|
||||
if (password !== this.state.password) {
|
||||
this.setState({password});
|
||||
}
|
||||
|
||||
// don't trim the password since we support spaces in passwords
|
||||
loginId = loginId.trim();
|
||||
password = password.trim();
|
||||
|
||||
if (!loginId) {
|
||||
// it's slightly weird to be constructing the message ID, but it's a bit nicer than triply nested if statements
|
||||
@@ -444,7 +444,7 @@ export default class LoginController extends React.Component {
|
||||
<a
|
||||
className='btn btn-custom-login gitlab'
|
||||
key='gitlab'
|
||||
href={Client.getOAuthRoute() + '/gitlab/login'}
|
||||
href={Client.getOAuthRoute() + '/gitlab/login' + this.props.location.search}
|
||||
>
|
||||
<span className='icon'/>
|
||||
<span>
|
||||
@@ -529,4 +529,4 @@ export default class LoginController extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +175,7 @@ export default class RhsRootPost extends React.Component {
|
||||
filenames={post.filenames}
|
||||
channelId={post.channel_id}
|
||||
userId={post.user_id}
|
||||
compactDisplay={this.props.compactDisplay}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -173,11 +173,24 @@ export default class SignupUserComplete extends React.Component {
|
||||
this.state.ldapPassword,
|
||||
null,
|
||||
() => {
|
||||
GlobalActions.emitInitialLoad(
|
||||
() => {
|
||||
browserHistory.push('/select_team');
|
||||
}
|
||||
);
|
||||
if (this.props.location.query.id || this.props.location.query.h) {
|
||||
Client.addUserToTeamFromInvite(
|
||||
this.props.location.query.d,
|
||||
this.props.location.query.h,
|
||||
this.props.location.query.id,
|
||||
() => {
|
||||
this.finishSignup();
|
||||
},
|
||||
() => {
|
||||
// there's not really a good way to deal with this, so just let the user log in like normal
|
||||
this.finishSignup();
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.finishSignup();
|
||||
},
|
||||
(err) => {
|
||||
if (err.id === 'ent.ldap.do_login.user_not_registered.app_error' || err.id === 'ent.ldap.do_login.user_filtered.app_error') {
|
||||
@@ -205,6 +218,15 @@ export default class SignupUserComplete extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
finishSignup() {
|
||||
GlobalActions.emitInitialLoad(
|
||||
() => {
|
||||
GlobalActions.loadDefaultLocale();
|
||||
browserHistory.push('/select_team');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
handleUserCreated(user, data) {
|
||||
track('signup', 'signup_user_02_complete');
|
||||
Client.loginById(
|
||||
@@ -761,4 +783,4 @@ export default class SignupUserComplete extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user