Commit a611e754 authored by Martin Kraft's avatar Martin Kraft

Merge remote-tracking branch 'origin/master' into advanced-permissions-phase-2

parents 1fd063a2 a4b2fcfc
This diff is collapsed.
......@@ -91,10 +91,9 @@ export function loadStatusesForProfilesMap(users) {
const statusesToLoad = [];
for (const userId in users) {
if (!users.hasOwnProperty(userId)) {
return;
if ({}.hasOwnProperty.call(users, userId)) {
statusesToLoad.push(userId);
}
statusesToLoad.push(userId);
}
loadStatusesByIds(statusesToLoad);
......
......@@ -376,8 +376,7 @@ function handleLeaveTeamEvent(msg) {
dispatch(batchActions([
{
type: UserTypes.RECEIVED_PROFILE_NOT_IN_TEAM,
data: {user_id: msg.data.user_id},
id: msg.data.team_id,
data: {id: msg.data.team_id, user_id: msg.data.user_id},
},
{
type: TeamTypes.REMOVE_MEMBER_FROM_TEAM,
......@@ -464,8 +463,7 @@ function handleUserAddedEvent(msg) {
getChannelStats(ChannelStore.getCurrentId())(dispatch, getState);
dispatch({
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
data: {user_id: msg.data.user_id},
id: msg.broadcast.channel_id,
data: {id: msg.broadcast.channel_id, user_id: msg.data.user_id},
});
}
......@@ -503,8 +501,7 @@ function handleUserRemovedEvent(msg) {
getChannelStats(ChannelStore.getCurrentId())(dispatch, getState);
dispatch({
type: UserTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL,
data: {user_id: msg.data.user_id},
id: msg.broadcast.channel_id,
data: {id: msg.broadcast.channel_id, user_id: msg.data.user_id},
});
}
}
......
......@@ -53,7 +53,7 @@ export default class AddUsersToTeam extends React.Component {
});
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.searchTerm !== nextProps.searchTerm) {
clearTimeout(this.searchTimeoutId);
......
......@@ -110,7 +110,7 @@ export default class AdminConsole extends React.Component {
}).isRequired,
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.props.actions.getConfig();
this.props.actions.getEnvironmentConfig();
reloadIfServerVersionChanged();
......
......@@ -248,15 +248,6 @@ export default {
help_text: 'admin.service.writeTimeoutDescription',
help_text_default: 'If using HTTP (insecure), this is the maximum time allowed from the end of reading the request headers until the response is written. If using HTTPS, it is the total time from when the connection is accepted until the response is written.',
},
{
type: Constants.SettingsTypes.TYPE_BOOL,
key: 'ServiceSettings.EnableAPIv3',
label: 'admin.service.enableAPIv3',
label_default: 'Allow use of API v3 endpoints:',
help_text: 'admin.service.enableAPIv3Description',
help_text_default: 'Set to false to disable all version 3 endpoints of the REST API. Integrations that rely on API v3 will fail and can then be identified for migration to API v4. API v3 is deprecated and will be removed in the near future. See <a href="https://api.mattermost.com" target="_blank">https://api.mattermost.com</a> for details.',
help_text_html: true,
},
{
type: Constants.SettingsTypes.TYPE_DROPDOWN,
key: 'ServiceSettings.WebserverMode',
......@@ -791,7 +782,7 @@ export default {
placeholder: 'admin.ldap.usernameAttrEx',
placeholder_default: 'E.g.: "sAMAccountName"',
help_text: 'admin.ldap.uernameAttrDesc',
help_text_default: 'The attribute in the AD/LDAP server that will be used to populate the username field in Mattermost. This may be the same as the ID Attribute.',
help_text_default: 'The attribute in the AD/LDAP server that will be used to populate the username field in Mattermost. This may be the same as the Login ID Attribute.',
isDisabled: needsUtils.and(
needsUtils.stateValueFalse('LdapSettings.Enable'),
needsUtils.stateValueFalse('LdapSettings.EnableSync'),
......@@ -803,9 +794,23 @@ export default {
label: 'admin.ldap.idAttrTitle',
label_default: 'ID Attribute: ',
placeholder: 'admin.ldap.idAttrEx',
placeholder_default: 'E.g.: "sAMAccountName"',
placeholder_default: 'E.g.: "objectGUID"',
help_text: 'admin.ldap.idAttrDesc',
help_text_default: 'The attribute in the AD/LDAP server that will be used as a unique identifier in Mattermost. It should be an AD/LDAP attribute with a value that does not change, such as username or uid. If a user\'s ID Attribute changes, it will create a new Mattermost account unassociated with their old one. This is the value used to log in to Mattermost in the "AD/LDAP Username" field on the sign in page. Normally this attribute is the same as the "Username Attribute" field above. If your team typically uses domain\\username to sign in to other services with AD/LDAP, you may choose to put domain\\username in this field to maintain consistency between sites.',
help_text_default: 'The attribute in the AD/LDAP server that will be used as a unique identifier in Mattermost. It should be an AD/LDAP attribute with a value that does not change. If a user\'s ID Attribute changes, it will create a new Mattermost account unassociated with their old one. If you need to change this after users have already logged in, you can use the CLI tool "platform ldap idmigrate".',
isDisabled: needsUtils.and(
needsUtils.stateValueEqual('LdapSettings.Enable', false),
needsUtils.stateValueEqual('LdapSettings.EnableSync', false),
),
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'LdapSettings.LoginIdAttribute',
label: 'admin.ldap.loginAttrTitle',
label_default: 'Login ID Attribute: ',
placeholder: 'admin.ldap.loginIdAttrEx',
placeholder_default: 'E.g.: "sAMAccountName"',
help_text: 'admin.ldap.loginAttrDesc',
help_text_default: 'The attribute in the AD/LDAP server that will be used by AD/LDAP users to login to Mattermost. This is the value used to log in to Mattermost in the "AD/LDAP Username" field on the sign in page. Normally this attribute is the same as the "Username Attribute" field above. If your team typically uses domain\\username to sign in to other services with AD/LDAP, you may choose to put domain\\username in this field to maintain consistency between sites.',
isDisabled: needsUtils.and(
needsUtils.stateValueFalse('LdapSettings.Enable'),
needsUtils.stateValueFalse('LdapSettings.EnableSync'),
......
......@@ -63,18 +63,18 @@ export default class AdminSidebarCategory extends React.Component {
render={() => (
<ul className={'sections ' + this.props.sectionClass}>
{
React.Children.map(this.props.children, (child) => {
if (child === null) {
return null;
}
React.Children.map(this.props.children, (child) => {
if (child === null) {
return null;
}
return React.cloneElement(child, {
parentLink: link,
});
})
}
return React.cloneElement(child, {
parentLink: link,
});
})
}
</ul>
)}
)}
/>
);
}
......
......@@ -39,7 +39,7 @@ export default class BrandImageSetting extends React.PureComponent {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
fetch(Client4.getBrandImageUrl(this.state.brandImageTimestamp)).then(
(resp) => {
if (resp.status === HTTP_STATUS_OK) {
......
......@@ -33,7 +33,7 @@ export default class ClusterTableContainer extends React.Component {
);
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.load();
// reload the cluster status every 15 seconds
......
......@@ -34,7 +34,7 @@ export class WebhookSettings extends AdminSettings {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.props.actions.loadRolesIfNeeded(['team_user', 'system_user']);
if (this.props.roles.system_user &&
this.props.roles.team_user) {
......@@ -42,7 +42,7 @@ export class WebhookSettings extends AdminSettings {
}
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (!this.state.loaded &&
nextProps.roles.system_user &&
nextProps.roles.team_user) {
......
......@@ -9,8 +9,11 @@ export default class CustomPluginSettings extends SchemaAdminSettings {
this.isPlugin = true;
}
componentWillReceiveProps(nextProps) {
if (!this.props.schema && nextProps.schema) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
const id = this.props.schema ? this.props.schema.id : '';
const nextId = nextProps.schema ? nextProps.schema.id : '';
if ((!this.props.schema && nextProps.schema) || (id !== nextId)) {
this.setState(this.getStateFromConfig(nextProps.config, nextProps.schema));
}
}
......
......@@ -66,7 +66,7 @@ class JobTable extends React.PureComponent {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.interval = setInterval(this.reload, 15000);
}
......
......@@ -60,7 +60,7 @@ export default class ManageRolesModal extends React.PureComponent {
this.state = getStateFromProps(props);
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
const user = this.props.user || {};
const nextUser = nextProps.user || {};
if (user.id !== nextUser.id) {
......
......@@ -39,7 +39,7 @@ export default class ManageTeamsModal extends React.Component {
}
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
const userId = this.props.user ? this.props.user.id : '';
const nextUserId = nextProps.user ? nextProps.user.id : '';
......
......@@ -48,7 +48,7 @@ export default class ManageTokensModal extends React.PureComponent {
this.state = {error: null};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
const userId = this.props.user ? this.props.user.id : null;
const nextUserId = nextProps.user ? nextProps.user.id : null;
if (nextUserId && nextUserId !== userId) {
......
......@@ -49,7 +49,7 @@ export default class MultiSelectSetting extends React.Component {
}
}
componentWillReceiveProps(newProps) {
UNSAFE_componentWillReceiveProps(newProps) { // eslint-disable-line camelcase
if (newProps.selected.length > 0 && newProps.mustBePresent && newProps.selected.join(',').indexOf(newProps.mustBePresent) === -1) {
this.setState({error: this.props.notPresent});
} else {
......
This diff is collapsed.
......@@ -82,7 +82,7 @@ export default class SamlSettings extends AdminSettings {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
AdminActions.samlCertificateStatus(
(data) => {
const files = {};
......
......@@ -43,7 +43,7 @@ export default class SchemaAdminSettings extends AdminSettings {
};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (nextProps.schema !== this.props.schema) {
this.setState(this.getStateFromConfig(nextProps.config, nextProps.schema));
}
......
......@@ -42,7 +42,7 @@ export default class Logs extends React.Component {
);
}
componentWillUpdate(nextProps, nextState) {
UNSAFE_componentWillUpdate(nextProps, nextState) { // eslint-disable-line camelcase
if (this.state.page !== nextState.page) {
this.props.actions.getLogs(nextState.page, nextState.perPage).then(
() => this.setState({loadingLogs: false})
......
......@@ -64,7 +64,7 @@ export default class SystemUsersList extends React.Component {
};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (nextProps.teamId !== this.props.teamId) {
this.setState({page: 0});
}
......
......@@ -110,7 +110,7 @@ export default class SystemUsers extends React.Component {
this.props.actions.getTeams(0, 1000).then(reloadIfServerVersionChanged);
}
componentWillUpdate(nextProps, nextState) {
UNSAFE_componentWillUpdate(nextProps, nextState) { // eslint-disable-line camelcase
const nextTeamId = nextState.teamId;
if (this.state.teamId !== nextTeamId) {
......
......@@ -42,14 +42,14 @@ export class UsersAndTeamsSettings extends AdminSettings {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.props.actions.loadRolesIfNeeded(['system_user']);
if (this.props.roles.system_user) {
this.loadPoliciesIntoState(this.props);
}
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (!this.state.loaded && nextProps.roles.system_user) {
this.loadPoliciesIntoState(nextProps);
}
......
......@@ -44,7 +44,7 @@ export default class LineChart extends React.PureComponent {
this.initChart();
}
componentWillUpdate(nextProps) {
UNSAFE_componentWillUpdate(nextProps) { // eslint-disable-line camelcase
const willHaveData = nextProps.data && nextProps.data.labels.length > 0;
const hasChart = Boolean(this.chart);
......
......@@ -77,7 +77,7 @@ export default class TeamAnalytics extends React.Component {
this.props.actions.getTeams(0, 1000);
}
componentWillUpdate(nextProps, nextState) {
UNSAFE_componentWillUpdate(nextProps, nextState) { // eslint-disable-line camelcase
if (nextState.team && nextState.team !== this.state.team) {
this.getData(nextState.team.id);
}
......
......@@ -56,7 +56,17 @@ export default class AnnouncementBar extends React.PureComponent {
this.setInitialError();
this.state = this.getState();
this.state = this.getState(props);
}
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (nextProps.enableBanner !== this.props.enableBanner ||
nextProps.bannerText !== this.props.bannerText ||
nextProps.bannerColor !== this.props.bannerColor ||
nextProps.bannerTextColor !== this.props.bannerTextColor ||
nextProps.allowBannerDismissal !== this.props.allowBannerDismissal) {
this.setState(this.getState(nextProps));
}
}
setInitialError = () => {
......@@ -85,17 +95,17 @@ export default class AnnouncementBar extends React.PureComponent {
}
}
getState() {
getState(props = this.props) {
const error = ErrorStore.getLastError();
if (error && error.message) {
return {message: error.message, color: null, textColor: null, type: error.type, allowDismissal: true};
}
const bannerText = this.props.bannerText || '';
const allowDismissal = this.props.allowBannerDismissal;
const bannerDismissed = localStorage.getItem(StoragePrefixes.ANNOUNCEMENT + this.props.bannerText);
const bannerText = props.bannerText || '';
const allowDismissal = props.allowBannerDismissal;
const bannerDismissed = localStorage.getItem(StoragePrefixes.ANNOUNCEMENT + props.bannerText);
if (this.props.enableBanner &&
if (props.enableBanner &&
bannerText.length > 0 &&
(!bannerDismissed || !allowDismissal)
) {
......@@ -103,8 +113,8 @@ export default class AnnouncementBar extends React.PureComponent {
Utils.removePrefixFromLocalStorage(StoragePrefixes.ANNOUNCEMENT);
return {
message: bannerText,
color: this.props.bannerColor,
textColor: this.props.bannerTextColor,
color: props.bannerColor,
textColor: props.bannerTextColor,
type: BAR_ANNOUNCEMENT_TYPE,
allowDismissal,
};
......
......@@ -21,11 +21,11 @@ export class AsyncComponent extends React.Component {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.load(this.props);
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (nextProps.doLoad !== this.props.doLoad) {
this.load(nextProps);
}
......@@ -43,8 +43,10 @@ export class AsyncComponent extends React.Component {
}
export function makeAsyncComponent(loadComponent) {
return (props) => (<AsyncComponent
doLoad={loadComponent}
{...props}
/>);
return (props) => (
<AsyncComponent
doLoad={loadComponent}
{...props}
/>
);
}
......@@ -36,7 +36,7 @@ export default class AtMention extends React.PureComponent {
};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (nextProps.mentionName !== this.props.mentionName || nextProps.usersByUsername !== this.props.usersByUsername) {
this.setState({
user: this.getUserFromMentionName(nextProps),
......
......@@ -38,7 +38,7 @@ export default class AudioVideoPreview extends React.PureComponent {
};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
this.handleFileInfoChanged(this.props.fileInfo);
}
......@@ -48,7 +48,7 @@ export default class AudioVideoPreview extends React.PureComponent {
}
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.fileUrl !== nextProps.fileUrl) {
this.handleFileInfoChanged(nextProps.fileInfo);
}
......
......@@ -26,7 +26,7 @@ export default class Authorize extends React.Component {
this.state = {};
}
componentWillMount() {
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
const clientId = (new URLSearchParams(this.props.location.search)).get('client_id');
if (!(/^[a-z0-9]+$/.test(clientId))) {
return;
......
......@@ -51,18 +51,18 @@ export default class BackstageCategory extends React.Component {
render={() => (
<ul className='sections'>
{
React.Children.map(children, (child) => {
if (!child) {
return child;
}
React.Children.map(children, (child) => {
if (!child) {
return child;
}
return React.cloneElement(child, {
parentLink: link,
});
})
}
return React.cloneElement(child, {
parentLink: link,
});
})
}
</ul>
)}
)}
/>
</li>
);
......
......@@ -10,7 +10,6 @@ import Constants from 'utils/constants';
import {getShortenedURL, cleanUpUrlable} from 'utils/url';
export default class ChangeURLModal extends React.PureComponent {
static propTypes = {
/**
......@@ -76,7 +75,7 @@ export default class ChangeURLModal extends React.PureComponent {
};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
// This check prevents the url being deleted when we re-render
// because of user status check
if (!this.state.userEdit) {
......@@ -106,29 +105,29 @@ export default class ChangeURLModal extends React.PureComponent {
if (url.length < 2) {
error.push(
this.formattedError('error1', 'change_url.longer', 'URL must be two or more characters.')
this.formattedError('error1', 'change_url.longer', 'URL must be two or more characters.')
);
}
if (url.charAt(0) === '-' || url.charAt(0) === '_') {
error.push(
this.formattedError('error2', 'change_url.startWithLetter', 'URL must start with a letter or number.')
this.formattedError('error2', 'change_url.startWithLetter', 'URL must start with a letter or number.')
);
}
if (url.length > 1 && (url.charAt(url.length - 1) === '-' || url.charAt(url.length - 1) === '_')) {
error.push(
this.formattedError('error3', 'change_url.endWithLetter', 'URL must end with a letter or number.')
this.formattedError('error3', 'change_url.endWithLetter', 'URL must end with a letter or number.')
);
}
if (url.indexOf('__') > -1) {
error.push(
this.formattedError('error4', 'change_url.noUnderscore', 'URL can not contain two underscores in a row.')
this.formattedError('error4', 'change_url.noUnderscore', 'URL can not contain two underscores in a row.')
);
}
// In case of error we don't detect
if (error.length === 0) {
error.push(
this.formattedError('errorlast', 'change_url.invalidUrl', 'Invalid URL')
this.formattedError('errorlast', 'change_url.invalidUrl', 'Invalid URL')
);
}
return error;
......
......@@ -116,7 +116,7 @@ export default class ChannelHeader extends React.Component {
window.removeEventListener('resize', this.handleResize);
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.channel.id !== nextProps.channel.id) {
this.props.actions.getCustomEmojisInText(nextProps.channel.header);
}
......
......@@ -28,7 +28,7 @@ export default class CenterChannel extends React.PureComponent {
};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.location.pathname !== nextProps.location.pathname && nextProps.location.pathname.includes('/pl/')) {
this.setState({returnTo: this.props.location.pathname});
}
......
......@@ -223,7 +223,7 @@ export default class ChannelIdentifierRouter extends React.PureComponent {
onChannelByIdentifierEnter(props);
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.match.params.identifier !== nextProps.match.params.identifier) {
onChannelByIdentifierEnter(nextProps);
}
......
......@@ -18,7 +18,7 @@ describe('components/ChannelMembersModal', () => {
},
canManageChannelMembers: true,
onModalDismissed: () => {}, // eslint-disable-line no-empty-function
showInviteModal: () => {}, // eslint-disable-line no-empty-function
showInviteModal: () => {}, // eslint-disable-line no-empty-function
};
test('renders the channel display name', () => {
......
......@@ -38,7 +38,7 @@ export default class ChannelNotificationsModal extends React.Component {
};
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (!Utils.areObjectsEqual(this.props.channelMember.notify_props, nextProps.channelMember.notify_props)) {
this.setState({
desktopNotifyLevel: nextProps.channelMember.notify_props.desktop,
......
......@@ -67,7 +67,7 @@ export default class ChannelView extends React.PureComponent {
$('body').removeClass('app__body');
}
componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps) { // eslint-disable-line camelcase
if (this.props.match.url !== nextProps.match.url) {
this.createDeferredPostView();